//------------------------------------------------- public bool ReadBlock(Guid BlockID_in, ref Hashtable BlockTags_out, ref byte[] Bytes_out) { if ((this._Stream == null)) { return(false); } if ((this._Blocks == null)) { return(false); } int ndx = 0; if (!this.Internal_FindBlock(BlockID_in, ref ndx)) { return(false); } StreamControlBlock BLK = (StreamControlBlock)this._Blocks[ndx]; BlockTags_out = BlockStream.CloneObject <Hashtable>(BLK.Tags); try { this._Stream.Seek(this._Header.DataOffset + BLK.Offset, SeekOrigin.Begin); byte[] inbytes = new byte[BLK.Length]; this._Stream.Read(inbytes, 0, inbytes.Length); if (!this._DecodeBytes(BlockTags_out, inbytes, ref Bytes_out)) { return(false); } } catch (Exception ex) { throw ex; } return(true); }
//========================================================================== //=== Block Info //========================================================================== //------------------------------------------------- public long DataSize() { if ((this._Blocks.Count == 0)) { return(0); } StreamControlBlock BLK = (StreamControlBlock)this._Blocks[this._Blocks.Count - 1]; return(BLK.Offset + BLK.Length); }
//------------------------------------------------- private bool Internal_AllocateBlock(Guid in_BlockID, int in_BlockLength, ref int out_BlockIndex) { //- - - - - - - - - - - - - - - - - - - - - - - - - out_BlockIndex = -1; if ((this._Blocks == null)) { return(false); } StreamControlBlock BLK; StreamControlBlock BLK2; int ndx = 0; // Try to Reclaim an Existing Empty Block for (ndx = 0; ndx <= (this._Blocks.Count - 1); ndx++) { BLK = (StreamControlBlock)this._Blocks[ndx]; if ((BLK.ID.CompareTo(Guid.Empty) == 0)) { if ((BLK.Length == in_BlockLength)) { // Exact Size Match Found, just Reuse this Block BLK.ID = in_BlockID; out_BlockIndex = ndx; this._BlocksDirty = true; return(true); } else if ((BLK.Length > in_BlockLength)) { // Larger Block Found, Split it into a Used Block and a Free Block BLK2 = new StreamControlBlock(Guid.Empty); this._Blocks.Insert(ndx + 1, BLK2); BLK2.Offset = (BLK.Offset + in_BlockLength); BLK2.Length = (BLK.Length - in_BlockLength); BLK.ID = in_BlockID; BLK.Length = in_BlockLength; out_BlockIndex = ndx; this._BlocksDirty = true; return(true); } } } // Append a New Block BLK = new StreamControlBlock(in_BlockID); BLK.Offset = 0; BLK.Length = in_BlockLength; ndx = _Blocks.Add(BLK); if ((ndx > 0)) { BLK2 = (StreamControlBlock)_Blocks[ndx - 1]; BLK.Offset = (BLK2.Offset + BLK2.Length); } out_BlockIndex = ndx; _BlocksDirty = true; return(true); }
//------------------------------------------------- public bool WriteBlock(Guid BlockID_in, Hashtable BlockTags_in, byte[] Bytes_in) { if ((this._Stream == null)) { return(false); } if (!this._Stream.CanWrite) { return(false); } if ((this._Blocks == null)) { return(false); } int ndx = 0; if (this.Internal_FindBlock(BlockID_in, ref ndx)) { // Free Existing Block if (!this.Internal_FreeBlock(ndx)) { return(false); } } // Encode Block byte[] outbytes = { }; if (!this._EncodeBytes(BlockTags_in, Bytes_in, ref outbytes)) { return(false); } // Allocate a New Block if (!this.Internal_AllocateBlock(BlockID_in, outbytes.Length, ref ndx)) { return(false); } StreamControlBlock BLK = (StreamControlBlock)this._Blocks[ndx]; try { this._Stream.Seek(this._Header.DataOffset + BLK.Offset, SeekOrigin.Begin); this._Stream.Write(outbytes, 0, outbytes.Length); BLK.Tags = BlockStream.CloneObject <Hashtable>(BlockTags_in); this._BlocksDirty = true; } catch (Exception ex) { throw ex; } return(true); }