コード例 #1
0
        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));
            }
        }
コード例 #2
0
ファイル: CtfMetadata.cs プロジェクト: lelonek1/perfview-1
 public CtfStream(CtfPropertyBag properties)
 {
     ID            = properties.GetInt("id");
     _header       = properties.GetType("event.header");
     _context      = properties.GetType("packet.context");
     _eventContext = properties.GetType("event.context");
 }
コード例 #3
0
        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());
        }
コード例 #4
0
        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();
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: CtfMetadata.cs プロジェクト: lelonek1/perfview-1
        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);
            }
        }
コード例 #7
0
        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();
            }
        }
コード例 #8
0
        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)));
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
 public CtfField(CtfMetadataType type, string name)
 {
     Type = type;
     Name = name;
 }
コード例 #11
0
 public CtfEnum(CtfMetadataType type, CtfNamedRange[] ranges)
     : base(CtfTypes.Enum)
 {
     Type   = type;
     Values = ranges;
 }
コード例 #12
0
 public CtfArray(CtfMetadataType type, string index)
     : base(CtfTypes.Array)
 {
     Type  = type;
     Index = index;
 }
コード例 #13
0
 internal void AddValue(string name, CtfMetadataType value)
 {
     _typeProperties[name] = value;
 }