Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice
  3. Dismiss Notice

PlayerPrefs can't be deleted in Unity Editor

Discussion in 'Scripting' started by shinriyo_twitter, Nov 27, 2011.

  1. shinriyo_twitter

    shinriyo_twitter

    Joined:
    Aug 12, 2011
    Posts:
    328
    Hi there

    I used PlayerPrefs in Unity editor.
    And I also use macos.

    I red the document http://unity3d.com/support/documentation/ScriptReference/PlayerPrefs.html
    It is written about Mac "OS X PlayerPrefs" but there aren't about Unity Editor.
    I thought OS X PlayerPrefs and Unity Editor are same.
    So, I deleted ~/Library/Preferences/unity.[company name].[product name].plist file.
    But, the data wasn't be deleted.
    Please tell me how to delete save data?
     
  2. GargerathSunman

    GargerathSunman

    Joined:
    May 1, 2008
    Posts:
    1,571
    PlayerPrefs.DeleteAll();
     
  3. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    They are, but you can't have the editor running when you delete the preferences. Close Unity, delete prefs, re-open.

    --Eric
     
  4. shinriyo_twitter

    shinriyo_twitter

    Joined:
    Aug 12, 2011
    Posts:
    328
    Hi GargerathSunman Eric5h5

    Thanks for replying. I will try it!
     
  5. squidbot

    squidbot

    Joined:
    Jan 4, 2011
    Posts:
    128
    This is a bit janky, buggy and unfinished, but I started writing a little prefs tool for the editor, including a "delete prefs" button as well as a list of the current prefs:

    PrefsUtil.cs

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections.Generic;
    4. using UnityEditor;
    5.  
    6. public class PrefsUtil : EditorWindow
    7. {
    8.     private static GUIStyle labelStyle;
    9.     private static Dictionary<string, object> currentPrefs;
    10.  
    11.     [MenuItem("Window/Motiga/Prefs Util")]
    12.     public static void ShowWindow()
    13.     {
    14.         labelStyle = GUIStyle.none;
    15.         labelStyle.normal.textColor = Color.white;
    16.         labelStyle.wordWrap = true;
    17.        
    18.         currentPrefs = GetCurrentPrefs();
    19.        
    20.         EditorWindow.GetWindow(typeof(PrefsUtil));
    21.     }
    22.  
    23.     private static Dictionary<string, object> GetCurrentPrefs()
    24.     {
    25.         if(Application.platform == RuntimePlatform.OSXEditor)
    26.         {
    27.             return GetMacPrefs();
    28.         }
    29.         else if(Application.platform == RuntimePlatform.WindowsEditor)
    30.         {
    31.             return GetWindowsPrefs();
    32.         }
    33.         return null;
    34.     }
    35.    
    36.     private static Dictionary<string, object> GetMacPrefs()
    37.     {
    38.         string prefsFileName = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)
    39.             + "/Library/Preferences/unity."
    40.             + PlayerSettings.companyName + "."
    41.             + PlayerSettings.productName + ".plist";
    42.  
    43.         Dictionary<string, object> plist;
    44.         try
    45.         {
    46.             plist = Plist.createDictionaryFromBinaryFile(prefsFileName);
    47.         }
    48.         catch(System.Exception eouter)
    49.         {
    50.             Debug.Log("Couldn't read binary prefs: " + eouter.ToString());
    51.             try
    52.             {
    53.                 plist = Plist.createDictionaryFromXmlFile(prefsFileName);
    54.             }
    55.             catch(System.Exception einner)
    56.             {
    57.                 Debug.Log("Couldn't read xml prefs: " + einner.ToString());
    58.                 return null;
    59.             }
    60.         }
    61.        
    62.         return plist;
    63.     }
    64.  
    65.     private static Dictionary<string, object> GetWindowsPrefs()
    66.     {
    67.         return new Dictionary<string, object>();
    68.     }
    69.  
    70.     public void OnGUI()
    71.     {
    72.         GUILayout.BeginHorizontal();
    73.         GUILayout.FlexibleSpace();
    74.         GUILayout.Label("This will clear all of your current game prefs to allow a fresh start",
    75.             labelStyle,
    76.             GUILayout.MaxWidth(200));
    77.  
    78.         if(GUILayout.Button("Clear Prefs", GUILayout.MaxWidth(200)))
    79.         {
    80.             PlayerPrefs.DeleteAll();
    81.         }
    82.         GUILayout.FlexibleSpace();
    83.         GUILayout.EndHorizontal();
    84.  
    85.         EditorGUILayout.Space();
    86.        
    87.         foreach(KeyValuePair<string, object> item in currentPrefs)
    88.         {
    89.             EditorGUILayout.LabelField(item.Key.ToString(), item.Value.ToString());
    90.         }
    91.     }
    92. }
    93.  
    94.  
    You also need this, PList.cs, I didn't write this, and unfortunately I don't have any attribution recorded, and I can't remember where I grabbed it :( There are many different plist readers out there, this one was convenient in how it created the dictionary.

    Code (csharp):
    1.  
    2. using System;
    3. using System.Collections.Generic;
    4. using System.IO;
    5. using System.Linq;
    6. using System.Xml;
    7.  
    8. public static class Plist
    9. {
    10.     private static List<int> offsetTable = new List<int>();
    11.     private static List<byte> objectTable = new List<byte>();
    12.     private static int refCount;
    13.     private static int objRefSize;
    14.     private static int offsetByteSize;
    15.     private static long offsetTableOffset;
    16.  
    17.     #region Public Functions
    18.  
    19.     public static Dictionary<string, object> createDictionaryFromXmlFile(string path)
    20.     {
    21.         XmlDocument doc = new XmlDocument();
    22.         doc.LoadXml(path);
    23.         XmlNode rootNode = doc.DocumentElement.ChildNodes[0];
    24.         return (Dictionary<string, object>)parse(rootNode);
    25.     }
    26.  
    27.     public static Dictionary<string, object> createDictionaryFromXml(string xml)
    28.     {
    29.         XmlDocument doc = new XmlDocument();
    30.         doc.Load(xml);
    31.         XmlNode rootNode = doc.DocumentElement.ChildNodes[0];
    32.         return (Dictionary<string,object>)parse(rootNode);
    33.     }
    34.  
    35.     public static Dictionary<string, object> createDictionaryFromBinaryFile(string path)
    36.     {
    37.         using (BinaryReader reader = new BinaryReader(new FileStream(path, FileMode.Open, FileAccess.Read)))
    38.         {
    39.             byte[] buffer = reader.ReadBytes((int)reader.BaseStream.Length);
    40.             return createDictionaryFromBinaryData(buffer);
    41.         }
    42.     }
    43.  
    44.     public static Dictionary<string, object> createDictionaryFromBinaryData(byte[] binaryData)
    45.     {
    46.         offsetTable.Clear();
    47.         List<byte> offsetTableBytes = new List<byte>();
    48.         objectTable.Clear();
    49.         refCount = 0;
    50.         objRefSize = 0;
    51.         offsetByteSize = 0;
    52.         offsetTableOffset = 0;
    53.  
    54.         List<byte> bList = binaryData.ToList();
    55.  
    56.         List<byte> trailer = bList.GetRange(bList.Count - 32, 32);
    57.  
    58.         parseTrailer(trailer);
    59.  
    60.         objectTable = bList.GetRange(0, (int)offsetTableOffset);
    61.  
    62.         offsetTableBytes = bList.GetRange((int)offsetTableOffset, bList.Count - (int)offsetTableOffset - 32);
    63.  
    64.         parseOffsetTable(offsetTableBytes);
    65.  
    66.         long magicHeader = BitConverter.ToInt64(objectTable.GetRange(0, 8).ToArray(), 0);
    67.  
    68.         if (magicHeader != 3472403351741427810)
    69.             throw new Exception("This is not a valid binary plist.");
    70.  
    71.         return (Dictionary<string,object>)parseBinaryDictionary(0);
    72.     }
    73.  
    74.     public static byte[] createBinaryDataFromXml(string xml)
    75.     {
    76.         return createBinaryFromDictionary(createDictionaryFromXml(xml));
    77.     }
    78.  
    79.     public static byte[] createBinaryFromDictionary(Dictionary<string, object> dictionary)
    80.     {
    81.         offsetTable.Clear();
    82.         objectTable.Clear();
    83.         refCount = 0;
    84.         objRefSize = 0;
    85.         offsetByteSize = 0;
    86.         offsetTableOffset = 0;
    87.  
    88.         int totalRefs = countDictionary(dictionary);
    89.  
    90.         refCount = totalRefs;
    91.  
    92.         objRefSize = RegulateNullBytes(BitConverter.GetBytes(refCount)).Length;
    93.  
    94.         writeBinaryDictionary(dictionary);
    95.  
    96.         writeBinaryString("bplist00", false);
    97.  
    98.         offsetTableOffset = (long)objectTable.Count;
    99.  
    100.         offsetTable.Add(objectTable.Count - 8);
    101.  
    102.         offsetByteSize = RegulateNullBytes(BitConverter.GetBytes(offsetTable.Last())).Length;
    103.  
    104.         List<byte> offsetBytes = new List<byte>();
    105.  
    106.         offsetTable.Reverse();
    107.  
    108.         for(int i =0; i < offsetTable.Count; i++)
    109.         {
    110.             offsetTable[i] = objectTable.Count - offsetTable[i];
    111.             byte[] buffer = RegulateNullBytes(BitConverter.GetBytes(offsetTable[i]), offsetByteSize);
    112.             Array.Reverse(buffer);
    113.             offsetBytes.AddRange(buffer);
    114.         }
    115.  
    116.         objectTable.AddRange(offsetBytes);
    117.  
    118.         objectTable.AddRange(new byte[6]);
    119.         objectTable.Add(Convert.ToByte(offsetByteSize));
    120.         objectTable.Add(Convert.ToByte(objRefSize));
    121.         objectTable.AddRange(BitConverter.GetBytes((long)totalRefs+1).Reverse());
    122.         objectTable.AddRange(BitConverter.GetBytes((long)0));
    123.         objectTable.AddRange(BitConverter.GetBytes(offsetTableOffset).Reverse());
    124.  
    125.         return objectTable.ToArray();
    126.     }
    127.  
    128.     public static string createXmlFromBinaryData(byte[] binaryData)
    129.     {
    130.         return createXmlFromDictionary(createDictionaryFromBinaryData(binaryData));
    131.     }
    132.  
    133.     public static string createXmlFromDictionary(Dictionary<string, object> dictionary)
    134.     {
    135.         using (MemoryStream ms = new MemoryStream())
    136.         {
    137.             XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
    138.             xmlWriterSettings.Encoding = new System.Text.UTF8Encoding(false);
    139.             xmlWriterSettings.ConformanceLevel = ConformanceLevel.Document;
    140.             xmlWriterSettings.Indent = true;
    141.  
    142.             XmlWriter writer = XmlWriter.Create(ms, xmlWriterSettings);
    143.             writer.WriteStartDocument();
    144.             writer.WriteComment("DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " + "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"");
    145.             writer.WriteStartElement("plist");
    146.             writer.WriteAttributeString("version", "1.0");
    147.             writeDictionaryValues(dictionary, writer);
    148.             writer.WriteEndElement();
    149.             writer.WriteEndDocument();
    150.             writer.Flush();
    151.             writer.Close();
    152.             return System.Text.Encoding.UTF8.GetString(ms.ToArray());
    153.         }
    154.    
    155.     }
    156.  
    157.     #endregion
    158.  
    159.     #region Private Functions
    160.  
    161.     private static Dictionary<string, object> parseDictionary(XmlNode node)
    162.     {
    163.         XmlNodeList children = node.ChildNodes;
    164.         if (children.Count % 2 != 0)
    165.         {
    166.             throw new DataMisalignedException("Dictionary elements must have an even number of child nodes");
    167.         }
    168.  
    169.         Dictionary<string, object> dict = new Dictionary<string, object>();
    170.  
    171.         for (int i = 0; i < children.Count; i += 2)
    172.         {
    173.             XmlNode keynode = children[i];
    174.             XmlNode valnode = children[i + 1];
    175.  
    176.             if (keynode.Name != "key")
    177.             {
    178.                 throw new ApplicationException("expected a key node");
    179.             }
    180.  
    181.             object result = parse(valnode);
    182.  
    183.             if (result != null)
    184.             {
    185.                 dict.Add(keynode.InnerText, result);
    186.             }
    187.         }
    188.  
    189.         return dict;
    190.     }
    191.  
    192.     private static List<object> parseArray(XmlNode node)
    193.     {
    194.         List<object> array = new List<object>();
    195.  
    196.         foreach (XmlNode child in node.ChildNodes)
    197.         {
    198.             object result = parse(child);
    199.             if (result != null)
    200.             {
    201.                 array.Add(result);
    202.             }
    203.         }
    204.  
    205.         return array;
    206.     }
    207.  
    208.     private static void composeArray(List<object> value, XmlWriter writer)
    209.     {
    210.         writer.WriteStartElement("array");
    211.         foreach (object obj in value)
    212.         {
    213.             compose(obj, writer);
    214.         }
    215.         writer.WriteEndElement();
    216.     }
    217.  
    218.     private static object parse(XmlNode node)
    219.     {
    220.         switch (node.Name)
    221.         {
    222.             case "dict":
    223.                 return parseDictionary(node);
    224.             case "array":
    225.                 return parseArray(node);
    226.             case "string":
    227.                 return node.InnerText;
    228.             case "integer":
    229.                 return Convert.ToInt32(node.InnerText);
    230.             case "real":
    231.                 return Convert.ToDouble(node.InnerText);
    232.             case "false":
    233.                 return false;
    234.             case "true":
    235.                 return true;
    236.             case "data":
    237.                 return Convert.FromBase64String(node.InnerText);
    238.         }
    239.  
    240.         throw new ApplicationException(String.Format("Plist Node `{0}' is not supported", node.Name));
    241.     }
    242.  
    243.     private static void compose(object value, XmlWriter writer)
    244.     {
    245.         switch (value.GetType().ToString())
    246.         {
    247.             case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
    248.                 writeDictionaryValues((Dictionary<string, object>)value, writer);
    249.                 break;
    250.  
    251.             case "System.Collections.Generic.List`1[System.Object]":
    252.                 composeArray((List<object>)value, writer);
    253.                 break;
    254.  
    255.             case "System.Byte[]":
    256.                 writer.WriteElementString("data", Convert.ToBase64String((Byte[])value));
    257.                 break;
    258.  
    259.             case "System.Double":
    260.                 writer.WriteElementString("real", value.ToString());
    261.                 break;
    262.  
    263.             case "System.Int32":
    264.                 writer.WriteElementString("integer", value.ToString());
    265.                 break;
    266.  
    267.             case "System.String":
    268.                 writer.WriteElementString("string", value.ToString());
    269.                 break;
    270.  
    271.             default:
    272.                 throw new Exception(String.Format("Value type '{0}' is unhandled", value.GetType().ToString()));
    273.         }
    274.     }
    275.  
    276.     private static void writeDictionaryValues(Dictionary<string, object> dictionary, XmlWriter writer)
    277.     {
    278.         writer.WriteStartElement("dict");
    279.         foreach (string key in dictionary.Keys)
    280.         {
    281.             object value = dictionary[key];
    282.             writer.WriteElementString("key", key);
    283.             compose(value, writer);
    284.         }
    285.         writer.WriteEndElement();
    286.     }
    287.  
    288.     private static int countDictionary(Dictionary<string, object> dictionary)
    289.     {
    290.         int count = 0;
    291.         foreach (string key in dictionary.Keys)
    292.         {
    293.             count++;
    294.             switch (dictionary[key].GetType().ToString())
    295.             {
    296.                 case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
    297.                     count += (countDictionary((Dictionary<string, object>)dictionary[key]) + 1);
    298.                     break;
    299.                 case "System.Collections.Generic.List`1[System.Object]":
    300.                     count += (countArray((List<object>)dictionary[key]) + 1);
    301.                     break;
    302.                 default:
    303.                     count++;
    304.                     break;
    305.             }
    306.         }
    307.         return count;
    308.     }
    309.  
    310.     private static int countArray(List<object> array)
    311.     {
    312.         int count = 0;
    313.         foreach (object obj in array)
    314.         {
    315.             switch (obj.GetType().ToString())
    316.             {
    317.                 case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
    318.                     count += (countDictionary((Dictionary<string, object>)obj) + 1);
    319.                     break;
    320.                 case "System.Collections.Generic.List`1[System.Object]":
    321.                     count += (countArray((List<object>)obj) + 1);
    322.                     break;
    323.                 default:
    324.                     count++;
    325.                     break;
    326.             }
    327.         }
    328.         return count;
    329.     }
    330.  
    331.     private static byte[] writeBinaryDictionary(Dictionary<string, object> dictionary)
    332.     {
    333.         List<byte> buffer = new List<byte>();
    334.         List<byte> header = new List<byte>();
    335.         List<int> refs = new List<int>();
    336.         for (int i = dictionary.Count - 1; i >= 0; i--)
    337.         {
    338.             composeBinary(dictionary.Values.ToArray()[i]);
    339.             offsetTable.Add(objectTable.Count);
    340.             refs.Add(refCount);
    341.             refCount--;
    342.         }
    343.         for (int i = dictionary.Count - 1; i >= 0; i--)
    344.         {
    345.             composeBinary(dictionary.Keys.ToArray()[i]);
    346.             offsetTable.Add(objectTable.Count);
    347.             refs.Add(refCount);
    348.             refCount--;
    349.         }
    350.  
    351.         if (dictionary.Count < 15)
    352.         {
    353.             header.Add(Convert.ToByte(0xD0 | Convert.ToByte(dictionary.Count)));
    354.         }
    355.         else
    356.         {
    357.             header.Add(0xD0 | 0xf);
    358.             header.AddRange(writeBinaryInteger(dictionary.Count,false));
    359.         }
    360.  
    361.  
    362.         foreach (int val in refs)
    363.         {
    364.             byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
    365.             Array.Reverse(refBuffer);
    366.             buffer.InsertRange(0, refBuffer);
    367.         }
    368.  
    369.         buffer.InsertRange(0, header);
    370.  
    371.         objectTable.InsertRange(0, buffer);
    372.  
    373.         return buffer.ToArray();
    374.     }
    375.  
    376.     private static byte[] composeBinaryArray(List<object> objects)
    377.     {
    378.         List<byte> buffer = new List<byte>();
    379.         List<byte> header = new List<byte>();
    380.         List<int> refs = new List<int>();
    381.  
    382.         for (int i = objects.Count - 1; i >= 0; i--)
    383.         {
    384.             composeBinary(objects[i]);
    385.             offsetTable.Add(objectTable.Count);
    386.             refs.Add(refCount);
    387.             refCount--;
    388.         }
    389.  
    390.         if (objects.Count < 15)
    391.         {
    392.             header.Add(Convert.ToByte(0xA0 | Convert.ToByte(objects.Count)));
    393.         }
    394.         else
    395.         {
    396.             header.Add(0xA0 | 0xf);
    397.             header.AddRange(writeBinaryInteger(objects.Count, false));
    398.         }
    399.  
    400.         foreach (int val in refs)
    401.         {
    402.             byte[] refBuffer = RegulateNullBytes(BitConverter.GetBytes(val), objRefSize);
    403.             Array.Reverse(refBuffer);
    404.             buffer.InsertRange(0, refBuffer);
    405.         }
    406.  
    407.         buffer.InsertRange(0, header);
    408.  
    409.         objectTable.InsertRange(0, buffer);
    410.  
    411.         return buffer.ToArray();
    412.     }
    413.  
    414.     private static byte[] composeBinary(object obj)
    415.     {
    416.         byte[] value;
    417.         switch (obj.GetType().ToString())
    418.         {
    419.             case "System.Collections.Generic.Dictionary`2[System.String,System.Object]":
    420.                 value = writeBinaryDictionary((Dictionary<string, object>)obj);
    421.                 return value;
    422.  
    423.             case "System.Collections.Generic.List`1[System.Object]":
    424.                 value = composeBinaryArray((List<object>)obj);
    425.                 return value;
    426.  
    427.             case "System.Byte[]":
    428.                 value = writeBinaryByteArray((byte[])obj);
    429.                 return value;
    430.  
    431.             case "System.Double":
    432.                 value = writeBinaryDouble((double)obj);
    433.                 return value;
    434.  
    435.             case "System.Int32":
    436.                 value = writeBinaryInteger((int)obj, true);
    437.                 return value;
    438.  
    439.             case "System.String":
    440.                 value = writeBinaryString((string)obj, true);
    441.                 return value;
    442.  
    443.             default:
    444.                 return new byte[0];
    445.         }
    446.  
    447.     }
    448.  
    449.     private static byte[] writeBinaryInteger(int value, bool write)
    450.     {
    451.         List<byte> buffer = BitConverter.GetBytes(value).ToList();
    452.         buffer = RegulateNullBytes(buffer.ToArray()).ToList();
    453.         while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
    454.             buffer.Add(0);
    455.         int header = 0x10 | (int)(Math.Log(buffer.Count) / Math.Log(2));
    456.  
    457.         if (BitConverter.IsLittleEndian)
    458.             buffer.Reverse();
    459.  
    460.         buffer.Insert(0, Convert.ToByte(header));
    461.  
    462.         if(write)
    463.             objectTable.InsertRange(0, buffer);
    464.  
    465.         return buffer.ToArray();
    466.     }
    467.  
    468.     private static byte[] writeBinaryDouble(double value)
    469.     {
    470.         List<byte> buffer = RegulateNullBytes(BitConverter.GetBytes(value), 4).ToList();
    471.         while (buffer.Count != Math.Pow(2, Math.Log(buffer.Count) / Math.Log(2)))
    472.             buffer.Add(0);
    473.         int header = 0x20 | (int)(Math.Log(buffer.Count) / Math.Log(2));
    474.  
    475.         if (BitConverter.IsLittleEndian)
    476.             buffer.Reverse();
    477.  
    478.         buffer.Insert(0, Convert.ToByte(header));
    479.  
    480.         objectTable.InsertRange(0, buffer);
    481.  
    482.         return buffer.ToArray();
    483.     }
    484.  
    485.     private static byte[] writeBinaryByteArray(byte[] value)
    486.     {
    487.         List<byte> buffer = value.ToList();
    488.         List<byte> header = new List<byte>();
    489.         if (value.Length < 15)
    490.         {
    491.             header.Add(Convert.ToByte(0x40 | Convert.ToByte(value.Length)));
    492.         }
    493.         else
    494.         {
    495.             header.Add(0x40 | 0xf);
    496.             header.AddRange(writeBinaryInteger(buffer.Count, false));
    497.         }
    498.  
    499.         buffer.InsertRange(0, header);
    500.  
    501.         objectTable.InsertRange(0, buffer);
    502.  
    503.         return buffer.ToArray();
    504.     }
    505.  
    506.     private static byte[] writeBinaryString(string value, bool head)
    507.     {
    508.         List<byte> buffer = new List<byte>();
    509.         List<byte> header = new List<byte>();
    510.         foreach (char chr in value.ToCharArray())
    511.             buffer.Add(Convert.ToByte(chr));
    512.  
    513.         if (head)
    514.         {
    515.             if (value.Length < 15)
    516.             {
    517.                 header.Add(Convert.ToByte(0x50 | Convert.ToByte(value.Length)));
    518.             }
    519.             else
    520.             {
    521.                 header.Add(0x50 | 0xf);
    522.                 header.AddRange(writeBinaryInteger(buffer.Count, false));
    523.             }
    524.         }
    525.  
    526.         buffer.InsertRange(0, header);
    527.  
    528.         objectTable.InsertRange(0, buffer);
    529.        
    530.         return buffer.ToArray();
    531.     }
    532.  
    533.     private static byte[] RegulateNullBytes(byte[] value)
    534.     {
    535.         return RegulateNullBytes(value, 1);
    536.     }
    537.  
    538.     private static byte[] RegulateNullBytes(byte[] value, int minBytes)
    539.     {
    540.         Array.Reverse(value);
    541.         List<byte> bytes = value.ToList();
    542.         for (int i = 0; i < bytes.Count; i++)
    543.         {
    544.             if (bytes[i] == 0  bytes.Count > minBytes)
    545.             {
    546.                 bytes.Remove(bytes[i]);
    547.                 i--;
    548.             }
    549.             else
    550.                 break;
    551.         }
    552.  
    553.         if (bytes.Count < minBytes)
    554.         {
    555.             int dist = minBytes - bytes.Count;
    556.             for (int i = 0; i < dist; i++)
    557.                 bytes.Insert(0, 0);
    558.         }
    559.  
    560.         value = bytes.ToArray();
    561.         Array.Reverse(value);
    562.         return value;
    563.     }
    564.  
    565.     private static void parseTrailer(List<byte> trailer)
    566.     {
    567.         offsetByteSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(6, 1).ToArray(), 4), 0);
    568.         objRefSize = BitConverter.ToInt32(RegulateNullBytes(trailer.GetRange(7, 1).ToArray(), 4), 0);
    569.         byte[] refCountBytes = trailer.GetRange(12, 4).ToArray();
    570.         Array.Reverse(refCountBytes);
    571.         refCount = BitConverter.ToInt32(refCountBytes, 0);
    572.         byte[] offsetTableOffsetBytes = trailer.GetRange(24, 8).ToArray();
    573.         Array.Reverse(offsetTableOffsetBytes);
    574.         offsetTableOffset = BitConverter.ToInt64(offsetTableOffsetBytes, 0);
    575.     }
    576.  
    577.     private static void parseOffsetTable(List<byte> offsetTableBytes)
    578.     {
    579.         for (int i = 0; i < offsetTableBytes.Count; i += offsetByteSize)
    580.         {
    581.             byte[] buffer = offsetTableBytes.GetRange(i, offsetByteSize).ToArray();
    582.             Array.Reverse(buffer);
    583.             offsetTable.Add(BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0));
    584.         }
    585.     }
    586.  
    587.     private static object parseBinaryDictionary(int objRef)
    588.     {
    589.         Dictionary<string, object> buffer = new Dictionary<string, object>();
    590.         List<int> refs = new List<int>();
    591.         int refCount = 0;
    592.  
    593.         byte dictByte = objectTable[offsetTable[objRef]];
    594.  
    595.         refCount = getCount(offsetTable[objRef], dictByte);
    596.  
    597.         int refStartPosition;
    598.  
    599.         if (refCount < 15)
    600.             refStartPosition = offsetTable[objRef] + 1;
    601.         else
    602.             refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
    603.  
    604.         for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize)
    605.         {
    606.             byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
    607.             Array.Reverse(refBuffer);
    608.             refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
    609.         }
    610.  
    611.         for (int i = 0; i < refCount; i++)
    612.         {
    613.             buffer.Add((string)parseBinary(refs[i]), parseBinary(refs[i + refCount]));
    614.         }
    615.  
    616.         return buffer;
    617.     }
    618.  
    619.     private static object parseBinaryArray(int objRef)
    620.     {
    621.         List<object> buffer = new List<object>();
    622.         List<int> refs = new List<int>();
    623.         int refCount = 0;
    624.  
    625.         byte arrayByte = objectTable[offsetTable[objRef]];
    626.  
    627.         refCount = getCount(offsetTable[objRef], arrayByte);
    628.  
    629.         int refStartPosition;
    630.  
    631.         if (refCount < 15)
    632.             refStartPosition = offsetTable[objRef] + 1;
    633.         else
    634.             refStartPosition = offsetTable[objRef] + 2 + RegulateNullBytes(BitConverter.GetBytes(refCount), 1).Length;
    635.  
    636.         for (int i = refStartPosition; i < refStartPosition + refCount * 2 * objRefSize; i += objRefSize)
    637.         {
    638.             byte[] refBuffer = objectTable.GetRange(i, objRefSize).ToArray();
    639.             Array.Reverse(refBuffer);
    640.             refs.Add(BitConverter.ToInt32(RegulateNullBytes(refBuffer, 4), 0));
    641.         }
    642.  
    643.         for (int i = 0; i < refCount; i++)
    644.         {
    645.             buffer.Add(parseBinary(refs[i]));
    646.         }
    647.  
    648.         return buffer;
    649.     }
    650.  
    651.     private static int getCount(int bytePosition, byte headerByte)
    652.     {
    653.         byte headerByteTrail = Convert.ToByte(headerByte  0xf);
    654.         if (headerByteTrail < 15)
    655.             return headerByteTrail;
    656.         else
    657.         {
    658.             return (int)parseBinaryInt(bytePosition + 1);
    659.         }
    660.     }
    661.  
    662.     private static object parseBinary(int objRef)
    663.     {
    664.         byte header = objectTable[offsetTable[objRef]];
    665.         switch (header  0xF0)
    666.         {
    667.             case 0x10:
    668.                 {
    669.                     return parseBinaryInt(offsetTable[objRef]);
    670.                 }
    671.             case 0x20:
    672.                 {
    673.                     return parseBinaryReal(offsetTable[objRef]);
    674.                 }
    675.             case 0x40:
    676.                 {
    677.                     return parseBinaryByteArray(offsetTable[objRef]);
    678.                 }
    679.             case 0x50:
    680.                 {
    681.                     return parseBinaryString(offsetTable[objRef]);
    682.                 }
    683.             case 0xD0:
    684.                 {
    685.                     return parseBinaryDictionary(objRef);
    686.                 }
    687.             case 0xA0:
    688.                 {
    689.                     return parseBinaryArray(objRef);
    690.                 }
    691.         }
    692.         throw new Exception("This type is not supported");
    693.     }
    694.  
    695.     private static object parseBinaryInt(int headerPosition)
    696.     {
    697.         byte header = objectTable[headerPosition];
    698.         int byteCount = (int)Math.Pow(2, header  0xf);
    699.         byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
    700.         Array.Reverse(buffer);
    701.  
    702.         return BitConverter.ToInt32(RegulateNullBytes(buffer, 4), 0);
    703.     }
    704.  
    705.     private static object parseBinaryReal(int headerPosition)
    706.     {
    707.         byte header = objectTable[headerPosition];
    708.         int byteCount = (int)Math.Pow(2, header  0xf);
    709.         byte[] buffer = objectTable.GetRange(headerPosition + 1, byteCount).ToArray();
    710.         Array.Reverse(buffer);
    711.  
    712.         return BitConverter.ToDouble(RegulateNullBytes(buffer, 8), 0);
    713.     }
    714.  
    715.     private static object parseBinaryString(int headerPosition)
    716.     {
    717.         byte headerByte = objectTable[headerPosition];
    718.         int charCount = getCount(headerPosition, headerByte);
    719.         int charStartPosition;
    720.         if (charCount < 15)
    721.             charStartPosition = headerPosition + 1;
    722.         else
    723.             charStartPosition = headerPosition + 2 + RegulateNullBytes(BitConverter.GetBytes(charCount), 1).Length;
    724.         string buffer = "";
    725.         foreach (byte byt in objectTable.GetRange(charStartPosition, charCount))
    726.         {
    727.             buffer += Convert.ToChar(byt);
    728.         }
    729.         return buffer;
    730.     }
    731.  
    732.     private static object parseBinaryByteArray(int headerPosition)
    733.     {
    734.         byte headerByte = objectTable[headerPosition];
    735.         int byteCount = getCount(headerPosition, headerByte);
    736.         int byteStartPosition;
    737.         if (byteCount < 15)
    738.             byteStartPosition = headerPosition + 1;
    739.         else
    740.             byteStartPosition = headerPosition + 2 + RegulateNullBytes(BitConverter.GetBytes(byteCount), 1).Length;
    741.         return objectTable.GetRange(byteStartPosition, byteCount).ToArray();
    742.     }
    743.    
    744.     #endregion
    745. }
    746.  
     
    Last edited: Nov 28, 2011
  6. gw1108

    gw1108

    Joined:
    Jan 22, 2013
    Posts:
    6