public void Test_TAGHeader_Read() { using (var reader = new TAGReader(new FileStream(Path.Combine("TestData", "TAGFiles", "TestTAGFile-TAG-Header-Read.tag"), FileMode.Open))) { Assert.NotNull(reader); TAGHeader header = new TAGHeader(); //Read the header header.Read(reader); Assert.Equal(1U, header.DictionaryID); Assert.Equal(1U, header.DictionaryMajorVer); Assert.Equal(4U, header.DictionaryMinorVer); Assert.Equal(1U, header.MajorVer); Assert.Equal(0U, header.MinorVer); Assert.True( header.FieldAndTypeTableOffset > 0 && header.FieldAndTypeTableOffset < reader.StreamSizeInNybbles / 2, "Field and type table offset read from header is invalid"); } }
/// <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); }