public static DatToken Load(DatBinaryReader reader) { var tokenByte = reader.ReadByte(); if (Enum.IsDefined(typeof(DatTokenType), tokenByte) == false) { throw new Exception($"Unable to parse DatToken with id = {tokenByte}"); } var token = new DatToken { TokenType = (DatTokenType)tokenByte }; switch (token.TokenType) { case DatTokenType.Call: case DatTokenType.CallExternal: case DatTokenType.PushInt: case DatTokenType.PushVar: case DatTokenType.PushInstance: case DatTokenType.Jump: case DatTokenType.JumpIf: case DatTokenType.SetInstance: token.IntParam = reader.ReadInt32(); break; case DatTokenType.PushArrayVar: token.IntParam = reader.ReadInt32(); token.ByteParam = reader.ReadByte(); break; } return(token); }
private void Load(Stream stream) { var reader = new DatBinaryReader(stream); Version = reader.ReadChar(); Symbols = LoadSymbols(reader); Tokens = LoadTokens(reader); }
private IEnumerable <DatToken> LoadTokens(DatBinaryReader reader) { int stackLength = reader.ReadInt32(); List <DatToken> result = new List <DatToken>(); while (stackLength > 0) { var token = DatToken.Load(reader); result.Add(token); stackLength -= token.Size; } return(result); }
private IEnumerable <DatSymbol> LoadSymbols(DatBinaryReader reader) { var symbolsCount = reader.ReadInt32(); var symbolsOrder = new int[symbolsCount]; for (int i = 0; i < symbolsCount; i++) { symbolsOrder[i] = reader.ReadInt32(); } var symbols = new DatSymbol[symbolsCount]; for (int i = 0; i < symbolsCount; i++) { symbols[i] = DatSymbol.Load(reader); } return(symbols); }
private static object[] GetContentIfExists(DatBinaryReader reader, DatSymbol symbol) { // TODO : Verify and refactor this method. object[] result = null; if (symbol.Flags.HasFlag(DatSymbolFlag.Classvar) == false) { if (symbol.Type == DatSymbolType.Func || symbol.Type == DatSymbolType.Class || symbol.Type == DatSymbolType.Prototype) { result = new object[1]; } else { result = new object[symbol.ArrayLength]; } if ((result.Length == 0) && (symbol.Type == DatSymbolType.Instance)) { result = new object[1]; } for (int i = 0; i < result.Length; i++) { switch (symbol.Type) { case DatSymbolType.String: result[i] = reader.ReadString(); break; case DatSymbolType.Float: result[i] = reader.ReadSingle(); break; default: result[i] = reader.ReadInt32(); break; } } } return(result); }
private List <DatSymbol> LoadDatSymbols(DatBinaryReader reader) { _nextSymbolIndex = 0; var symbolsCount = reader.ReadInt32(); var symbolsOrder = new int[symbolsCount]; for (int i = 0; i < symbolsCount; i++) { symbolsOrder[i] = reader.ReadInt32(); } List <DatSymbol> symbols = new List <DatSymbol>(); for (int i = 0; i < symbolsCount; i++) { DatSymbol symbol = new DatSymbol(reader) { Index = _nextSymbolIndex }; symbols.Add(symbol); _nextSymbolIndex++; } return(symbols); }
/// <summary> /// Creates DatSymbol from binary (DAT formatted) stream /// </summary> public DatSymbol(DatBinaryReader reader) { var hasName = Convert.ToBoolean(reader.ReadUInt32()); if (hasName) // TODO is it even possible for symbol to not have name? { Name = reader.ReadString(); } OffClsRet = reader.ReadUInt32(); uint bitField = reader.ReadUInt32(); Count = bitField & 0xFFF; BuiltinType = (SymbolType)((bitField & 0xF000) >> 12); Flags = (SymbolFlag)((bitField & 0x3F0000) >> 16); FileIndex = reader.ReadUInt32(); Line = reader.ReadUInt32(); LinesCount = reader.ReadUInt32(); Column = reader.ReadUInt32(); CharsCount = reader.ReadUInt32(); Content = new object[] {}; if (!Flags.HasFlag(SymbolFlag.ClassVar)) { switch (BuiltinType) { case SymbolType.Class: case SymbolType.Func: case SymbolType.Instance: case SymbolType.Prototype: Content = new object[] { reader.ReadInt32() }; break; default: Content = new object[Count]; for (int i = 0; i < Count; ++i) { switch (BuiltinType) { case SymbolType.String: Content[i] = reader.ReadString(); break; case SymbolType.Float: Content[i] = reader.ReadSingle(); break; default: Content[i] = reader.ReadInt32(); break; } } break; } } ParentIndex = reader.ReadInt32(); }
/// <summary> /// Loads DatSymbol from binary DAT formatted stream /// </summary> public static DatSymbol Load(DatBinaryReader reader) { var symbol = new DatSymbol(); // Read Name var hasName = Convert.ToBoolean(reader.ReadUInt32()); if (hasName) { symbol.Name = reader.ReadString(); } // Read ReturnType / ClassSize / ClassVarOffset / ArrayLength / Type / Flags var valueField = reader.ReadInt32(); var bitField = reader.ReadUInt32(); symbol.ArrayLength = bitField & 0xFFF; symbol.Type = (DatSymbolType)((bitField & 0xF000) >> 12); symbol.Flags = (DatSymbolFlag)((bitField & 0x3F0000) >> 16); if (symbol.Type == DatSymbolType.Func && symbol.Flags.HasFlag(DatSymbolFlag.Return)) { symbol.ReturnType = (DatSymbolType)valueField; } if (symbol.Type == DatSymbolType.Class) { symbol.ClassSize = valueField; } if (symbol.Flags.HasFlag(DatSymbolFlag.Classvar)) { symbol.ClassVarOffset = valueField; } symbol.Location = new DatSymbolLocation { FileNumber = reader.ReadInt32(), Line = reader.ReadInt32(), LinesCount = reader.ReadInt32(), Position = reader.ReadInt32(), PositionsCount = reader.ReadInt32(), }; switch (symbol.Type) { case DatSymbolType.Class: symbol.ClassOffset = reader.ReadInt32(); break; case DatSymbolType.Func: case DatSymbolType.Instance: case DatSymbolType.Prototype: symbol.FirstTokenAddress = reader.ReadInt32(); break; default: symbol.Content = GetContentIfExists(reader, symbol); break; } symbol.ParentIndex = reader.ReadInt32(); return(symbol); }