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); }
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); } }
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); }
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); }
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; }
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); } }
protected void ReadAreaHeader(long offset, long[] header) { Read(offset, headerBuf, 0, 16); header[0] = BytesUtil.ReadInt8(headerBuf, 0); header[1] = BytesUtil.ReadInt8(headerBuf, 8); }