public int Read(int dataId, byte[] buffer, int offset, int length) { if (dataId < 0 || dataId >= 16384) { throw new ArgumentException("dataId out of range"); } try { int dataPointer = dataId; int pos = dataPointer * 6; int dataIdPos = pagedAccess.ReadInt32(pos); int dataIdLength = ((int)pagedAccess.ReadInt16(pos + 4)) & 0x0FFFF; if (dataIdPos < 0) { dataPointer = -(dataIdPos + 1); pos = dataPointer * 6; dataIdPos = pagedAccess.ReadInt32(pos); dataIdLength = ((int)pagedAccess.ReadInt16(pos + 4)) & 0x0FFFF; } length = Math.Min(length, dataIdLength); // Read the encoded form into a byte[] array, content.Seek(dataIdPos, SeekOrigin.Begin); return(content.Read(buffer, offset, length)); } catch (IOException e) { // We wrap this IOException around a BlockReadException. This can only // indicate a corrupt compressed block file or access to a dataId that // is out of range of the nodes stored in this file. throw new BlockReadException("IOError reading data from block file", e); } }
public void Write(int dataId, byte[] buffer, int offset, int count) { // Arg checks if (count < 0 || count >= 65536) { throw new ArgumentException("count < 0 || count > 65535"); } if (count + offset > buffer.Length) { throw new ArgumentException(); } if (offset < 0) { throw new ArgumentException(); } if (dataId < 0 || dataId >= 16384) { throw new ArgumentException("dataId out of range"); } byte[] tmpArea = new byte[6]; // Seek to the position of this data id in the table, int pos = dataId * 6; int dataIdPos = pagedAccess.ReadInt32(pos); int dataIdLength = (pagedAccess.ReadInt16(pos + 4)) & 0x0FFFF; // These values should be 0, if not we've already written data here, if (dataIdPos != 0 || dataIdLength != 0) { throw new ApplicationException("data_id previously written"); } // Write the content to the end of the file, content.Seek(length, SeekOrigin.Begin); content.Write(buffer, offset, count); pagedAccess.InvalidateSection(length, count); // Write the table entry, ByteBuffer.WriteInt4(length, tmpArea, 0); ByteBuffer.WriteInt2((short)count, tmpArea, 4); content.Seek(pos, SeekOrigin.Begin); content.Write(tmpArea, 0, 6); pagedAccess.InvalidateSection(pos, 6); // Set the new content length length = length + count; }