예제 #1
0
                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()}");
                    }
                }
예제 #2
0
        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)}.");
            }
        }
예제 #4
0
                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()}");
                        }
                    }
                }
예제 #5
0
        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]}");
            }
        }