Пример #1
0
        protected void SplitArea(long offset, long newBoundary)
        {
            // Split the area pointed to by the offset.
            Read(offset, headerBuf, 0, 8);
            long curSize   = BytesUtil.ReadInt8(headerBuf, 0) & ActiveFlag;
            long leftSize  = newBoundary;
            long rightSize = curSize - newBoundary;

            if (rightSize < 0)
            {
                throw new IOException("Could not split the area.");
            }

            BytesUtil.WriteInt8(leftSize, headerBuf, 0);
            BytesUtil.WriteInt8(rightSize, headerBuf, 8);

            // ISSUE: Boundary alteration is a moment when corruption could occur.
            //   There are three seeks and writes here and when we are setting the
            //   end points, there is a risk of failure.

            // First set the boundary
            Write((offset + newBoundary) - 8, headerBuf, 0, 16);
            // Now set the end points
            Write(offset, headerBuf, 0, 8);
            Write((offset + curSize) - 8, headerBuf, 8, 8);
        }
Пример #2
0
        public void BuildPage(long buildPageNumber, long position, byte[] pageBuffer, int offset)
        {
            lock (this) {
                File.Read(position, buffer, 0, 36);

                var type       = BytesUtil.ReadInt8(buffer, 0);
                var resourceId = BytesUtil.ReadInt8(buffer, 12);
                var pageNumber = BytesUtil.ReadInt8(buffer, 20);
                var pageOffset = BytesUtil.ReadInt4(buffer, 28);
                var pageLength = BytesUtil.ReadInt4(buffer, 32);

                // Some asserts,
                if (type != 1)
                {
                    throw new IOException(String.Format("Invalid page type '{0}' at position '{1}'", type, position));
                }

                if (pageNumber != buildPageNumber)
                {
                    throw new IOException(String.Format(
                                              "The page number '{0}' does not match the number of the page to build ('{1}')", pageNumber, buildPageNumber));
                }

                // Read the content.
                File.Read(position + 36, pageBuffer, offset + pageOffset, pageLength);
            }
        }
Пример #3
0
        private long GetNextAreaHeader(long offset, long[] header)
        {
            Read(offset, headerBuf, 0, 8);
            long sz = BytesUtil.ReadInt8(headerBuf, 0);

            sz = sz & ActiveFlag;
            long nextOffset = offset + sz;

            if (nextOffset >= DataAreaEndOffset)
            {
                // Return a 0 sized block
                header[0] = 0;
                return(-1);
            }

            Read(nextOffset, headerBuf, 0, 8);
            header[0] = BytesUtil.ReadInt8(headerBuf, 0);
            return(nextOffset);
        }
Пример #4
0
        private long GetPreviousAreaHeader(long offset, long[] header)
        {
            // If the offset is the start of the file area
            if (offset == DataAreaOffset)
            {
                // Return a 0 sized block
                header[0] = 0;
                return(-1);
            }

            Read(offset - 8, headerBuf, 0, 8);
            long sz = BytesUtil.ReadInt8(headerBuf, 0);

            sz = sz & ActiveFlag;
            long previousPointer = offset - sz;

            Read(previousPointer, headerBuf, 0, 8);
            header[0] = BytesUtil.ReadInt8(headerBuf, 0);
            return(previousPointer);
        }
Пример #5
0
            public StoreArea(StoreBase store, long id, long offset, bool readOnly)
            {
                Store      = store;
                Id         = id;
                IsReadOnly = readOnly;

                store.CheckOffset(offset);

                store.Read(offset, buffer, 0, 8);
                long v = BytesUtil.ReadInt8(buffer, 0);

                if ((v & DeletedFlag) != 0)
                {
                    throw new IOException("Store being constructed on deleted area.");
                }

                long maxSize = v - 16;

                StartOffset = offset + 8;
                position    = StartOffset;
                EndOffset   = StartOffset + maxSize;
            }
Пример #6
0
        public bool Open()
        {
            lock (this) {
                OpenStore(IsReadOnly);

                // If it's small, initialize to empty
                if (DataAreaEndOffset < DataAreaOffset)
                {
                    Init();
                }

                byte[] readBuf = new byte[(int)BinAreaOffset];
                Read(0, readBuf, 0, readBuf.Length);

                using (var stream = new MemoryStream(readBuf)) {
                    using (var reader = new BinaryReader(stream)) {
                        int magic = reader.ReadInt32();
                        if (magic != Magic)
                        {
                            throw new IOException("Format invalid: Magic value is not as expected.");
                        }

                        int version = reader.ReadInt32();
                        if (version != 1)
                        {
                            throw new IOException("Format invalid: unrecognized version.");
                        }

                        reader.ReadInt64();                         // ignore
                        byte status = reader.ReadByte();
                        ClosedClean = true;

                        if (status == 1)
                        {
                            // This means the store wasn't closed cleanly.
                            ClosedClean = false;
                        }
                    }
                }

                // Read the bins
                ReadBins();

                // Mark the file as open
                if (!IsReadOnly)
                {
                    Write(16, 1);
                }

                long fileLength = DataAreaEndOffset;
                if (fileLength <= 8)
                {
                    throw new IOException("Format invalid: File size is too small.");
                }

                // Set the wilderness offset.
                if (fileLength == DataAreaOffset)
                {
                    WildernessOffset = -1;
                }
                else
                {
                    Read(fileLength - 8, readBuf, 0, 8);
                    long lastBoundary    = BytesUtil.ReadInt8(readBuf, 0);
                    long lastAreaPointer = fileLength - lastBoundary;

                    if (lastAreaPointer < DataAreaOffset)
                    {
                        throw new IOException("File corrupt: last area offset is before data part of file.");
                    }

                    if (lastAreaPointer > fileLength - 8)
                    {
                        throw new IOException("File corrupt: last_area_pointer at the end of the file.");
                    }

                    Read(lastAreaPointer, readBuf, 0, 8);

                    long lastAreaHeader = BytesUtil.ReadInt8(readBuf, 0);

                    // If this is a freed block, then set this are the wilderness offset.
                    if ((lastAreaHeader & DeletedFlag) != 0)
                    {
                        WildernessOffset = lastAreaPointer;
                    }
                    else
                    {
                        WildernessOffset = -1;
                    }
                }

                IsClosed = false;
                return(ClosedClean);
            }
        }
Пример #7
0
 protected void ReadAreaHeader(long offset, long[] header)
 {
     Read(offset, headerBuf, 0, 16);
     header[0] = BytesUtil.ReadInt8(headerBuf, 0);
     header[1] = BytesUtil.ReadInt8(headerBuf, 8);
 }