private IEnumerable <CtfField> ParseStructFields(string metadata, int begin, int end) { Debug.Assert(metadata[begin] == '{'); foreach (string statement in EnumerateStatements(metadata, begin + 1, end)) { int index; string name = null; CtfMetadataType type = ParseOneType(statement, out index); name = statement.Substring(index).Trim(); Debug.Assert(type != null); Debug.Assert(name != null); int openBracket = name.IndexOf('[') + 1; int closeBracket = openBracket > 0 ? name.IndexOf(']', openBracket + 1) : -1; if (closeBracket != -1) { string arrayVal = name.Substring(openBracket, closeBracket - openBracket).Trim(); name = name.Substring(0, openBracket - 1).Trim(); type = new CtfArray(type, arrayVal); } yield return(new CtfField(type, name)); } }
public CtfStream(CtfPropertyBag properties) { ID = properties.GetInt("id"); _header = properties.GetType("event.header"); _context = properties.GetType("packet.context"); _eventContext = properties.GetType("event.context"); }
public CtfMetadataDeclaration(CtfDeclarationTypes declaration, CtfMetadataType type, string name, string text) { Definition = declaration; Type = type; Name = name; RawText = text; Debug.Assert(name == null || name == name.Trim()); }
private object ReadType(CtfStruct strct, object[] result, CtfMetadataType type) { Align(type.Align); switch (type.CtfType) { case CtfTypes.Array: CtfArray array = (CtfArray)type; int len = array.GetLength(strct, result); object[] ret = new object[len]; for (int j = 0; j < len; j++) { ret[j] = ReadType(null, null, array.Type); } return(ret); case CtfTypes.Enum: return(ReadType(strct, result, ((CtfEnum)type).Type)); case CtfTypes.Float: CtfFloat flt = (CtfFloat)type; ReadBits(flt.Exp + flt.Mant); return(0f); // TODO: Not implemented. case CtfTypes.Integer: CtfInteger ctfInt = (CtfInteger)type; return(ReadInteger(ctfInt)); case CtfTypes.String: bool ascii = ((CtfString)type).IsAscii; return(ReadString(ascii)); case CtfTypes.Struct: return(ReadStruct((CtfStruct)type)); case CtfTypes.Variant: CtfVariant var = (CtfVariant)type; int i = strct.GetFieldIndex(var.Switch); CtfField field = strct.Fields[i]; CtfEnum enumType = (CtfEnum)field.Type; int value = strct.GetFieldValue <int>(result, i); string name = enumType.GetName(value); field = var.Union.Where(f => f.Name == name).Single(); return(ReadType(strct, result, field.Type)); default: throw new InvalidOperationException(); } }
public static T ReadInt <T>(CtfMetadataType type, byte[] buffer, int bitOffset) where T : IConvertible { if (type.CtfType == CtfTypes.Enum) { type = ((CtfEnum)type).Type; } CtfInteger intType = (CtfInteger)type; object result = intType.Read(buffer, bitOffset); object converted = ((IConvertible)result).ToType(typeof(T), null); return((T)converted); }
internal void ResolveReferences(Dictionary <string, CtfMetadataType> typealias) { _header = _header.ResolveReference(typealias); _header.ResolveReference(typealias); _context = _context.ResolveReference(typealias); _context.ResolveReference(typealias); foreach (CtfEvent evt in _events) { evt.ResolveReferences(typealias); } }
public void ReadTypeIntoBuffer(CtfStruct context, CtfMetadataType type) { Align(type.Align); type.BitOffset = _bitOffset; if (type.CtfType == CtfTypes.Enum) { type = ((CtfEnum)type).Type; type.BitOffset = _bitOffset; } else if (type.CtfType != CtfTypes.Struct && type.CtfType != CtfTypes.Variant) { int size = type.GetSize(); if (size != CtfEvent.SizeIndeterminate) { ReadBits(size); return; } } switch (type.CtfType) { case CtfTypes.Array: CtfArray array = (CtfArray)type; var indexType = context.GetField(array.Index).Type; int len = CtfInteger.ReadInt <int>(indexType, _buffer, indexType.BitOffset); int elemSize = array.Type.GetSize(); if (elemSize == CtfEvent.SizeIndeterminate) { for (int j = 0; j < len; j++) { ReadTypeIntoBuffer(null, array.Type); } } else { for (int j = 0; j < len; j++) { Align(type.Align); ReadBits(elemSize); } } break; case CtfTypes.Float: CtfFloat flt = (CtfFloat)type; ReadBits(flt.Exp + flt.Mant); break; case CtfTypes.Integer: CtfInteger ctfInt = (CtfInteger)type; ReadBits(ctfInt.Size); break; case CtfTypes.String: Debug.Assert((_bitOffset % 8) == 0); int startOffset = _bitOffset >> 3; int offset = startOffset; ReadBits(8); bool ascii = ((CtfString)type).IsAscii; if (ascii) { while (_buffer[offset++] != 0) { ReadBits(8); } } else { byte b = _buffer[offset]; while (b != 0) { switch (b) { default: break; case 0xc: case 0xd: ReadBits(8); break; case 0xe: ReadBits(16); break; case 0xf: ReadBits(24); break; } offset = ReadBits(8) >> 3; b = _buffer[offset]; } } int bufferLen = (_bitOffset >> 3) - startOffset; Encoding encoding = ascii ? Encoding.ASCII : Encoding.UTF8; byte[] newArr = Encoding.Convert(encoding, Encoding.Unicode, _buffer, startOffset, bufferLen); ((CtfString)type).Length = bufferLen; if (_buffer.Length < _bufferLength + newArr.Length) { byte[] buffer = ReallocateBuffer(_bufferLength + newArr.Length); System.Buffer.BlockCopy(buffer, 0, _buffer, 0, _bufferLength); } System.Buffer.BlockCopy(newArr, 0, _buffer, startOffset, newArr.Length); _bufferLength = startOffset + newArr.Length; _bitOffset = _bufferLength * 8; break; case CtfTypes.Struct: ReadStruct((CtfStruct)type); break; case CtfTypes.Variant: CtfVariant var = (CtfVariant)type; CtfField field = context.GetField(var.Switch); CtfEnum enumType = (CtfEnum)field.Type; int value = CtfInteger.ReadInt <int>(enumType, _buffer, enumType.BitOffset); string name = enumType.GetName(value); field = var.GetVariant(name); ReadTypeIntoBuffer(null, field.Type); break; default: throw new InvalidOperationException(); } }
private CtfMetadataDeclaration ParseOneDeclaration(string metadata, int index, out int end) { end = -1; int open = metadata.IndexOf('{', index); if (open == -1) { return(null); } int start = metadata.Substring(0, open).LastIndexOf('\n') + 1; if (start == 0) { return(null); } CtfDeclarationTypes directive = CtfDeclarationTypes.Unknown; string[] directiveElements = metadata.Substring(start, open - start).Trim().Split(' '); string directiveString = directiveElements[0]; string name = null; switch (directiveString) { case "trace": directive = CtfDeclarationTypes.Trace; break; case "typealias": directive = CtfDeclarationTypes.TypeAlias; int closeBrace = FindCloseBrace(metadata, open) + 1; CtfPropertyBag bag = GetPropertyBag(metadata, open, closeBrace); CtfMetadataType t = null; switch (directiveElements[1]) { case "integer": t = new CtfInteger(bag); break; default: throw new IOException(); } int colonEquals = metadata.IndexOf(":=", closeBrace) + 2; int semi = colonEquals; while (metadata[++semi] != ';') { ; } name = metadata.Substring(colonEquals, semi - colonEquals).Trim(); end = semi + 1; return(new CtfMetadataDeclaration(CtfDeclarationTypes.TypeAlias, t, name, directiveElements[1])); case "env": directive = CtfDeclarationTypes.Environment; break; case "clock": directive = CtfDeclarationTypes.Clock; break; case "struct": directive = CtfDeclarationTypes.Struct; name = directiveElements[1]; break; case "stream": directive = CtfDeclarationTypes.Stream; break; case "event": directive = CtfDeclarationTypes.Event; break; default: break; } int close = FindCloseBrace(metadata, open); int curr = close; while (metadata[curr++] != ';') { ; } int nameStart = metadata.IndexOf(":=", close); if (name == null && nameStart != -1 && nameStart < curr) { nameStart += 2; // move past := name = metadata.Substring(nameStart, curr - nameStart - 1).Trim(); } Debug.Assert(metadata[open] == '{'); Debug.Assert(metadata[close] == '}'); end = curr; if (directive == CtfDeclarationTypes.Struct) { CtfPropertyBag bag = null; Match match = s_align.Match(metadata, close, end - close); if (match.Success) { bag = new CtfPropertyBag(); bag.AddValue("align", match.Groups[1].ToString()); } CtfField[] fields = ParseStructFields(metadata, open, close).ToArray(); return(new CtfMetadataDeclaration(directive, bag, fields, name, metadata.Substring(index, curr - index))); } else { CtfPropertyBag properties = GetPropertyBag(metadata, open, close); return(new CtfMetadataDeclaration(directive, properties, name, metadata.Substring(index, curr - index))); } }
private CtfMetadataType ParseOneType(string statement, out int index) { CtfMetadataType type = null; Match match; if ((match = s_integer.Match(statement)).Success) { Group group = match.Groups[1]; CtfPropertyBag bag = GetPropertyBag(group.ToString()); type = new CtfInteger(bag); index = group.Index + group.Length; } else if ((match = s_struct.Match(statement)).Success) { var group = match.Groups[1]; if (group.ToString() != "{") { throw new InvalidOperationException(); } int open = group.Index; int close = FindCloseBrace(statement, open); CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); type = new CtfStruct(null, fields); index = close + 1; } else if ((match = s_float.Match(statement)).Success) { int open = match.Index + match.Length - 1; int close = FindCloseBrace(statement, open); CtfPropertyBag bag = GetPropertyBag(statement, open, close); type = new CtfFloat(bag); index = close + 1; } else if ((match = s_variant.Match(statement)).Success) { string switchVariable = match.Groups[1].ToString(); int open = statement.IndexOf('{'); int close = FindCloseBrace(statement, open); if (close == -1) { throw new InvalidOperationException(); } CtfField[] fields = ParseStructFields(statement, open, close).ToArray(); type = new CtfVariant(switchVariable, fields); index = close + 1; } else if ((match = s_variable.Match(statement)).Success) { var typeGroup = match.Groups[1]; string typeName = typeGroup.ToString().Trim(); if (typeName == "string") { type = new CtfString(); } else { type = new CtfUnresolvedType(typeName); } index = typeGroup.Index + typeGroup.Length; } else if ((match = s_enum.Match(statement)).Success) { var groups = match.Groups; string typeName = groups[1].ToString().Trim(); int open = statement.IndexOf('{'); int close = FindCloseBrace(statement, open); if (close == -1) { throw new InvalidOperationException(); } CtfNamedRange[] ranges = ParseNamedRanges(statement, open + 1, close).ToArray(); // TODO: Can enums just be an inline defined integer? type = new CtfEnum(new CtfUnresolvedType(typeName), ranges); index = close + 1; } else { // TODO: Floating point index = 0; return(null); } return(type); }
public CtfField(CtfMetadataType type, string name) { Type = type; Name = name; }
public CtfEnum(CtfMetadataType type, CtfNamedRange[] ranges) : base(CtfTypes.Enum) { Type = type; Values = ranges; }
public CtfArray(CtfMetadataType type, string index) : base(CtfTypes.Array) { Type = type; Index = index; }
internal void AddValue(string name, CtfMetadataType value) { _typeProperties[name] = value; }