Ejemplo n.º 1
0
        /// <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;
            }
        }
Ejemplo n.º 2
0
        /// <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;
            }
        }