Exemplo n.º 1
0
        /// <summary>
        /// Reads this instance.
        /// </summary>
        /// <returns></returns>
        public unsafe byte[] Read(ulong size)
        {
            // We prepare variables.
            byte[] data = new byte[size];
            ulong  i    = 0;

            // Begin loop.
            for (ulong addr = blocks[0]; addr != 0;)
            {
                uint  seq;
                ulong next;

                // Read header first.
                Block headerBlock = service.Read(BlockType.BigObjectData, addr);
                fixed(byte *p = headerBlock.Data)
                {
                    BlockLinkHeader *header = (BlockLinkHeader *)p;

                    next = header->NextBlock;
                    seq  = header->Sequential;
                }

                // First block special.
                for (uint j = (uint)sizeof(BlockLinkHeader); j < headerBlock.Data.Length && i < size; i++, j++)
                {
                    data[i] = headerBlock.Data[j];
                }

                // All sequential blocks.
                for (uint k = 1; k < seq; k++)
                {
                    Block dataBlock = service.Read(BlockType.BigObjectData, addr + k);

                    for (uint z = 0; z < dataBlock.Data.Length && i < size; i++, z++)
                    {
                        data[i] = dataBlock.Data[z];
                    }
                }

                // Next iteration.
                addr = next;
            }

            return(data);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Deallocates this instance.
        /// </summary>
        public unsafe void Deallocate()
        {
            if (!CanWrite)
            {
                throw new ArgumentException("Cannot deallocate.");
            }

            IService writeService = service as IService;

            // We deallocate link.
            ulong addr = this.blocks[0];

            for (; addr != 0;)
            {
                // We read the link.
                Block block = writeService.Read(BlockType.BigObjectData, addr);
                uint  lenght;
                ulong next;

                // We extract header.
                fixed(byte *p = block.Data)
                {
                    BlockLinkHeader *header = (BlockLinkHeader *)p;

                    next   = header->NextBlock;
                    lenght = header->Sequential;
                }

                // We free all.
                for (uint i = 0; i < lenght; i++)
                {
                    writeService.DeAllocate(addr + i);
                }

                // We proceed to next.
                addr = next;
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the specified data.
        /// </summary>
        /// <param name="data">The data.</param>
        public unsafe void Write(byte[] data)
        {
            if (!CanWrite)
            {
                throw new ArgumentException("Cannot write.");
            }

            IService writeService = service as IService;

            // We first organize blocks into logican units.
            ulong                   prev           = 0;
            LogicalBlockUnit        processingLink = new LogicalBlockUnit(0);
            List <LogicalBlockUnit> links          = new List <LogicalBlockUnit>();

            foreach (ulong block in blocks)
            {
                if (block == prev + 1)
                {
                    processingLink.Count++;
                }
                else
                {
                    links.Add(processingLink);
                    processingLink = new LogicalBlockUnit(block);
                }
                prev = block;
            }
            links.Add(processingLink);

            // We have organised units, we can now actually write. We begin
            // at 1 because the first link is always an empty link.
            ulong dataOffset = 0;

            for (uint i = 1; i < (uint)links.Count; i++)
            {
                // We extract logical unit and next.
                LogicalBlockUnit link = links[(int)i];
                ulong            next = i == links.Count - 1 ? 0 : links[(int)(i + 1)].First;

                // We write to it, header first.
                Block block = new Block(service.BlockSize);
                fixed(byte *p = block.Data)
                {
                    BlockLinkHeader *header = (BlockLinkHeader *)p;

                    header->Sequential = link.Count;
                    header->NextBlock  = next;
                }

                // TODO: use ulong(s) in future for copying, not bytes.

                // We copy to header block (make sure we do not acces out of it).
                ulong maxWrite = service.BlockSize - (ulong)sizeof(BlockLinkHeader);
                if (maxWrite > (ulong)data.LongLength - dataOffset)
                {
                    maxWrite = (ulong)data.LongLength - dataOffset;
                }
                for (uint k = 0; k < maxWrite; k++)
                {
                    block.Data[k + (uint)sizeof(BlockLinkHeader)] = data[dataOffset++];
                }

                writeService.Write(BlockType.BigObjectData, link.First, block);

                // And the rest of it.
                for (uint j = 1; j < link.Count; j++)
                {
                    maxWrite = service.BlockSize;
                    if (maxWrite > (ulong)data.LongLength - dataOffset)
                    {
                        maxWrite = (ulong)data.LongLength - dataOffset;
                    }
                    for (uint l = 0; l < maxWrite; l++)
                    {
                        block.Data[l] = data[dataOffset++];
                    }

                    writeService.Write(BlockType.BigObjectData, link.First + j, block);
                }
            }
        }