BinaryWriter wrapper that writes NBT primitives to a stream, while taking care of endianness and string encoding, and counting bytes written.
Exemplo n.º 1
0
 /// <summary> Initializes a new instance of the NbtWriter class. </summary>
 /// <param name="stream"> Stream to write to. </param>
 /// <param name="rootTagName"> Name to give to the root tag (written immediately). </param>
 /// <param name="bigEndian"> Whether NBT data should be in Big-Endian encoding. </param>
 /// <exception cref="ArgumentNullException"> <paramref name="stream"/> or <paramref name="rootTagName"/> is <c>null</c>. </exception>
 /// <exception cref="ArgumentException"> <paramref name="stream"/> is not writable. </exception>
 public NbtWriter([NotNull] Stream stream, [NotNull] String rootTagName, bool bigEndian)
 {
     if (rootTagName == null) throw new ArgumentNullException("rootTagName");
     writer = new NbtBinaryWriter(stream, bigEndian);
     writer.Write((byte)NbtTagType.Compound);
     writer.Write(rootTagName);
     parentType = NbtTagType.Compound;
 }
Exemplo n.º 2
0
 internal override void WriteTag(NbtBinaryWriter writeStream)
 {
     writeStream.Write(NbtTagType.String);
     if (Name == null)
     {
         throw new NbtFormatException("Name is null");
     }
     writeStream.Write(Name);
     writeStream.Write(Value);
 }
Exemplo n.º 3
0
 internal override void WriteTag(NbtBinaryWriter writeStream)
 {
     writeStream.Write(NbtTagType.List);
     if (Name == null)
     {
         throw new NbtFormatException("Name is null");
     }
     writeStream.Write(Name);
     WriteData(writeStream);
 }
Exemplo n.º 4
0
 /// <summary> Initializes a new instance of the NbtWriter class. </summary>
 /// <param name="stream"> Stream to write to. </param>
 /// <param name="rootTagName"> Name to give to the root tag (written immediately). </param>
 /// <param name="bigEndian"> Whether NBT data should be in Big-Endian encoding. </param>
 /// <exception cref="ArgumentNullException"> <paramref name="stream"/> or <paramref name="rootTagName"/> is <c>null</c>. </exception>
 /// <exception cref="ArgumentException"> <paramref name="stream"/> is not writable. </exception>
 public NbtWriter(Stream stream, String rootTagName, bool bigEndian)
 {
     if (rootTagName == null)
     {
         throw new ArgumentNullException("rootTagName");
     }
     writer = new NbtBinaryWriter(stream, bigEndian);
     writer.Write((byte)NbtTagType.Compound);
     writer.Write(rootTagName);
     parentType = NbtTagType.Compound;
 }
Exemplo n.º 5
0
 public override long ReadInt64()
 {
     if (BitConverter.IsLittleEndian == bigEndian)
     {
         return(NbtBinaryWriter.Swap(base.ReadInt64()));
     }
     else
     {
         return(base.ReadInt64());
     }
 }
Exemplo n.º 6
0
 internal override void WriteTag(NbtBinaryWriter writeStream, bool writeName)
 {
     writeStream.Write(NbtTagType.Double);
     if (writeName)
     {
         if (Name == null)
         {
             throw new NbtFormatException("Name is null");
         }
         writeStream.Write(Name);
     }
     writeStream.Write(Value);
 }
Exemplo n.º 7
0
 internal override void WriteData(NbtBinaryWriter writeStream)
 {
     if (ListType == NbtTagType.Unknown)
     {
         throw new NbtFormatException("NbtList had no elements and an Unknown ListType");
     }
     writeStream.Write(ListType);
     writeStream.Write(tags.Count);
     foreach (NbtTag tag in tags)
     {
         tag.WriteData(writeStream);
     }
 }
