/// <summary> /// Create a Dragon tape block object. /// Note that it is possible to create illegal blocks using this method by providing an unsupported block type or an invalid /// checksum. Use the <see cref="Validate">Validate</see> method to verify that the block is actually valid. /// For supported block types, the returned object will be of the appropriate type. /// </summary> /// <param name="blocktype">Block type idenfifier.</param> /// <param name="data">Array containing the block payload data, or <value>null</value> for no payload.</param> /// <param name="offset">Offset into the data array of first byte of block payload data.</param> /// <param name="length">Size of the block payload data.</param> /// <param name="checksum">Block checksum.</param> /// <returns>Dragon tape block object.</returns> public static DragonTapeBlock CreateBlock(DragonTapeBlockType blocktype, byte[] data, int offset, int length, int checksum) { DragonTapeBlock block = null; switch (blocktype) { case DragonTapeBlockType.Header: block = new DragonTapeHeaderBlock(data, offset, length, checksum); break; case DragonTapeBlockType.Data: block = new DragonTapeDataBlock(data, offset, length, checksum); break; case DragonTapeBlockType.EndOfFile: block = new DragonTapeEofBlock(data, offset, length, checksum); break; default: block = new DragonTapeBlock(blocktype); block.SetData(data, offset, length); block.Checksum = checksum; break; } return(block); }
/// <summary> /// Reads the next file header block from tape. /// This function will continue reading tape data until it finds a header block. /// </summary> /// <returns>The header block.</returns> private DragonTapeHeaderBlock ReadHeaderBlock() { while (true) { DragonTapeBlock.Sync(Tape, 1); var block = DragonTapeBlock.ReadBlockSynced(Tape); if (block is DragonTapeHeaderBlock) { return((DragonTapeHeaderBlock)block); } } }
/// <summary> /// Reads a sequence of data blocks. /// Reads data blocks until an EOF block is encoutered. Return the combined payload from the data blocks. Assumes that the tape is located /// just following the header block. /// </summary> /// <param name="isgapped">Set if the blocks are recorded with gaps.</param> /// <returns>Data payload</returns> private byte[] ReadDataBlocks(string filename, bool isgapped) { /* Read blocks and put the block payloads into the blocks list. End when the EOF block is encountered. */ var blocks = new List <byte[]>(); var datalength = 0; var eof = false; while (!eof) { DragonTapeBlock.Sync(Tape, 0); var block = DragonTapeBlock.ReadBlockSynced(Tape); switch (block.BlockType) { case DragonTapeBlockType.Data: blocks.Add(block.Data); datalength += block.Length; break; case DragonTapeBlockType.EndOfFile: eof = true; break; default: throw new InvalidFileException(filename, String.Format("Unexpected block of type {0}", (int)block.BlockType)); } } /* Convert the individual blocks into a single byte array. */ var data = new byte[datalength]; var offset = 0; for (int i = 0; i < blocks.Count; i++) { Array.Copy(blocks[i], 0, data, offset, blocks[i].Length); offset += blocks[i].Length; } return(data); }