internal void WriteValue(BinaryWriterEx bw, object value) { switch (Type) { case ParamType.aob: bw.WriteBytes((byte[])value); break; case ParamType.b: bw.WriteBoolean((bool)value); break; case ParamType.u8: case ParamType.x8: bw.WriteByte((byte)value); break; case ParamType.s8: bw.WriteSByte((sbyte)value); break; case ParamType.u16: case ParamType.x16: bw.WriteUInt16((ushort)value); break; case ParamType.s16: bw.WriteInt16((short)value); break; case ParamType.u32: case ParamType.x32: bw.WriteUInt32((uint)value); break; case ParamType.s32: bw.WriteInt32((int)value); break; case ParamType.u64: case ParamType.x64: bw.WriteUInt64((ulong)value); break; case ParamType.s64: bw.WriteInt64((long)value); break; case ParamType.f32: bw.WriteSingle((float)value); break; case ParamType.f64: bw.WriteDouble((double)value); break; default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}"); } }
public void WriteDoubleWorks(Double value) { for (int i = 0; i < 2; i++) { bool littleEndian = i != 0; using (MemoryStream ms = new MemoryStream()) { using (BinaryWriterEx writer = new BinaryWriterEx(ms, true, littleEndian)) { writer.WriteDouble(value); Assert.AreEqual(sizeof(Double), ms.Length); ms.Position = 0; CollectionAssert.AreEqual(ms.ToArray(), Binary.GetDoubleBytes(value, littleEndian)); } } } }
public void WriteStandardValueTypeToRaw(BinaryWriterEx bw, object value) { switch (ValueType) { case "aob": bw.WriteBytes((byte[])value); break; case "b": bw.WriteBoolean((bool)value); break; case "u8": case "x8": bw.WriteByte((byte)value); break; case "s8": bw.WriteSByte((sbyte)value); break; case "u16": case "x16": bw.WriteUInt16((ushort)value); break; case "s16": bw.WriteInt16((short)value); break; case "u32": case "x32": bw.WriteUInt32((uint)value); break; case "s32": bw.WriteInt32((int)value); break; case "u64": case "x64": bw.WriteUInt64((ulong)value); break; case "s64": bw.WriteInt64((long)value); break; case "f32": bw.WriteSingle((float)value); break; case "f64": bw.WriteDouble((double)value); break; default: throw new Exception($"Value type '{ValueType}' is not a standard type " + $"and must be handled manually instead of calling {nameof(XmlStructDefField)}." + $"{nameof(WriteStandardValueTypeToRaw)}."); } }
internal void WriteDefaultValue(BinaryWriterEx bw) { if (ValueToAssert != null) { WriteAssertValue(bw); } else if (DefaultValue == null) { switch (Type) { case ParamType.aob: for (int i = 0; i < AobLength; i++) { bw.WriteByte(0); } break; case ParamType.b: case ParamType.u8: case ParamType.x8: bw.WriteByte(0); break; case ParamType.s8: bw.WriteSByte(0); break; case ParamType.u16: case ParamType.x16: bw.WriteUInt16(0); break; case ParamType.s16: bw.WriteInt16(0); break; case ParamType.u32: case ParamType.x32: bw.WriteUInt32(0); break; case ParamType.s32: bw.WriteInt32(0); break; case ParamType.u64: case ParamType.x64: bw.WriteUInt64(0); break; case ParamType.s64: bw.WriteInt64(0); break; case ParamType.f32: bw.WriteSingle(0); break; case ParamType.f64: bw.WriteDouble(0); break; default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}"); } } else { switch (Type) { case ParamType.aob: var assertAob = (byte[])DefaultValue; bw.WriteBytes(assertAob); break; case ParamType.b: case ParamType.u8: case ParamType.x8: bw.WriteByte((byte)DefaultValue); break; case ParamType.s8: bw.WriteSByte((sbyte)DefaultValue); break; case ParamType.u16: case ParamType.x16: bw.WriteUInt16((ushort)DefaultValue); break; case ParamType.s16: bw.WriteInt16((short)DefaultValue); break; case ParamType.u32: case ParamType.x32: bw.WriteUInt32((uint)DefaultValue); break; case ParamType.s32: bw.WriteInt32((int)DefaultValue); break; case ParamType.u64: case ParamType.x64: bw.WriteUInt64((ulong)DefaultValue); break; case ParamType.s64: bw.WriteInt64((long)DefaultValue); break; case ParamType.f32: bw.WriteSingle((float)DefaultValue); break; case ParamType.f64: bw.WriteDouble((double)DefaultValue); break; default: throw new Exception($"Invalid ParamTemplate ParamType: {Type.ToString()}"); } } }
private static void Parse(string plaintext, BinaryWriterEx bw, int current, ref int next) { if (current == 0 && plaintext[current] == '.') { throw new Exception("Cannot start with an abort if previous number is false byte"); } else if (current == 0 && plaintext[current] == '~') { throw new Exception("Cannot start with a continuation byte thing or whatever"); } // Number literal if (plaintext[current] == '-' || char.IsDigit(plaintext[current])) { // Is subtract and not a literal if (plaintext[current] == '-' && (next == plaintext.Length || !char.IsDigit(plaintext[next]))) { bw.WriteByte(BytesByOperator["-"]); } else { while (next < plaintext.Length && char.IsDigit(plaintext[next])) { next++; } if (next + 1 < plaintext.Length && plaintext[next] == '.' && char.IsDigit(plaintext[next + 1])) { next++; while (next < plaintext.Length && char.IsDigit(plaintext[next])) { next++; } } string str = plaintext.Substring(current, next - current); double value = double.Parse(str); if (value == Math.Floor(value)) { if (value >= -64 && value <= 63) { bw.WriteByte((byte)(value + 64)); } else { bw.WriteByte((byte)0x82); bw.WriteInt32((int)value); } } else if (value == (float)value) { bw.WriteByte((byte)0x80); bw.WriteSingle((float)value); } else { bw.WriteByte((byte)0x81); bw.WriteDouble(value); } } } // String literal else if (plaintext[current] == '"') { while (next < plaintext.Length && plaintext[next] != '"') { next++; } if (next == plaintext.Length) { throw new Exception("Unclosed string literal"); } string value = plaintext.Substring(current + 1, next - current - 1); if (value.Contains('\r') || value.Contains('\n')) { throw new Exception("String literals may not contain newlines"); } bw.WriteByte((byte)0xA5); bw.WriteBytes(bw.BigEndian ? Encoding.BigEndianUnicode.GetBytes(value + "\0") : Encoding.Unicode.GetBytes(value + "\0")); next++; } // Add else if (plaintext[current] == '+') { bw.WriteByte(BytesByOperator["+"]); } // Multiply else if (plaintext[current] == '*') { bw.WriteByte(BytesByOperator["*"]); } // Negate else if (plaintext[current] == 'N' || plaintext[current] == 'n') { bw.WriteByte(BytesByOperator["N"]); } else if (plaintext[current] == '/') { // Comment if (next < plaintext.Length && plaintext[next] == '/') { while (next < plaintext.Length && plaintext[next] != '\n') { next++; } next++; } // Divide else { bw.WriteByte(BytesByOperator["/"]); } } else if (plaintext[current] == '<') { // Less than or equal to if (next < plaintext.Length && plaintext[next] == '=') { bw.WriteByte(BytesByOperator["<="]); next++; } // Less than else { bw.WriteByte(BytesByOperator["<"]); } } else if (plaintext[current] == '>') { // Set register if (next < plaintext.Length && plaintext[next] == '[') { if (next + 2 >= plaintext.Length || plaintext[next + 2] != ']') { throw new Exception("Malformed register storage"); } if (!"01234567".Contains(plaintext[next + 1])) { throw new Exception("Register must be from 0-7"); } bw.WriteByte((byte)(0xA7 + byte.Parse(plaintext[next + 1].ToString()))); next += 3; } // Greater than or equal to else if (next < plaintext.Length && plaintext[next] == '=') { bw.WriteByte(BytesByOperator[">="]); next++; } // Greater than else { bw.WriteByte(BytesByOperator[">"]); } } // Equal to else if (plaintext[current] == '=') { if (next == plaintext.Length || plaintext[next] != '=') { throw new Exception("Orphaned = found"); } bw.WriteByte(BytesByOperator["=="]); next++; } // Not equal to else if (plaintext[current] == '!') { if (next == plaintext.Length || plaintext[next] != '=') { throw new Exception("Orphaned ! found"); } bw.WriteByte(BytesByOperator["!="]); next++; } // Logical and else if (plaintext[current] == '&') { if (next == plaintext.Length || plaintext[next] != '&') { throw new Exception("Orphaned & found"); } bw.WriteByte(BytesByOperator["&&"]); next++; } // Logical or else if (plaintext[current] == '|') { if (next == plaintext.Length || plaintext[next] != '|') { throw new Exception("Orphaned | found"); } bw.WriteByte(BytesByOperator["||"]); next++; } // Function call else if (plaintext[current] == '(') { if (next + 1 >= plaintext.Length || plaintext[next + 1] != ')') { throw new Exception("Unclosed function call"); } if (!"0123456".Contains(plaintext[next])) { throw new Exception("Function call must take 0-6 arguments"); } bw.WriteByte((byte)(0x84 + byte.Parse(plaintext[next].ToString()))); next += 2; } // Get register else if (plaintext[current] == '[') { if (next + 2 >= plaintext.Length || plaintext[next + 1] != ']' || plaintext[next + 2] != '>') { throw new Exception("Malformed register retrieval"); } if (!"01234567".Contains(plaintext[next])) { throw new Exception("Register must be from 0-7"); } bw.WriteByte((byte)(0xAF + byte.Parse(plaintext[next].ToString()))); next += 3; } // ~ or . else if (BytesByTerminator.ContainsKey(plaintext[current])) { bw.WriteByte(BytesByTerminator[plaintext[current]]); } // Unknown opcode else if (plaintext[current] == '#') { if (next + 1 >= plaintext.Length) { throw new Exception("Hex literal too short"); } bw.WriteByte(Convert.ToByte(plaintext.Substring(current + 1, 2), 16)); next += 2; } // Whitespace else if (char.IsWhiteSpace(plaintext[current])) { while (next < plaintext.Length && char.IsWhiteSpace(plaintext[next])) { next++; } } // Uh-oh else { throw new Exception($"Unknown character: {plaintext[current]}"); } }