Exemplo n.º 8
0
 internal override void WriteTag(NbtBinaryWriter writeStream, bool writeName)
 {
     writeStream.Write(NbtTagType.IntArray);
     if (writeName)
     {
         if (Name == null)
         {
             throw new NbtFormatException("Name is null");
         }
         writeStream.Write(Name);
     }
     WriteData(writeStream);
 }
Exemplo n.º 9
0
 internal override void WriteData(NbtBinaryWriter writeStream)
 {
     writeStream.Write(Value.Length);
     writeStream.Write(Value, 0, Value.Length);
 }
Exemplo n.º 10
0
        /// <summary> Saves this NBT file to a stream. Nothing is written to stream if RootTag is <c>null</c>. </summary>
        /// <param name="stream"> Stream to write data to. May not be <c>null</c>. </param>
        /// <param name="compression"> Compression mode to use for saving. May not be AutoDetect. </param>
        /// <returns> Number of bytes written to the stream. </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is <c>null</c>. </exception>
        /// <exception cref="ArgumentException"> If AutoDetect was given as the <paramref name="compression"/> mode. </exception>
        /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for <paramref name="compression"/>. </exception>
        /// <exception cref="InvalidDataException"> If given stream does not support writing. </exception>
        /// <exception cref="NbtFormatException"> If RootTag is null;
        /// or if RootTag is unnamed;
        /// or if one of the NbtCompound tags contained unnamed tags;
        /// or if an NbtList tag had Unknown list type and no elements. </exception>
        public long 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");
            }

            if (rootTag.Name == null) {
                throw new NbtFormatException(
                    "Cannot save NbtFile: Root tag is not named. Its name may be an empty string, but not null.");
            }

            long startOffset = 0;
            if (stream.CanSeek) {
                startOffset = stream.Position;
            } else {
                stream = new ByteCountingStream(stream);
            }

            switch (compression) {
                case NbtCompression.ZLib:
                    stream.WriteByte(0x78);
                    stream.WriteByte(0x01);
                    int checksum;
                    using (var compressStream = new ZLibStream(stream, CompressionMode.Compress, true)) {
                        var bufferedStream = new BufferedStream(compressStream, WriteBufferSize);
                        RootTag.WriteTag(new NbtBinaryWriter(bufferedStream, BigEndian));
                        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)
                        var bufferedStream = new BufferedStream(compressStream, WriteBufferSize);
                        RootTag.WriteTag(new NbtBinaryWriter(bufferedStream, BigEndian));
                        bufferedStream.Flush();
                    }
                    break;

                case NbtCompression.None: {
                    var writer = new NbtBinaryWriter(stream, BigEndian);
                    RootTag.WriteTag(writer);
                }
                    break;

                default:
                    throw new ArgumentOutOfRangeException("compression");
            }

            if (stream.CanSeek) {
                return stream.Position - startOffset;
            } else {
                return ((ByteCountingStream)stream).BytesWritten;
            }
        }
