Exemple #1
0
        public IndexFileNTX(Stream stream, DbfTable dbfTable, bool?skipDeleted = null, int indexPageCacheSize = 0)
            : base(stream, dbfTable, skipDeleted, indexPageCacheSize)         // 'stream', 'dbfTable' and 'skipDeleted' already stored by base class constructor
        {
            this.header = GetHeader(stream);                                  // fill 'header' & IsStreamValid/Exception if error

            Top();
        }
Exemple #2
0
        public static NtxHeader GetHeader(Stream stream)
        {
            if (stream.Length < (pageSize * 2))
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "NTX index stream length '{0}' < '{1}'!", stream.Length, (pageSize * 2));
            }

            if ((stream.Length % pageSize) != 0)
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "NTX index stream length ({0}) isn't a multiple of '{1}'!", stream.Length, pageSize);
            }

            //

            NtxHeader header = new NtxHeader();

            stream.Position = 0;

            BinaryReader reader = new BinaryReader(stream);                     // don't use 'using (BinaryReader reader...' because 'using' dispose 'stream' too!

            header.signature = reader.ReadUInt16();
            header.version   = reader.ReadUInt16();
            header.root      = reader.ReadInt32();
            header.unused    = reader.ReadInt32();
            header.itemSize  = reader.ReadUInt16();
            header.keySize   = reader.ReadUInt16();
            header.keyDec    = reader.ReadUInt16();
            header.maxItem   = reader.ReadUInt16();
            header.halfPage  = reader.ReadUInt16();
            header.keyExpr   = reader.ReadBytes(maxKeyLen);

            byte uniqueFlag = reader.ReadByte();

            header.unique = (uniqueFlag != 0);

            Debug.Assert(reader.BaseStream.Position == 279);

            //

            byte sign1Byte = (byte)(header.signature >> 8);                       // get first byte

            if (!Array.Exists(validSignatures, s => (s == sign1Byte)))
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "Signature byte of NTX index stream is invalid! '{0}'", sign1Byte);
            }

            byte sign2Byte = (byte)(header.signature);                            // cut off first byte

            if (sign2Byte != 0)
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "Second signature byte in NTX index stream header is invalid!'{0}'", sign2Byte);
            }

            if ((header.keySize < 1) || (header.keySize > 250))
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "Key size in NTX index stream header is invalid!");
            }

            if ((header.keySize + 8) != header.itemSize)
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "Key size (+8) in NTX index stream header is invalid!");
            }

            if (ProcessKeyExpressionBuffer(header.keyExpr) == null)
            {
                throw ExceptionFactory.CreateNotSupportedException("Content of key expression bytes is envalid!");
            }

            if (!((uniqueFlag == 0) || (uniqueFlag == 1)))
            {
                throw ExceptionFactory.CreateArgumentOutOfRangeException("stream", "Unique flag in NTX index stream header is invalid!");
            }

            //

            return(header);
        }