public static SharedObject Parse(string filename, SharedObject so = null) { if (so == null) { so = new SharedObject(); } if (!File.Exists(filename)) { Console.WriteLine("SharedObject " + filename + " doesn't exist."); return(so); } SOReader file = new SOReader(filename); List <string> string_table = new List <string>(); //Read header SOHeader header = new SOHeader(); header.padding1 = file.Read16(); header.file_size = file.Read32(); file.file_size = (int)header.file_size + 6; header.padding2 = file.Read32(); header.padding3 = file.Read16(); header.padding4 = file.Read32(); Console.WriteLine("Data size: " + header.file_size); //Read SO name and othe rparameters UInt16 so_name_length = file.Read16(); string so_name = file.ReadString(so_name_length); //string_table.Add(so_name); Console.WriteLine("SO name: " + so_name); UInt32 so_type = file.Read32(); Console.WriteLine("SO type: " + so_type); while (file.pos < file.file_size) { SOValue so_value = new SOValue(); // Read parameter name. Name length is encoded into 7 bits, 8th bit is flag if name is inline or indexed. UInt32 length_int = (UInt32)file.ReadCompressedInt(); bool name_inline = (length_int & 0x01) > 0; length_int >>= 1; if (name_inline) { so_value.key = file.ReadString((int)length_int); string_table.Add(so_value.key); } else { so_value.key = string_table[(int)length_int]; } Console.WriteLine(so_value.key + " (inline: " + name_inline + ")"); // Read parameter value. First byte is value type. so_value.type = file.Read8(); if (so_value.type == SOTypes.TYPE_NULL) { Console.WriteLine("\tNULL"); } else if (so_value.type == SOTypes.TYPE_BOOL_FALSE) { so_value.bool_val = false; Console.WriteLine("\tFalse"); } else if (so_value.type == SOTypes.TYPE_BOOL_TRUE) { so_value.bool_val = true; Console.WriteLine("\tTrue"); } else if (so_value.type == SOTypes.TYPE_INT) { so_value.int_val = (int)file.ReadCompressedInt(); Console.WriteLine("\t" + so_value.int_val); } else if (so_value.type == SOTypes.TYPE_DOUBLE) { so_value.double_val = file.ReadDouble(); Console.WriteLine("\t" + so_value.double_val); } else if (so_value.type == SOTypes.TYPE_STRING) { Int32 val_length = file.ReadCompressedInt(); bool val_inline = (val_length & 0x00000001) > 0; val_length >>= 1; if (!val_inline) { Console.WriteLine("\tReference to string: " + val_length); if (val_length < string_table.Count) { so_value.string_val = string_table[(int)val_length]; Console.WriteLine("\t" + so_value.string_val); } } else { so_value.string_val = file.ReadString((int)val_length); string_table.Add(so_value.string_val); Console.WriteLine("\t" + so_value.string_val + " (" + val_length + ")"); } } else { Console.WriteLine("Type not implemented yet: " + so_value.type); //Move read position to next item while (file.pos < file.file_size) { byte next_byte = file.Read8(); if (next_byte == 0) { --file.pos; break; } } } so.values.Add(so_value); if (file.pos < file.file_size) { file.Read8(); //Padding } } return(so); }