Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }