Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    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