示例#1
0
 public MessageStruct(Memory <byte> data, int offset, MemberParser parser, int count, MessageStruct parent)
     : this(data, offset, parser)
 {
     Parent     = parent;
     fieldCount = count;
     Parse();
 }
示例#2
0
        public static int PopulateFields(MessageStruct messageStruct)
        {
            int           position = 0;
            int           offset   = messageStruct.Offset;
            Memory <byte> buffer   = messageStruct.Data;
            MemberParser  parser   = messageStruct.Parser;

            return(PopulateFields(messageStruct, parser, buffer, offset, ref position));
        }
示例#3
0
        public static int PopulateFields(MessageStruct messageStruct, MemberParser parser, Memory <byte> buffer, int offset, ref int position)
        {
            while (parser != null)
            {
                if (parser.PreAlignment != 0)
                {
                    int align = (position + offset) % parser.PreAlignment;
                    //Debug.WriteLine($"PreAlign {parser.MemberName} offset {offset} position {position} align {align} alignCheck {parser.PreAlignment}");
                    if (align > 0)
                    {
                        position += parser.PreAlignment - align;
                    }
                }

                bool condition = CheckCondition(messageStruct, parser);
                if (condition)
                {
                    int    fieldOffset = position;
                    object value       = GetFieldValue(messageStruct, parser, buffer, ref position);
                    if (value != null)
                    {
                        Field field = new Field();
                        field.Name   = parser.MemberName;
                        field.Offset = fieldOffset;
                        field.Type   = parser.MemberType;
                        field.Value  = value;
                        field.Length = position - fieldOffset;

                        messageStruct.Fields.Add(field);
                        messageStruct.FieldIndex.Add(field.Name, messageStruct.Fields.Count - 1);
                    }
                }

                if (parser.PostAlignment != 0)
                {
                    int align = (offset + position) % parser.PostAlignment;
                    //Debug.WriteLine($"PostAlign {parser.MemberName} offset {offset} position {position} ({offset + position}) align {align} alignCheck {parser.PostAlignment}");
                    if (align > 0)
                    {
                        position += parser.PostAlignment - align;
                    }
                }

                parser = parser.Next;
            }

            return(position);
        }
示例#4
0
        private static object FindFieldValue(MessageStruct messageStruct, string fieldName)
        {
            object        result = null;
            MessageStruct cs     = messageStruct;

            while (cs != null)
            {
                result = cs[fieldName];
                if (result != null)
                {
                    return(result);
                }
                cs = cs.Parent;
            }
            return(result);
        }
示例#5
0
        private static bool CheckCondition(MessageStruct messageStruct, MemberParser parser)
        {
            bool   result = true;
            object tmp    = null;

            if (parser.Condition != MemberParserCondition.None)
            {
                tmp = FindFieldValue(messageStruct, parser.ConditionField);
                if (tmp != null)
                {
                    long condCheck = Convert.ToInt64(tmp);
                    condCheck ^= parser.ConditionXor;
                    condCheck &= parser.ConditionAnd;
                    switch (parser.Condition)
                    {
                    case MemberParserCondition.EQ:
                        result = (condCheck == parser.ConditionResult);
                        break;

                    case MemberParserCondition.NE:
                        result = (condCheck != parser.ConditionResult);
                        break;

                    case MemberParserCondition.GE:
                        result = (condCheck >= parser.ConditionResult);
                        break;

                    case MemberParserCondition.GT:
                        result = (condCheck > parser.ConditionResult);
                        break;

                    case MemberParserCondition.LE:
                        result = (condCheck <= parser.ConditionResult);
                        break;

                    case MemberParserCondition.LT:
                        result = (condCheck < parser.ConditionResult);
                        break;
                    }
                }
            }
            return(result);
        }
