internal FIELD(GffFieldType type, string label = "") { if (label.Length > MAX_LABEL_LENGTH) { throw new Exception($"Label \"{label}\" is longer than {MAX_LABEL_LENGTH} characters, and is invalid."); } Type = type; Label = label; }
/// <summary> /// This method updates the cache and hak list properties in the module /// info, adding the passed array of strings to the appropriate property. /// Both of these lists consist of an array of structures with 1 string /// item in each struture. /// </summary> /// <param name="listTag">The property name for the list</param> /// <param name="entryTag">The property name for each string in the list's /// structures</param> /// <param name="structID">The structure ID of the structures in the list</param> /// <param name="stringType">The data type of the string in the list, either /// ExoString or ResRef</param> /// <param name="values">The array of strings to add, duplicates are pruned</param> private void UpdateList(string listTag, string entryTag, uint structID, GffFieldType stringType, string[] values) { // Get the array of elements in the list. GffListField listField = (GffListField) GetField(properties[listTag]); GffFieldCollection list = listField.Value; // Create a string collection containing lower case copies of all of // the strings. StringCollection strings = new StringCollection(); strings.AddRange(values); for (int i = 0; i < strings.Count; i ++) strings[i] = strings[i].ToLower(); // Make a first pass and eliminate any strings that are already // in the module. foreach (GffStructField field in list) { // Get the string entry for the value. GffFieldDictionary dict = field.Value; GffField structValue = dict[entryTag]; // Check to see if the hak is in the list of haks to add if it is // then remove it. int index = strings.IndexOf((string) structValue.Value); if (-1 != index) strings.RemoveAt(index); } // Now loop through all of the remaining strings and add them to the // beginning of the list. We walk the list backwards adding the items // to the beginning of the list's collection, so when we are done // all of the added items are in order at the FRONT of the list. for (int i = strings.Count - 1; i >= 0; i--) { // Create a ExoString field for the hak file name. GffField structValue = GffFieldFactory.CreateField(stringType); structValue.Value = strings[i]; // Create a GffStructField for the new list element and // save the exoString hak name in it. GffStructField listStruct = (GffStructField) GffFieldFactory.CreateField(GffFieldType.Struct); listStruct.StructureType = structID; listStruct.Value = new GffFieldDictionary(); listStruct.Value.Add(entryTag, structValue); // Add the structure to the list. list.Insert(0, listStruct); } }
private static FIELD CreateNewField(BinaryReader br, int index, int fieldOffset, int dataOrDataOffset, GffFieldType fieldType) { FIELD data; switch (fieldType) { case GffFieldType.BYTE: data = new BYTE(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.CHAR: data = new CHAR(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.WORD: data = new WORD(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.SHORT: data = new SHORT(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.DWORD: data = new DWORD(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.INT: data = new INT(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.DWORD64: data = new DWORD64(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.INT64: data = new INT64(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.FLOAT: data = new FLOAT(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.DOUBLE: data = new DOUBLE(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.CExoString: data = new CExoString(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.ResRef: data = new ResRef(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.CExoLocString: data = new CExoLocString(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.VOID: data = new VOID(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.Struct: int lbl_index = br.ReadInt32(); data = new STRUCT(br, br.ReadInt32(), lbl_index); break; case GffFieldType.List: data = new LIST(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.Orientation: data = new Orientation(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.Vector: data = new Vector(br, fieldOffset + dataOrDataOffset * 12); break; case GffFieldType.StrRef: data = new StrRef(br, fieldOffset + dataOrDataOffset * 12); break; default: throw new Exception(string.Format("UNEXPECTED FIELD TYPE \"{0}\", IN STRUCT INDEX \"{1}\"", fieldType, index)); } return(data); }
internal STRUCT(BinaryReader br, int index, int LabelIndex = -1) : base(GffFieldType.Struct) { //Header Info br.BaseStream.Seek(8, 0); int StructOffset = br.ReadInt32(); int StuctCount = br.ReadInt32(); int FieldOffset = br.ReadInt32(); int FieldCount = br.ReadInt32(); int LabelOffset = br.ReadInt32(); int LabelCount = br.ReadInt32(); int FieldDataOffset = br.ReadInt32(); int FieldDataCount = br.ReadInt32(); int FieldIndicesOffset = br.ReadInt32(); //label logic if (LabelIndex < 0 || LabelIndex > LabelCount) { Label = ""; } else { br.BaseStream.Seek(LabelOffset + LabelIndex * 16, 0); Label = new string(br.ReadChars(16)).TrimEnd('\0'); } //Struct Info br.BaseStream.Seek(StructOffset + index * 12, 0); Struct_Type = br.ReadInt32(); int DataOrDataOffset = br.ReadInt32(); int S_FieldCount = br.ReadInt32(); //If there is only one field, it pulls it from the field area if (S_FieldCount == 1) { br.BaseStream.Seek(FieldOffset + DataOrDataOffset * 12, 0); GffFieldType fieldType = (GffFieldType)br.ReadInt32(); FIELD data = CreateNewField(br, index, FieldOffset, DataOrDataOffset, fieldType); Fields.Add(data); } //If there is more than one field, a set of Indices are read off, and then those fields are read in else if (S_FieldCount > 1) { for (int i = 0; i < S_FieldCount; i++) { br.BaseStream.Seek(FieldIndicesOffset + DataOrDataOffset + 4 * i, 0); int f_index = br.ReadInt32(); br.BaseStream.Seek(FieldOffset + f_index * 12, 0); GffFieldType fieldType = (GffFieldType)br.ReadInt32(); FIELD data = CreateNewField(br, index, FieldOffset, f_index, fieldType); Fields.Add(data); } } else if (S_FieldCount == 0) { return; } else { throw new Exception(string.Format("BAD FIELD COUNT \"{0}\", IN STRUCT INDEX \"{1}\"", S_FieldCount, index)); } }
/// <summary> /// Class constructor /// </summary> /// <param name="type">Data type of the field</param> public RawGffField(GffFieldType type) { Type = (UInt32) type; LabelIndex = 0; DataOrDataOffset = 0; }
/// <summary> /// Class constructor /// </summary> /// <param name="uiName">Display name of the field</param> /// <param name="label">Tag of the field</param> /// <param name="type">Data type of the field</param> /// <param name="structureID">Structure ID of the field, only meaningful /// for lists and structures</param> /// <param name="children">Schema for the structure's child fields</param> public GffFieldSchema(string uiName, string tag, GffFieldType type, uint structID, GffSchemaCollection children) { this.uiName = uiName; this.tag = tag; this.type = type; this.structID = structID; this.children = children; }
/// <summary> /// Class constructor /// </summary> /// <param name="uiName">Display name of the field</param> /// <param name="label">Tag of the field</param> /// <param name="type">Data type of the field</param> public GffFieldSchema(string uiName, string tag, GffFieldType type) : this(uiName, tag, type, 0, null) { }
/// <summary> /// Creates a GffField derived object for the specified field type. /// </summary> /// <param name="type">The type of object to create</param> /// <returns>The created GffField derived object</returns> public static GffField CreateField(GffFieldType type) { switch (type) { case GffFieldType.Byte: return new GffByteField(); case GffFieldType.Char: return new GffCharField(); case GffFieldType.Word: return new GffWordField(); case GffFieldType.Short: return new GffShortField(); case GffFieldType.DWord: return new GffDWordField(); case GffFieldType.Int: return new GffIntField(); case GffFieldType.Float: return new GffFloatField(); case GffFieldType.DWord64: return new GffDWord64Field(); case GffFieldType.Int64: return new GffInt64Field(); case GffFieldType.Double: return new GffDoubleField(); case GffFieldType.ResRef: return new GffResRefField(); case GffFieldType.ExoString: return new GffExoStringField(); case GffFieldType.Void: return new GffVoidField(); case GffFieldType.Struct: return new GffStructField(); case GffFieldType.List: return new GffListField(); case GffFieldType.ExoLocString: return new GffExoLocStringField(); default: throw new NWNException("Unsupported data type"); } }
/// <summary> /// Class constructor /// </summary> /// <param name="fieldType">The data type of the field.</param> /// <param name="fieldValue">The field's value</param> protected GffField(GffFieldType fieldType, object fieldValue) { // Make sure the derived class implements IGffSerialize if (!(this is IGffFieldSerialize)) throw new NWNException("Must implement IGffSerialize"); this.fieldType = fieldType; this.fieldValue = fieldValue; }