/// <summary> /// Writes blob and it's header to the underlaying stream. /// </summary> /// <param name="blobType">The type of the blob.</param> /// <param name="blobContent">The pbf serialized content of the blob.</param> private void WriteBlob(string blobType, byte[] blobContent) { Blob blob = new Blob(); if (this.Settings.Compression == CompressionMode.None) { blob.Raw = blobContent; } else if (this.Settings.Compression == CompressionMode.ZlibDeflate) { MemoryStream zlibStream = new MemoryStream(); //ZLIB header zlibStream.WriteByte(120); zlibStream.WriteByte(156); using (System.IO.Compression.DeflateStream deflateSteram = new System.IO.Compression.DeflateStream(zlibStream, System.IO.Compression.CompressionMode.Compress, true)) { deflateSteram.Write(blobContent, 0, blobContent.Length); } blob.RawSize = (int)blobContent.Length; blob.ZlibData = new byte[zlibStream.Length]; Array.Copy(zlibStream.GetBuffer(), blob.ZlibData, zlibStream.Length); } MemoryStream blobStream = new MemoryStream(); Serializer.Serialize<Blob>(blobStream, blob); BlobHeader header = new BlobHeader(); header.Type = blobType; header.DataSize = (int)blobStream.Length; Serializer.SerializeWithLengthPrefix(_output, header, PrefixStyle.Fixed32BigEndian); blobStream.WriteTo(_output); }
/// <summary> /// Read blob and deserializes its content. /// </summary> /// <param name="header">Header of the blob.</param> /// <returns>Deserialized content of the read blob or null if blob contains unknown data.</returns> private object ReadBlob(BlobHeader header) { byte[] buffer = new byte[header.DataSize]; _input.Read(buffer, 0, header.DataSize); Blob blob = Serializer.Deserialize<Blob>(new MemoryStream(buffer)); Stream blobContentStream; if (blob.Raw != null) { blobContentStream = new MemoryStream(blob.Raw); } else if (blob.ZlibData != null) { MemoryStream deflateStreamData = new MemoryStream(blob.ZlibData); //skip ZLIB header deflateStreamData.Seek(2, SeekOrigin.Begin); blobContentStream = new System.IO.Compression.DeflateStream(deflateStreamData, System.IO.Compression.CompressionMode.Decompress); } else { throw new NotSupportedException(); } if (header.Type.Equals("OSMData", StringComparison.InvariantCultureIgnoreCase)) { if ((blob.RawSize.HasValue && blob.RawSize > MaxDataBlockSize) || (blob.RawSize.HasValue == false && blobContentStream.Length > MaxDataBlockSize)) { throw new InvalidDataException("Invalid OSMData block"); } return Serializer.Deserialize<PrimitiveBlock>(blobContentStream); } else if (header.Type.Equals("OSMHeader", StringComparison.InvariantCultureIgnoreCase)) { if ((blob.RawSize.HasValue && blob.RawSize > MaxHeaderBlockSize) || (blob.RawSize.HasValue == false && blobContentStream.Length > MaxHeaderBlockSize)) { throw new InvalidDataException("Invalid OSMHeader block"); } return Serializer.Deserialize<OsmHeader>(blobContentStream); } else { return null; } }