예제 #1
0
        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);
            }
        }
예제 #2
0
        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;
        }