internal BinaryMap(int length, BinaryTokens tokens) { BlockMap = new List<BinaryBlockType>(); // (int)(length / 1000f) TextMap = new List<string>(); BlockMap.Add(BinaryBlockType.Start); TextMap.Add(""); this.tokens = tokens; }
private void ContainerEnd(BinaryTokens token) { writer.Write((byte)token); var current = writer.BaseStream.Position; var offset = containerPositionStack.Pop(); writer.BaseStream.Seek(offset, SeekOrigin.Begin); writer.Write((uint)(current - offset - 4)); // byte size (minus 4 since we want to skip the actual byte size value) writer.BaseStream.Seek(current, SeekOrigin.Begin); }
private void ContainerBegin(BinaryTokens token) { writer.Write((byte)token); containerPositionStack.Push(writer.BaseStream.Position); writer.Write((uint)0); // byte size }
public static BinaryMap Decode(string gameToken, byte[] bytes) { tokens = new BinaryTokens("eu4bin.csv"); map = new BinaryMap(bytes.Length, tokens); raw = bytes; map.AddString(ANSI.GetString(raw, 0, 6), false); int i = 6; SpecialCode specialcode = SpecialCode.None; SpecialCode type = SpecialCode.None; string handler = ""; bool quoted = false; bool? list = null; bool oneLineInheritance = false; BinaryToken code = null; BinaryToken inheritedCode = null; while (i < raw.Length - 1) { // 1. Check for a special code first specialcode = GetSpecialCode(i); if (specialcode != 0) { if ((int)specialcode < 4) // brace or equals sign { ReadSpecial(ref i); // Right-brace sign clears current inheritance. if (specialcode == SpecialCode.RightBrace) { inheritedCode = null; type = SpecialCode.None; handler = ""; quoted = false; list = null; } continue; } else { // If there is attempt to redefine inherited properties, ignore it and read regardless. if (inheritedCode == null) { type = specialcode; } // Now interpret the special code. i += 2; switch (type) { case SpecialCode.String: ReadString(ref i, quoted); continue; case SpecialCode.Integer: ReadInteger(ref i); continue; case SpecialCode.Float: ReadFloat(ref i); continue; case SpecialCode.Float5: ReadFloat5(ref i); continue; case SpecialCode.Boolean: ReadBoolean(ref i); continue; case SpecialCode.Date: ReadDate(ref i, false); continue; // never quoted in practice default: break; } continue; } } // 2. No special code encountered, we are looking for a token now code = tokens.TryGetCode(raw[i], raw[i + 1]); // from little-endian code // If the token does not match anything, try to continue to read data in the same format as previously. if (code == null) { // Maybe it is an unknown token SpecialCode sc1 = GetSpecialCode(i - 2); SpecialCode sc2 = GetSpecialCode(i + 2); if (sc1 == SpecialCode.Equals || sc2 == SpecialCode.Equals) { map.AddToken("UNKNOWN_" + GetHexString(i)); i += 2; if (TryAddSpecials(ref i)) continue; TryReadTypeDefinition(ref i, ref type); } switch (type) { case SpecialCode.String: ReadString(ref i, quoted); continue; case SpecialCode.Integer: ReadInteger(ref i); continue; case SpecialCode.Float: ReadFloat(ref i); continue; case SpecialCode.Float5: ReadFloat5(ref i); continue; case SpecialCode.Boolean: ReadBoolean(ref i); continue; case SpecialCode.Date: ReadDate(ref i, quoted); continue; default: break; } i += 2; continue; } // 3. We have found the token // Tackle inheritance: if it is on for a given token, enforce properties until the next right-brace sign. if (code.InheritType) { inheritedCode = code; type = inheritedCode.DataType; handler = inheritedCode.Text; quoted = inheritedCode.Quoted; list = inheritedCode.List; oneLineInheritance = true; } // If no inheritance, read properties from the current token. else if (inheritedCode == null) { type = code.DataType; handler = code.Text; quoted = code.Quoted; list = code.List; } if (type == SpecialCode.Variable) // variable { // Get parent token string[] parents = map.GetParents(); InterpretCode(gameToken, handler, ref map, ref i, ref type, ref quoted, parents); continue; } else { map.AddToken(code.Text); i += 2; if (TryAddSpecials(ref i)) { oneLineInheritance = false; continue; } if (oneLineInheritance) inheritedCode = null; TryReadTypeDefinition(ref i, ref type); switch (type) { case SpecialCode.String: ReadString(ref i, quoted); continue; case SpecialCode.Integer: ReadInteger(ref i); continue; case SpecialCode.Float: ReadFloat(ref i); continue; case SpecialCode.Float5: ReadFloat5(ref i); continue; case SpecialCode.Boolean: ReadBoolean(ref i); continue; case SpecialCode.Date: ReadDate(ref i, quoted); continue; default: continue; // map.AddAttribToken(i); break; } } } map.Finish(); return map; }