/// <summary> Saves this NBT file to a stream. Nothing is written to stream if RootTag is null. </summary> /// <param name="stream"> Stream to write data to. May not be null. </param> /// <param name="compression"> Compression mode to use for saving. May not be AutoDetect. </param> /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is null. </exception> /// <exception cref="ArgumentException"> If AutoDetect was given as the compression mode. </exception> /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for compression. </exception> /// <exception cref="InvalidDataException"> If given stream does not support writing. </exception> /// <exception cref="NbtFormatException"> If one of the NbtCompound tags contained unnamed tags; /// or if an NbtList tag had Unknown list type and no elements. </exception> public void SaveToStream( [NotNull] Stream stream, NbtCompression compression ) { if( stream == null ) throw new ArgumentNullException( "stream" ); switch( compression ) { case NbtCompression.AutoDetect: throw new ArgumentException( "AutoDetect is not a valid NbtCompression value for saving." ); case NbtCompression.ZLib: case NbtCompression.GZip: case NbtCompression.None: break; default: throw new ArgumentOutOfRangeException( "compression" ); } // do not write anything for empty tags if( RootTag == null ) return; switch( compression ) { case NbtCompression.ZLib: stream.WriteByte( 0x78 ); stream.WriteByte( 0x01 ); int checksum; using( var compressStream = new ZLibStream( stream, CompressionMode.Compress, true ) ) { BufferedStream bufferedStream = new BufferedStream( compressStream, BufferSize ); RootTag.WriteTag( new NbtWriter( bufferedStream ), true ); bufferedStream.Flush(); checksum = compressStream.Checksum; } byte[] checksumBytes = BitConverter.GetBytes(checksum); if( BitConverter.IsLittleEndian ) { // Adler32 checksum is big-endian Array.Reverse( checksumBytes ); } stream.Write( checksumBytes, 0, checksumBytes.Length ); break; case NbtCompression.GZip: using( var compressStream = new GZipStream( stream, CompressionMode.Compress, true ) ) { // use a buffered stream to avoid gzipping in small increments (which has a lot of overhead) BufferedStream bufferedStream = new BufferedStream( compressStream, BufferSize ); RootTag.WriteTag( new NbtWriter( bufferedStream ), true ); bufferedStream.Flush(); } break; case NbtCompression.None: RootTag.WriteTag( new NbtWriter( stream ), true ); break; } }
/// <summary> Saves this NBT file to a stream. Nothing is written to stream if RootTag is null. </summary> /// <param name="stream"> Stream to write data to. May not be null. </param> /// <param name="compression"> Compression mode to use for saving. May not be AutoDetect. </param> /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is null. </exception> /// <exception cref="ArgumentException"> If AutoDetect was given as the compression mode. </exception> /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for compression. </exception> /// <exception cref="InvalidDataException"> If given stream does not support writing. </exception> /// <exception cref="NbtFormatException"> If one of the NbtCompound tags contained unnamed tags; /// or if an NbtList tag had Unknown list type and no elements. </exception> public void SaveToStream([NotNull] Stream stream, NbtCompression compression) { if (stream == null) { throw new ArgumentNullException("stream"); } switch (compression) { case NbtCompression.AutoDetect: throw new ArgumentException("AutoDetect is not a valid NbtCompression value for saving."); case NbtCompression.ZLib: case NbtCompression.GZip: case NbtCompression.None: break; default: throw new ArgumentOutOfRangeException("compression"); } // do not write anything for empty tags if (RootTag == null) { return; } switch (compression) { case NbtCompression.ZLib: stream.WriteByte(0x78); stream.WriteByte(0x01); int checksum; using (var compressStream = new ZLibStream(stream, CompressionMode.Compress, true)) { BufferedStream bufferedStream = new BufferedStream(compressStream, BufferSize); RootTag.WriteTag(new NbtWriter(bufferedStream), true); bufferedStream.Flush(); checksum = compressStream.Checksum; } byte[] checksumBytes = BitConverter.GetBytes(checksum); if (BitConverter.IsLittleEndian) { // Adler32 checksum is big-endian Array.Reverse(checksumBytes); } stream.Write(checksumBytes, 0, checksumBytes.Length); break; case NbtCompression.GZip: using (var compressStream = new GZipStream(stream, CompressionMode.Compress, true)) { // use a buffered stream to avoid gzipping in small increments (which has a lot of overhead) BufferedStream bufferedStream = new BufferedStream(compressStream, BufferSize); RootTag.WriteTag(new NbtWriter(bufferedStream), true); bufferedStream.Flush(); } break; case NbtCompression.None: RootTag.WriteTag(new NbtWriter(stream), true); break; } }