public IndexDefinitionRecord(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            ExternalFile = rx.ZeroTerminatedString();

            if (ExternalFile.Length == 0)
            {
                int read = rx.Byte();

                if (read != 0x01)
                {
                    throw new ArgumentException($"Bad index definition: missing 0x01 after zero string ({read:X2})");
                }
            }

            Name        = rx.ZeroTerminatedString();
            Flags       = rx.Byte();
            FieldsInKey = rx.ShortLE();

            KeyField     = new int[FieldsInKey];
            KeyFieldFlag = new int[FieldsInKey];

            for (int i = 0; i < FieldsInKey; i++)
            {
                KeyField[i]     = rx.ShortLE();
                KeyFieldFlag[i] = rx.ShortLE();
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates a new <see cref="TpsRecord"/> by partially copying the previous one.
        /// </summary>
        /// <param name="previous">The previous record.</param>
        /// <param name="rx">The data to read from.</param>
        public TpsRecord(TpsRecord previous, RandomAccess rx)
        {
            if (previous == null)
            {
                throw new ArgumentNullException(nameof(previous));
            }

            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Flags = rx.Byte();

            if ((Flags & 0x80) != 0)
            {
                RecordLength = rx.ShortLE();
            }
            else
            {
                RecordLength = previous.RecordLength;
            }

            if ((Flags & 0x40) != 0)
            {
                HeaderLength = rx.ShortLE();
            }
            else
            {
                HeaderLength = previous.HeaderLength;
            }

            int copy = Flags & 0x3F;

            var newData = new List <byte>(RecordLength);

            newData.AddRange(previous.Data.GetData().Take(copy));
            newData.AddRange(rx.ReadBytes(RecordLength - copy));

            Data = new RandomAccess(newData.ToArray());

            if (Data.Length != RecordLength)
            {
                throw new ArgumentException("Data and record length mismatch.");
            }

            BuildHeader();
        }
        public TableDefinitionHeader(RandomAccess rx)
            : base(rx)
        {
            AssertIsType(0xFA);

            Block = rx.ShortLE();
        }
Exemple #4
0
        public TpsHeader(RandomAccess rx)
        {
            Data = rx ?? throw new ArgumentNullException(nameof(rx));

            Address = rx.LongLE();

            if (Address != 0)
            {
                throw new NotATopSpeedFileException("File does not start with 0x00000000. It is not a TopSpeed file or it may be encrypted.");
            }

            HeaderSize = rx.ShortLE();

            var header = rx.Read(HeaderSize - 6);

            FileLength1             = header.LongLE();
            FileLength2             = header.LongLE();
            MagicNumber             = header.FixedLengthString(4);
            Zeroes                  = header.ShortLE();
            LastIssuedRow           = header.LongBE();
            Changes                 = header.LongLE();
            ManagementPageReference = header.ToFileOffset(header.LongLE());

            PageStart = header.ToFileOffset(header.LongArrayLE((0x110 - 0x20) / 4));
            PageEnd   = header.ToFileOffset(header.LongArrayLE((0x200 - 0x110) / 4));
        }
        public void ShouldParseShortLittleEndian(short value, byte[] data)
        {
            var   rx     = new RandomAccess(data);
            short parsed = rx.ShortLE();

            Assert.AreEqual(value, parsed);
        }
Exemple #6
0
        /// <summary>
        /// Instantiates a new SHORT.
        /// </summary>
        /// <param name="rx"></param>
        public TpsShort(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Value = rx.ShortLE();
        }
Exemple #7
0
        /// <summary>
        /// Creates a new <see cref="TpsRecord"/>. This is typically done on the first of a list.
        /// </summary>
        /// <param name="rx">The data to read from.</param>
        public TpsRecord(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Flags = rx.Byte();

            if ((Flags & 0xC0) != 0xC0)
            {
                throw new ArgumentException($"Cannot construct a TpsRecord without record lengths (0x{rx.ToHex2(Flags)})");
            }

            RecordLength = rx.ShortLE();
            HeaderLength = rx.ShortLE();

            Data = rx.Read(RecordLength);

            BuildHeader();
        }
Exemple #8
0
        public FieldDefinitionRecord(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Type         = (TpsTypeCode)rx.Byte();
            Offset       = rx.ShortLE();
            FullName     = rx.ZeroTerminatedString();
            ElementCount = rx.ShortLE();
            Length       = rx.ShortLE();
            Flags        = rx.ShortLE();
            Index        = rx.ShortLE();

            switch (Type)
            {
            case TpsTypeCode.Decimal:
                BcdDigitsAfterDecimalPoint = rx.Byte();
                BcdElementLength           = rx.Byte();
                break;

            case TpsTypeCode.String:
            case TpsTypeCode.CString:
            case TpsTypeCode.PString:
                StringLength = rx.ShortLE();
                StringMask   = rx.ZeroTerminatedString();
                if (StringMask.Length == 0)
                {
                    rx.Byte();
                }
                break;
            }
        }
        public TableDefinitionRecord(RandomAccess rx, Encoding encoding)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Encoding = encoding ?? throw new ArgumentNullException(nameof(encoding));

            DriverVersion = rx.ShortLE();
            RecordLength  = rx.ShortLE();
            FieldCount    = rx.ShortLE();
            MemoCount     = rx.ShortLE();
            IndexCount    = rx.ShortLE();

            _fields  = new List <FieldDefinitionRecord>();
            _memos   = new List <MemoDefinitionRecord>();
            _indexes = new List <IndexDefinitionRecord>();

            try
            {
                for (int i = 0; i < FieldCount; i++)
                {
                    _fields.Add(new FieldDefinitionRecord(rx));
                }
                for (int i = 0; i < MemoCount; i++)
                {
                    _memos.Add(new MemoDefinitionRecord(rx));
                }
                for (int i = 0; i < IndexCount; i++)
                {
                    _indexes.Add(new IndexDefinitionRecord(rx));
                }
            }
            catch (ArgumentException ex)
            {
                throw new ArgumentException($"Bad table definition: {ToString()}", ex);
            }
        }
Exemple #10
0
        public MemoDefinitionRecord(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            ExternalFile = rx.ZeroTerminatedString();

            if (ExternalFile.Length == 0)
            {
                byte memoMarker = rx.Byte();

                if (memoMarker != 1)
                {
                    throw new ArgumentException($"Bad memo definition: missing 0x01 after zero string. Was 0x{memoMarker:x2}.");
                }
            }

            FullName = rx.ZeroTerminatedString();
            Length   = rx.ShortLE();
            Flags    = rx.ShortLE();
        }
Exemple #11
0
        public TpsPage(RandomAccess rx)
        {
            if (rx == null)
            {
                throw new ArgumentNullException(nameof(rx));
            }

            Records = new List <TpsRecord>();

            Address = rx.LongLE();
            Size    = rx.ShortLE();

            var header = rx.Read(Size - 6);

            SizeUncompressed = header.ShortLE();
            SizeUncompressedWithoutHeader = header.ShortLE();
            RecordCount = header.ShortLE();
            Flags       = header.Byte();

            CompressedData = header.Read(Size - 13);
        }