public MessageStruct(Memory <byte> data, int offset, MemberParser parser, int count, MessageStruct parent) : this(data, offset, parser) { Parent = parent; fieldCount = count; Parse(); }
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)); }
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); }
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); }
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); }
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; }
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); }