Exemplo n.º 1
0
        /// <summary>
        /// Reads a record using the previous data available.
        /// TPS uses a stupid ( prossesing costly ) method to save space. It copies data from the last record if possible
        /// </summary>
        /// <param name="previous"></param>
        /// <param name="pageDataRandomAccess"></param>
        public TPSRecord(ref TPSRecord previous, ref RandomAccess pageDataRandomAccess)
        {
            //the flag tells us what data we should be copying
            _flags = pageDataRandomAccess.leByte();
            if ((_flags & 0x80) != 0)
            {
                _recordLength = pageDataRandomAccess.leShort();
            }
            else
            {
                _recordLength = previous.RecordLength;
            }
            if ((_flags & 0x40) != 0)
            {
                _headerLength = pageDataRandomAccess.leShort();
            }
            else
            {
                _headerLength = previous.HeaderLength;
            }

            //The last part tells us how much actual record data we should copy
            int copy = _flags & 0x3F;

            _data = new byte[_recordLength];
            try {
                Buffer.BlockCopy(previous.RecordData, 0, _data, 0, copy);
                Buffer.BlockCopy(pageDataRandomAccess.leBytes(_recordLength - copy), 0, _data, copy, (_recordLength - copy));
                //We may have to check if we pulled enough bytes from the pageDataRA, incase we hit the end prematurely
            } catch (Exception ex) {
                throw new Exception("When reading " + (_recordLength - copy) + " bytes of TpsRecord");
            }
            //
            buildHeader();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets data from the page
        /// If the page is compressed, it will uncompress it and return it.
        /// </summary>
        /// <returns></returns>
        private byte[] GetData()
        {
            //set our Randomaccess to the start of this page
            RandomAccess ra = RandomAccess.GetInstance();

            byte[] pageData;
            ra.jumpAbs(addr);

            ra.jumpRelative(13);             //skip the header

            //pull the page data
            //This really shouldn't be very big.. on my files it was about 8kb
            //If the file is using compression... uncompress it

            if ((pageSize != pageSizeUncompressed) && (flags == 0))
            {
                try {
                    pageData = ra.deRle(pageSize - 13);
                } catch (Exception ex) {
                    throw new Exception("Bad RLE DataBlock ( compressed: " + pageSize + " uncompressed: " + pageSizeUncompressed + " Page Address: " + addr + "Record Count: " + recordCount.ToString() + "): ", ex);
                }
            }
            else
            {
                pageData = ra.leBytes(pageSize - 13);
            }

            return(pageData);
        }
Exemplo n.º 3
0
        public TPSRecord(ref RandomAccess pageDataRandomAccess)
        {
            _flags = pageDataRandomAccess.leByte();
            if ((_flags & 0xC0) != 0xC0)
            {
                throw new Exception("Can't construct a TpsRecord without record lengths");
            }
            _recordLength = pageDataRandomAccess.leShort();
            _headerLength = pageDataRandomAccess.leShort();

            _data = pageDataRandomAccess.leBytes(_recordLength);     //read all of the data into a buffer.
            //
            buildHeader();
        }
Exemplo n.º 4
0
        public object parseField(int type, int ofs, int len, TableField field, RandomAccess ra)
        {
            ra.jumpAbs(ofs);
            switch (type)
            {
            case 1:
                // byte
                assertEqual(1, len);
                return(ra.leByte());

            case 2:
                // short
                assertEqual(2, len);
                return(ra.leShort());

            case 3:
                // unsigned short
                assertEqual(2, len);
                return(ra.leUShort());

            case 4:
                // Date, mask encoded.
                long date = ra.leULong();
                if (date != 0)
                {
                    long years  = (date & 0xFFFF0000) >> 16;
                    long months = (date & 0x0000FF00) >> 8;
                    long days   = (date & 0x000000FF);
                    return(new DateTime((int)years, (int)months, (int)days));
                }
                else
                {
                    return(null);
                }

            case 5:
                //
                // Time, mask encoded.
                // So far i've only had values with hours and minutes
                // but no seconds or milliseconds so I've no way of
                // knowing how to decode these.
                //
                //TODO: Fix the time here based on decaseconds
                int time  = ra.leLong();
                int mins  = (time & 0x00FF0000) >> 16;
                int hours = (time & 0x7F000000) >> 24;
                //
                return(hours + " " + mins);            //

            case 6:
                // Long
                assertEqual(4, len);
                return(ra.leLong());

            case 7:
                // Unsigned Long
                assertEqual(4, len);
                return(ra.leULong());

            case 8:
                // Float
                assertEqual(4, len);
                return(ra.leFloat());

            case 9:
                // Double
                assertEqual(8, len);
                return(ra.leDouble());

            case 0x0A:
                // BCD encoded.
                return(ra.binaryCodedDecimal(len, field.BcdLengthOfElement, field.BcdDigitsAfterDecimalPoint));

            case 0x12:
                // Fixed Length String
                return(ra.fixedLengthString(len));

            case 0x13:
                return(ra.zeroTerminatedString());

            case 0x14:
                return(ra.pascalString());

            case 0x16:
                // Group (an overlay on top of existing data, can be anything).
                return(ra.leBytes(len));

            default:
                throw new Exception("Unsupported type " + type + " (" + len + ")");
            }
        }