/// <summary> /// Saves all of the data associated with the given structure. /// </summary> /// <param name="type">The type ID of the structure</param> /// <param name="dict">The structure's dictionary</param> /// <param name="rawData">The raw data in which to save the structure</param> /// <returns>The index of the structure in the raw data</returns> public static uint SaveFieldStruct(uint type, GffFieldDictionary dict, RawGffData rawData) { // Create the structure and fill in the data we can then add it. Note // that we can't fill in the DataOrDataOffset yet since we don't know // what that value is until after all of the fields have been added. // We will update the structure when we are done. RawGffData.RawGffStruct rawStruct = new RawGffData.RawGffStruct(type); rawStruct.FieldCount = (uint) dict.Count; rawStruct.DataOrDataOffset = 0; uint structureIndex = rawData.AddStruct(rawStruct); // Create an array to hold all of the field index values and loop through // the dictionary to store all of the structure elements. uint[] indeces = new uint[dict.Count]; uint i = 0; foreach (DictionaryEntry entry in dict) { // Get the label and field from the entry. string label = (string) entry.Key; GffField field = (GffField) entry.Value; // Create a raw field for the field. RawGffData.RawGffField rawField = new RawGffData.RawGffField(field.Type); // Get the index of the label, adding it if it's not in the raw data. rawField.LabelIndex = (uint) rawData.GetLabelIndex(label); if (0xffffffff == rawField.LabelIndex) rawField.LabelIndex = (uint) rawData.AddLabel(label); // Serialize the field's data and save the offset to the serialized // data (for some fields the offset may be the data itself). IGffFieldSerialize serialize = (IGffFieldSerialize) field; rawField.DataOrDataOffset = serialize.Serialize(rawData); // Add the field to the raw data, saving the index of the added // field in our index array. indeces[i++] = rawData.AddField(rawField); } // If we have multiple fields, we have to add the index array to the // field indeces and save the offset, otherwise we can just save the // field index as our data offset. Once we do this we have to update // the structure to store the offset. rawStruct.DataOrDataOffset = 1 == dict.Count ? indeces[0] : rawData.AddFieldIndeces(indeces); rawData.UpdateStruct(structureIndex, rawStruct); // Return the structure's index. return structureIndex; }
/// <summary> /// Override to deserialize the object from the GFF file's binary data. /// </summary> /// <param name="rawField">The raw field from the GFF</param> /// <param name="rawData">The GFF's raw file data</param> void IGffFieldSerialize.Deserialize(RawGffData.RawGffField rawField, RawGffData rawData) { // Get the list of structure indeces for the items in the list uint[] indeces = rawData.GetListIndeces(rawField.DataOrDataOffset); // Create a field collection for the structures, and loop through // the index array. GffFieldCollection fields = new GffFieldCollection(); for (int i = 0; i < indeces.Length; i++) { // Get the raw structure data for this structure. RawGffData.RawGffStruct rawStruct = rawData.GetStruct(indeces[i]); // Create a GffStructField object for the structure and set it's // structure type. GffStructField field = (GffStructField) GffFieldFactory.CreateField(GffFieldType.Struct); field.StructureType = rawStruct.Type; // Create a dummy field object so we can deserialize the structure, // set it's DataOrDataOffset to the structure index. RawGffData.RawGffField dummyField = new RawGffData.RawGffField(GffFieldType.Struct); dummyField.LabelIndex = 0; dummyField.DataOrDataOffset = indeces[i]; // Deserialize the structure. ((IGffFieldSerialize) field).Deserialize(dummyField, rawData); // Add the structure to the collection. fields.Add(field); } Value = fields; }