/// <summary> /// Reads the TAG file schema dictionary from the TAG file data using the TAG file reader /// </summary> /// <param name="reader"></param> /// <returns></returns> public bool Read(TAGReader reader) { string fieldName; while ((fieldName = reader.ReadANSIString()) != string.Empty) { uint tempFieldType = reader.ReadUnSignedIntegerValue(1); // If field type is 15, then read an extra var int to determine extended data type if (tempFieldType == 15) { if (!reader.ReadVarInt(out short tempFieldTypeExtended)) { return(false); } tempFieldType += (uint)tempFieldTypeExtended; } var fieldType = (TAGDataType)tempFieldType; if (!reader.ReadVarInt(out var id)) { return(false); } Entries.Add(id, new TAGDictionaryItem(fieldName, fieldType, id)); } if (Entries.Count > DEFAULT_TAG_FILE_SCHEMA_DICTIONARY_CAPACITY) { Log.LogInformation($"TAG file schema dictionary final size of {Entries.Count} exceeds default capacity for dictionary of {DEFAULT_TAG_FILE_SCHEMA_DICTIONARY_CAPACITY}. Consider increasing it."); } return(true); }
} // This is a byte offset /// <summary> /// Reads the contents of the TAG file header using the provided reader /// </summary> /// <param name="reader"></param> public void Read(TAGReader reader) { MajorVer = reader.ReadUnSignedIntegerValue(1); MinorVer = reader.ReadUnSignedIntegerValue(1); DictionaryID = reader.ReadUnSignedIntegerValue(4); DictionaryMajorVer = reader.ReadUnSignedIntegerValue(1); DictionaryMinorVer = reader.ReadUnSignedIntegerValue(1); FieldAndTypeTableOffset = reader.ReadUnSignedIntegerValue(8); }
/// <summary> /// Reads the context of a TAG file using the provided reader and sink /// </summary> /// <param name="reader"></param> /// <param name="sink"></param> /// <returns></returns> public TAGReadResult Read(TAGReader reader, TAGValueSinkBase sink) { try { if (reader.StreamSizeInNybbles == 0) { return(TAGReadResult.ZeroLengthFile); } try { Header.Read(reader); } catch (Exception E) { Log.LogError(E, "Invalid tag file. Exception in TTagFile.ReadStream - Header.LoadFromStream:"); return(TAGReadResult.InvalidDictionary); } // If the offset to the dictionary is zero, then it follows immediately after the header long DataEndPos; try { if (Header.FieldAndTypeTableOffset != 0) { long StreamPos = reader.NybblePosition; reader.NybblePosition = Header.FieldAndTypeTableOffset * 2; // FieldAndTypeTableOffset is in bytes if (!Dictionary.Read(reader)) { return(TAGReadResult.InvalidDictionary); } reader.NybblePosition = StreamPos; DataEndPos = Header.FieldAndTypeTableOffset * 2; // FieldAndTypeTableOffset is in bytes } else { if (!Dictionary.Read(reader)) { return(TAGReadResult.InvalidDictionary); } DataEndPos = reader.StreamSizeInNybbles; } } catch (Exception E) { Log.LogWarning(E, "Exception in TagFile.ReadFile:"); return(TAGReadResult.InvalidDictionary); } // Now read in the data from the file if (!sink.Starting()) { return(TAGReadResult.SinkStartingFailure); } while (!sink.Aborting() && reader.NybblePosition < DataEndPos) { if (!reader.ReadVarInt(out short ValueTypeID)) { if (reader.NybblePosition >= DataEndPos) { break; // We have finished } return(TAGReadResult.InvalidValueTypeID); // This is an invalid tag file } if (Dictionary.Entries.Keys.Count == 0) { return(TAGReadResult.InvalidDictionary); } if (!Dictionary.Entries.TryGetValue(ValueTypeID, out TAGDictionaryItem DictionaryEntry)) { return(TAGReadResult.InvalidValueTypeID); } try { switch (DictionaryEntry.Type) { case TAGDataType.t4bitInt: case TAGDataType.t8bitInt: case TAGDataType.t12bitInt: case TAGDataType.t16bitInt: case TAGDataType.t32bitInt: sink.ReadIntegerValue(DictionaryEntry, reader.ReadSignedIntegerValue(IntegerNybbleSizes.Nybbles[(byte)DictionaryEntry.Type])); break; case TAGDataType.t4bitUInt: case TAGDataType.t8bitUInt: case TAGDataType.t12bitUInt: case TAGDataType.t16bitUInt: case TAGDataType.t32bitUInt: sink.ReadUnsignedIntegerValue(DictionaryEntry, reader.ReadUnSignedIntegerValue(IntegerNybbleSizes.Nybbles[(byte)DictionaryEntry.Type])); break; case TAGDataType.tIEEESingle: sink.ReadIEEESingleValue(DictionaryEntry, reader.ReadSinglePrecisionIEEEValue()); break; case TAGDataType.tIEEEDouble: sink.ReadIEEEDoubleValue(DictionaryEntry, reader.ReadDoublePrecisionIEEEValue()); break; case TAGDataType.tANSIString: sink.ReadANSIStringValue(DictionaryEntry, reader.ReadANSIString()); break; case TAGDataType.tUnicodeString: sink.ReadUnicodeStringValue(DictionaryEntry, reader.ReadUnicodeString()); break; case TAGDataType.tEmptyType: sink.ReadEmptyValue(DictionaryEntry); break; } } catch (Exception E) { Log.LogError(E, "Exception in TagFile.ReadFile while reading field value:"); return(TAGReadResult.InvalidValue); } } if (!sink.Finishing()) { return(TAGReadResult.SinkFinishingFailure); } } catch (IOException E) { Log.LogDebug(E, "Exception in TagFile.ReadFile:"); return(TAGReadResult.CouldNotOpenFile); } return(TAGReadResult.NoError); }