/// <summary> /// Given a codec, write a type description to a stream, from which this codec can be /// reconstructed later. This returns the number of bytes written, so that, if this /// were a seekable stream, the positions would differ by this amount before and after /// a call to this method. /// </summary> public int WriteCodec(Stream definitionStream, IValueCodec codec) { // *** Codec type description *** // string: codec loadname // LEB128 int: Byte size of the parameterization // byte[]: The indicated parameterization using (BinaryWriter writer = OpenBinaryWriter(definitionStream)) { string loadName = codec.LoadName; writer.Write(loadName); int bytes = _encoding.GetByteCount(loadName); bytes = checked (bytes + Utils.Leb128IntLength((uint)bytes)); MemoryStream mem = _memPool.Get(); int output = codec.WriteParameterization(mem); Contracts.Check(mem.Length == output, "codec description length did not match stream length"); Contracts.Check(mem.Length <= int.MaxValue); // Is this even possible in the current implementation of MemoryStream? writer.WriteLeb128Int((ulong)mem.Length); bytes = checked (bytes + Utils.Leb128IntLength((uint)mem.Length) + output); mem.Position = 0; mem.CopyTo(definitionStream); _memPool.Return(ref mem); return(bytes); } }
private void CompressionWorker(BlockingCollection <Block> toCompress, BlockingCollection <Block> toWrite, int columns, OrderedWaiter waiter, ExceptionMarshaller exMarshaller) { Contracts.AssertValue(exMarshaller); try { _host.AssertValue(toCompress); _host.AssertValue(toWrite); _host.Assert(columns > 0); _host.Assert(_deterministicBlockOrder == (waiter != null)); foreach (Block block in toCompress.GetConsumingEnumerable(exMarshaller.Token)) { MemoryStream compressed = _memPool.Get(); int uncompLength; using (Stream stream = _compression.CompressStream(compressed)) { MemoryStream uncompressed = block.BlockData; uncompLength = (int)uncompressed.Length; ArraySegment <byte> buffer; bool tmp = uncompressed.TryGetBuffer(out buffer); Contracts.Assert(tmp); stream.Write(buffer.Array, buffer.Offset, buffer.Count); _memPool.Return(ref uncompressed); } if (_deterministicBlockOrder) { waiter.Wait((long)columns * block.BlockIndex + block.ColumnIndex, exMarshaller.Token); } toWrite.Add(new Block(compressed, block.ColumnIndex, block.BlockIndex, uncompLength), exMarshaller.Token); if (_deterministicBlockOrder) { waiter.Increment(); } } } catch (Exception ex) { exMarshaller.Set("compressing", ex); } }