示例#6
0
        private void ParseVector()
        {
            int position = 0;

            for (int i = 0; i < fieldCount; i++)
            {
                Memory <byte>       buffer = Data.Slice(position);
                MessageParser.Field field  = new MessageParser.Field();
                field.Offset = position;
                field.Type   = MemberParserType.Struct;

                MessageStruct ms = new MessageStruct(buffer, Offset + position, Parser, this);
                field.Value  = ms;
                field.Length = ms.Length;
                position    += ms.Length;

                Fields.Add(field);
            }
            Length = position;
        }
示例#7
0
        private static object GetFieldValue(MessageStruct current, MemberParser parser, Memory <byte> buffer, ref int position)
        {
            switch (parser.MemberType)
            {
            case MemberParserType.BYTE:
                return(buffer.Read <byte>(ref position));

            case MemberParserType.WORD:
                return(buffer.Read <short>(ref position));

            case MemberParserType.PackedWORD:
            {
                short tmp = buffer.Read <byte>(ref position);
                if ((tmp & 0x80) != 0)
                {
                    tmp = (short)(((tmp & 0x7f) << 8) | buffer.Read <byte>(ref position));
                }
                return(tmp);
            }

            case MemberParserType.DWORD:
                return(buffer.Read <int>(ref position));

            case MemberParserType.PackedDWORD:
            {
                int tmp = buffer.Read <short>(ref position);
                if ((tmp & 0x8000) != 0)
                {
                    tmp = ((tmp & 0x7fff) << 16) + buffer.Read <short>(ref position);
                }
                return(tmp);
            }

            case MemberParserType.QWORD:
                return(buffer.Read <long>(ref position));

            case MemberParserType.@float:
                return(buffer.Read <float>(ref position));

            case MemberParserType.@double:
                return(buffer.Read <double>(ref position));

            case MemberParserType.String:
            {
                //Debug.WriteLine($"Extracting String value {parser.MemberName}");
                // strings need to be a multiple of 4 including length
                int lenlen = 2;
                int length = buffer.Read <short>(ref position);
                if (length == -1)
                {
                    lenlen += 4;
                    length  = buffer.Read <int>(ref position);
                }

                Memory <byte> tmp = buffer.Slice(position, length);
                position += length;

                int align = (position + current.Offset) % 4;
                if (align > 0)
                {
                    position += (4 - align);
                }

                return(System.Text.Encoding.ASCII.GetString(tmp.Span));
            }

            case MemberParserType.WString:
            {
                int lenlen = 1;
                int length = buffer.Read <byte>(ref position);
                if ((length & 0x80) != 0)
                {
                    lenlen++;
                    length = ((length & 0x7f) << 8) | buffer.Read <byte>(ref position);
                }

                Memory <byte> tmp = buffer.Slice(position, length * 2);

                position += length * 2;

                return(System.Text.Encoding.Unicode.GetString(tmp.Span));
            }

            case MemberParserType.Struct:
            {
                Memory <byte> tmp = buffer.Slice(position);
                MessageStruct ms  = new MessageStruct(tmp, current.Offset + position, parser.Child, current);
                position += ms.Length;
                return(ms);
            }

            case MemberParserType.Vector:
            {
                object tmp    = FindFieldValue(current, parser.LengthField);
                long   length = 0;
                if (tmp != null)
                {
                    length = Convert.ToInt64(tmp);
                }
                long mask = parser.LengthMask;
                length &= mask;
                if (mask != 0)
                {
                    while ((mask & 0x1) == 0)
                    {
                        length >>= 1;
                        mask   >>= 1;
                    }
                }

                Memory <byte> tmpData = buffer.Slice(position);
                MessageStruct ms      = new MessageStruct(tmpData, current.Offset + position, parser.Child, (int)(length + parser.LengthDelta), current);
                position += ms.Length;
                return(ms);
            }

            case MemberParserType.Case:
                PopulateFields(current, parser.Child, buffer, current.Offset, ref position);
                break;

            default:
                System.Diagnostics.Debug.WriteLine($"Invalid MemberParserType {parser.MemberType}");
                break;
            }

            return(null);
        }