Ejemplo n.º 1
0
        static NbtVersion DetectVersion([NotNull] Stream stream)
        {
            NbtVersion version = NbtVersion.Legacy;

            if (!stream.CanSeek)
            {
                throw new NotSupportedException("Cannot detect file version on a stream that's not seekable.");
            }
            int firstByte = stream.ReadByte();

            switch (firstByte)
            {
            case -1:
                throw new EndOfStreamException();

            case 0x07:
                version = NbtVersion.V7;
                break;

            case 0x08:
                version = NbtVersion.V8;
                break;

            default:
                version = NbtVersion.Legacy;
                break;
            }

            stream.Seek(-1, SeekOrigin.Current);
            return(version);
        }
Ejemplo n.º 2
0
 /// <summary> Loads NBT data from a stream. Existing <c>RootTag</c> will be replaced </summary>
 /// <param name="stream"> Stream from which data will be loaded. If compression is set to AutoDetect, this stream must support seeking. </param>
 /// <param name="compression"> Compression method to use for loading/saving this file. </param>
 /// <param name="version"> Version of the file. </param>
 /// <returns> Number of bytes read from the stream. </returns>
 /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is <c>null</c>. </exception>
 /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for <paramref name="compression"/>. </exception>
 /// <exception cref="NotSupportedException"> If <paramref name="compression"/> or <paramref name="version"/> is set to AutoDetect, but the stream is not seekable. </exception>
 /// <exception cref="EndOfStreamException"> If file ended earlier than expected. </exception>
 /// <exception cref="InvalidDataException"> If file compression could not be detected, decompressing failed, or given stream does not support reading. </exception>
 /// <exception cref="NbtFormatException"> If an error occurred while parsing data in NBT format. </exception>
 public long LoadFromStream([NotNull] Stream stream, NbtCompression compression, NbtVersion version)
 {
     return(LoadFromStream(stream, compression, version, null));
 }
Ejemplo n.º 3
0
        /// <summary> Loads NBT data from a stream. Existing <c>RootTag</c> will be replaced </summary>
        /// <param name="stream"> Stream from which data will be loaded. If compression or file version is set to AutoDetect, this stream must support seeking. </param>
        /// <param name="compression"> Compression method to use for loading/saving this file. </param>
        /// <param name="version"> Version of the file. </param>
        /// <param name="selector"> Optional callback to select which tags to load into memory. Root may not be skipped.
        /// No reference is stored to this callback after loading (don't worry about implicitly captured closures). May be <c>null</c>. </param>
        /// <returns> Number of bytes read from the stream. </returns>
        /// <exception cref="ArgumentNullException"> <paramref name="stream"/> is <c>null</c>. </exception>
        /// <exception cref="ArgumentOutOfRangeException"> If an unrecognized/unsupported value was given for <paramref name="compression"/>. </exception>
        /// <exception cref="NotSupportedException"> If <paramref name="compression"/> or <paramref name="fileVersion"/> is set to AutoDetect, but the stream is not seekable. </exception>
        /// <exception cref="EndOfStreamException"> If file ended earlier than expected. </exception>
        /// <exception cref="InvalidDataException"> If file compression could not be detected, decompressing failed, or given stream does not support reading. </exception>
        /// <exception cref="NbtFormatException"> If an error occurred while parsing data in NBT format. </exception>
        public long LoadFromStream([NotNull] Stream stream, NbtCompression compression, NbtVersion version, [CanBeNull] TagSelector selector)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            FileName = null;

            if (version == NbtVersion.AutoDetect)
            {
                FileVersion = DetectVersion(stream);
            }
            else
            {
                FileVersion = version;
            }

            if (FileVersion == NbtVersion.Legacy)
            {
                // detect compression, based on the first byte
                if (compression == NbtCompression.AutoDetect)
                {
                    FileCompression = DetectCompression(stream);
                }
                else
                {
                    FileCompression = compression;
                }
            }
            else
            {
                FileCompression = NbtCompression.None;
                BigEndian       = false;
            }

            // prepare to count bytes read
            long startOffset = 0;

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

            switch (FileCompression)
            {
            case NbtCompression.GZip:
                using (var decStream = new GZipStream(stream, CompressionMode.Decompress, true)) {
                    if (bufferSize > 0)
                    {
                        LoadFromStreamInternal(new BufferedStream(decStream, bufferSize), selector);
                    }
                    else
                    {
                        LoadFromStreamInternal(decStream, selector);
                    }
                }
                break;

            case NbtCompression.None:
                LoadFromStreamInternal(stream, selector);
                break;

            case NbtCompression.ZLib:
                if (stream.ReadByte() != 0x78)
                {
                    throw new InvalidDataException(WrongZLibHeaderMessage);
                }
                stream.ReadByte();
                using (var decStream = new DeflateStream(stream, CompressionMode.Decompress, true)) {
                    if (bufferSize > 0)
                    {
                        LoadFromStreamInternal(new BufferedStream(decStream, bufferSize), selector);
                    }
                    else
                    {
                        LoadFromStreamInternal(decStream, selector);
                    }
                }
                break;

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

            // report bytes read
            if (stream.CanSeek)
            {
                return(stream.Position - startOffset);
            }
            else
            {
                return(((ByteCountingStream)stream).BytesRead);
            }
        }