/** * <summary>Get a list of Tags from a stream. This is meant for internal use only.</summary> * <param name="stream">The stream to read from. (Position is expected to be at 0).</param> * <returns>The list of tags.</returns> */ public static List <T> GetListData <T>(Stream stream) where T : ITag { BigBinaryReader binReader = new BigBinaryReader(stream); TagBuilder currentBuilder = new TagBuilder(); binReader.BaseStream.Seek(0, SeekOrigin.Begin); List <T> output = new List <T>(); while (binReader.BaseStream.Position != binReader.BaseStream.Length) { currentBuilder.setDataType(binReader.ReadByte()); currentBuilder.setDataSize(binReader.ReadInt32()); //TODO see if this is correct. currentBuilder.setStartingIndex(binReader.BaseStream.Position); currentBuilder.setNameSize(binReader.ReadInt16()); byte[] nameBytes = binReader.ReadBytes(currentBuilder.getNameSize()); String tagName = Encoding.UTF8.GetString(nameBytes); currentBuilder.setName(tagName); byte[] value = binReader.ReadBytes((int)(currentBuilder.getStartingIndex() - stream.Position) + (int)currentBuilder.getDataSize()); currentBuilder.setValueBytes(value); output.Add((T)currentBuilder.proccess()); } return(output); }
/** * <summary> * This object goes through the data and scouts out the information from the given key. * This method is recursive, which is why the parameter offset exists. * </summary> * * <param name="data">The input array of bytes</param> * <param name="key">The key</param> * <param name="counter">The Scout object</param> * <param name="startIndex">The starting index for the count.</param> * <returns>The key scout.</returns> */ public static KeyScout ScoutObjectData(byte[] data, string key, KeyScout counter, int startIndex) { MemoryStream stream = new MemoryStream(data); BigBinaryReader binReader = new BigBinaryReader(stream); TagBuilder currentBuilder = new TagBuilder(); binReader.BaseStream.Seek(0, SeekOrigin.Begin); string name = key.Split('.')[0]; string otherKey = getKey(key.Split('.')); while (binReader.BaseStream.Position != binReader.BaseStream.Length) { KeyScoutChild child = new KeyScoutChild(); currentBuilder.setDataType(binReader.ReadByte()); child.SetStartingIndex((int)binReader.BaseStream.Position + startIndex); currentBuilder.setDataSize(binReader.ReadInt32()); currentBuilder.setStartingIndex(binReader.BaseStream.Position); currentBuilder.setNameSize(binReader.ReadInt16()); if (currentBuilder.getNameSize() != Encoding.UTF8.GetByteCount(name)) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } byte[] nameBytes = binReader.ReadBytes(currentBuilder.getNameSize()); string tagName = Encoding.UTF8.GetString(nameBytes); currentBuilder.setName(tagName); if (tagName != name) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } int binPos = (int)binReader.BaseStream.Position; byte[] value = binReader.ReadBytes((int)(currentBuilder.getStartingIndex() - stream.Position) + (int)currentBuilder.getDataSize()); currentBuilder.setValueBytes(value); binReader.Close(); if (otherKey != null) { validateNotCompressed(currentBuilder); child.SetSize(currentBuilder.getDataSize()); child.SetName(currentBuilder.getName()); counter.AddChild(child); return(ScoutObjectData(currentBuilder.getValueBytes(), otherKey, counter, binPos + startIndex)); } child.SetSize(currentBuilder.getDataSize()); child.SetName(currentBuilder.getName()); counter.SetEnd(child); return(counter); } return(null); }
/** * <summary>Checks to see if a key exists within a stream.</summary> * <param name="stream">The stream to check in.</param> * <param name="key">The key to find.</param> * * <returns>If the key exists.</returns> */ public static bool FindSubObjectData(Stream stream, string key) { BigBinaryReader binReader = new BigBinaryReader(stream); TagBuilder currentBuilder = new TagBuilder(); string name = key.Split('.')[0]; string otherKey = getKey(key.Split('.')); while (binReader.BaseStream.Position != binReader.BaseStream.Length) { currentBuilder.setDataType(binReader.ReadByte()); currentBuilder.setDataSize(binReader.ReadInt32()); //TODO see if this is correct. currentBuilder.setStartingIndex(binReader.BaseStream.Position); currentBuilder.setNameSize(binReader.ReadInt16()); if (currentBuilder.getNameSize() != Encoding.UTF8.GetByteCount(name)) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } byte[] nameBytes = binReader.ReadBytes(currentBuilder.getNameSize()); string tagName = Encoding.UTF8.GetString(nameBytes); currentBuilder.setName(tagName); if (tagName != name) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } if (otherKey != null) { validateNotCompressed(currentBuilder); return(FindSubObjectData(stream, otherKey)); } byte[] value = binReader.ReadBytes((int)(currentBuilder.getStartingIndex() - stream.Position) + (int)currentBuilder.getDataSize()); currentBuilder.setValueBytes(value); return(true); } return(false); }
/** * <inheritdoc/> */ public Tag <List <ITag> > CreateFromData(byte[] value) { int length = value.Length; ICompressor compressor; byte[] bitData; using (BigBinaryReader bbr = new BigBinaryReader(new MemoryStream(value))) { short compressorLength = bbr.ReadInt16(); length -= 2 + compressorLength; byte[] compressorBytes = new byte[compressorLength]; bbr.Read(compressorBytes, 0, compressorLength); string compressionName = Encoding.UTF8.GetString(compressorBytes); compressor = ODSUtil.GetCompressor(compressionName); if (compressor == null) { throw new ODSException("Cannot find compressor: " + compressionName); } bitData = bbr.ReadBytes((int)(bbr.BaseStream.Length - bbr.BaseStream.Position)); } this.compressor = compressor; byte[] decompressedData; using (MemoryStream memStream = new MemoryStream()) { using (Stream compressedStream = compressor.GetDecompressStream(new MemoryStream(bitData))) { compressedStream.CopyTo(memStream); } decompressedData = memStream.ToArray(); } this.value = InternalUtils.GetListData <ITag>(decompressedData); return(this); }
public static ITag getSubData(Stream stream, string name) { BigBinaryReader binReader = new BigBinaryReader(stream); TagBuilder currentBuilder = new TagBuilder(); while (binReader.BaseStream.Position != binReader.BaseStream.Length) { currentBuilder.setDataType(binReader.ReadByte()); currentBuilder.setDataSize(binReader.ReadInt32()); //TODO see if this is correct. currentBuilder.setStartingIndex(binReader.BaseStream.Position); currentBuilder.setNameSize(binReader.ReadInt16()); if (currentBuilder.getNameSize() != Encoding.UTF8.GetByteCount(name)) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } byte[] nameBytes = binReader.ReadBytes(currentBuilder.getNameSize()); String tagName = Encoding.UTF8.GetString(nameBytes); currentBuilder.setName(tagName); if (tagName != name) { binReader.BaseStream.Seek((currentBuilder.getStartingIndex() - stream.Position) + currentBuilder.getDataSize(), SeekOrigin.Current); currentBuilder = new TagBuilder(); continue; } byte[] value = binReader.ReadBytes((int)(currentBuilder.getStartingIndex() - stream.Position) + (int)currentBuilder.getDataSize()); currentBuilder.setValueBytes(value); return(currentBuilder.proccess()); } return(null); }