public ByamlWriter(Stream stream, bool supportPaths, ByteOrder byteOrder, ushort version) { _version = version; _supportPaths = supportPaths; _byteOrder = byteOrder; _writer = new BinaryDataWriter(stream, ByamlFile.GetEncoding(byteOrder), true) { ByteOrder = _byteOrder }; }
protected Dictionary <uint, dynamic> _alreadyReadNodes = null; //Offset in the file, reference to node // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ public ByamlReader(Stream stream, bool supportPaths, ByteOrder byteOrder, ushort version, bool fastLoad = false) { _version = version; _supportPaths = supportPaths; _byteOrder = byteOrder; _fastLoad = fastLoad; if (fastLoad) { _alreadyReadNodes = new Dictionary <uint, dynamic>(); } _reader = new BinaryDataReader(stream, ByamlFile.GetEncoding(byteOrder), true) { ByteOrder = byteOrder }; }
protected bool TryStartLoading() { // Load the header, specifying magic bytes ("BY"), version and main node offsets. if (_reader.ReadUInt16() != BYAML_MAGIC) { //switch endian and try again _byteOrder = _byteOrder == ByteOrder.LittleEndian ? ByteOrder.BigEndian : ByteOrder.LittleEndian; _reader = new BinaryDataReader(_reader.BaseStream, ByamlFile.GetEncoding(_byteOrder), true) { ByteOrder = _byteOrder }; _reader.Position = 0; if (_reader.ReadUInt16() != BYAML_MAGIC) { throw new Exception("Header mismatch"); } } _version = _reader.ReadUInt16(); uint nameArrayOffset = _reader.ReadUInt32(); uint stringArrayOffset = _reader.ReadUInt32(); if (_reader.Length == 16) { _supportPaths = false; } else { using (_reader.TemporarySeek()) { // Paths are supported if the third offset is a path array (or unknown) and the fourth a root. ByamlNodeType thirdNodeType = PeekNodeType(_reader); _reader.Seek(sizeof(uint)); ByamlNodeType fourthNodeType = PeekNodeType(_reader); _supportPaths = (thirdNodeType == ByamlNodeType.Unknown || thirdNodeType == ByamlNodeType.PathArray) && (fourthNodeType == ByamlNodeType.Array || fourthNodeType == ByamlNodeType.Dictionary); } } uint pathArrayOffset = 0; if (_supportPaths) { pathArrayOffset = _reader.ReadUInt32(); } uint rootNodeOffset = _reader.ReadUInt32(); if (rootNodeOffset == 0) //empty byml { return(false); } // Read the name array, holding strings referenced by index for the names of other nodes. if (nameArrayOffset != 0) { _reader.Seek(nameArrayOffset, SeekOrigin.Begin); _nameArray = ReadCollectionNode(_reader.ReadUInt32()); } // Read the optional string array, holding strings referenced by index in string nodes. if (stringArrayOffset != 0) { _reader.Seek(stringArrayOffset, SeekOrigin.Begin); _stringArray = ReadCollectionNode(_reader.ReadUInt32()); } // Read the optional path array, holding paths referenced by index in path nodes. if (_supportPaths && pathArrayOffset != 0) { // The third offset is the root node, so just read that and we're done. _reader.Seek(pathArrayOffset, SeekOrigin.Begin); _pathArray = ReadCollectionNode(_reader.ReadUInt32()); } // Read the root node. _reader.Seek(rootNodeOffset, SeekOrigin.Begin); return(true); dynamic ReadCollectionNode(uint lengthAndType) { int length = (int)Get3LsbBytes(lengthAndType); ByamlNodeType nodeType = (ByamlNodeType)Get1MsbByte(lengthAndType); switch (nodeType) { case ByamlNodeType.Array: return(ReadArrayNode(_reader, length)); case ByamlNodeType.Dictionary: return(ReadDictionaryNode(_reader, length)); case ByamlNodeType.StringArray: return(ReadStringArrayNode(_reader, length)); case ByamlNodeType.PathArray: return(ReadPathArrayNode(_reader, length)); default: return(null); //should never happen } } }