Exemplo n.º 11
0
        /// <summary> Saves this NBT file to a stream. Nothing is written to stream if RootTag is <c>null</c>. </summary>
        /// <param name="stream"> Stream to write data to. May not be <c>null</c>. </param>
        /// <param name="compression"> Compression mode to use for saving. May not be AutoDetect. </param>
        /// <returns> Number of bytes written to the stream. </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is <c>null</c>. </exception>
        /// <exception cref="ArgumentException"> If AutoDetect was given as the <paramref name="compression"/> mode. </exception>
        /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for <paramref name="compression"/>. </exception>
        /// <exception cref="InvalidDataException"> If given stream does not support writing. </exception>
        /// <exception cref="NbtFormatException"> If RootTag is null;
        /// or if RootTag is unnamed;
        /// or if one of the NbtCompound tags contained unnamed tags;
        /// or if an NbtList tag had Unknown list type and no elements. </exception>
        public long 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");
            }

            if (rootTag.Name == null)
            {
                // This may trigger if root tag has been renamed
                throw new NbtFormatException(
                          "Cannot save NbtFile: Root tag is not named. Its name may be an empty string, but not null.");
            }

            long startOffset = 0;

            if (stream.CanSeek)
            {
                startOffset = stream.Position;
            }
            else
            {
                stream = new ByteCountingStream(stream);
            }

            switch (compression)
            {
            case NbtCompression.ZLib:
                stream.WriteByte(0x78);
                stream.WriteByte(0x01);
                int checksum;
                using (var compressStream = new ZLibStream(stream, CompressionMode.Compress, true)) {
                    var bufferedStream = new BufferedStream(compressStream, WriteBufferSize);
                    RootTag.WriteTag(new NbtBinaryWriter(bufferedStream, BigEndian)
                    {
                        UseVarInt = UseVarInt
                    });
                    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)
                    var bufferedStream = new BufferedStream(compressStream, WriteBufferSize);
                    RootTag.WriteTag(new NbtBinaryWriter(bufferedStream, BigEndian)
                    {
                        UseVarInt = UseVarInt
                    });
                    bufferedStream.Flush();
                }
                break;

            case NbtCompression.None:
                var writer = new NbtBinaryWriter(stream, BigEndian)
                {
                    UseVarInt = UseVarInt
                };
                RootTag.WriteTag(writer);
                break;

            default:
                throw new ArgumentOutOfRangeException("compression");
            }

            if (stream.CanSeek)
            {
                return(stream.Position - startOffset);
            }
            else
            {
                return(((ByteCountingStream)stream).BytesWritten);
            }
        }
Exemplo n.º 12
0
 internal override void WriteTag(NbtBinaryWriter writeStream)
 {
     writeStream.Write(NbtTagType.Long);
     if (Name == null)
         throw new NbtFormatException("Name is null");
     writeStream.Write(Name);
     writeStream.Write(Value);
 }
Exemplo n.º 13
0
 internal override void WriteTag( NbtBinaryWriter writeStream, bool writeName )
 {
     writeStream.Write( NbtTagType.Double );
     if( writeName ) {
         if( Name == null )
             throw new NbtFormatException( "Name is null" );
         writeStream.Write( Name );
     }
     writeStream.Write( Value );
 }
Exemplo n.º 14
0
 // WriteData does not write the tag's ID byte or the name
 internal abstract void WriteData(NbtBinaryWriter writeReader);
Exemplo n.º 15
0
 internal override void WriteData( NbtBinaryWriter writeStream )
 {
     writeStream.Write( Value.Length );
     writeStream.Write( Value, 0, Value.Length );
 }
Exemplo n.º 16
0
 // WriteData does not write the tag's ID byte or the name
 internal abstract void WriteData([NotNull] NbtBinaryWriter writeStream);
Exemplo n.º 17
0
 internal override void WriteData(NbtBinaryWriter writeStream)
 {
     writeStream.Write(Value);
 }
Exemplo n.º 18
0
 internal abstract void WriteTag([NotNull] NbtBinaryWriter writeReader, bool writeName);
Exemplo n.º 19
0
 internal override void WriteData(NbtBinaryWriter writeStream)
 {
     writeStream.Write(Value);
 }
Exemplo n.º 20
0
 internal override void WriteData(NbtBinaryWriter writeStream)
 {
     writeStream.Write(Value.Length);
     for (int i = 0; i < Value.Length; i++) {
         writeStream.Write(Value[i]);
     }
 }
Exemplo n.º 21
0
 // WriteData does not write the tag's ID byte or the name
 internal abstract void WriteData([NotNull] NbtBinaryWriter writeReader);
Exemplo n.º 22
0
 internal override void WriteTag(NbtBinaryWriter writeStream)
 {
     writeStream.Write(NbtTagType.IntArray);
     if (Name == null)
         throw new NbtFormatException("Name is null");
     writeStream.Write(Name);
     WriteData(writeStream);
 }