예제 #1
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();
            }
        }
예제 #2
0
        public IEnumerable <CtfEventHeader> EnumerateEventHeaders()
        {
            CtfStruct  header   = _streamDefinition.EventHeader;
            CtfVariant v        = (CtfVariant)header.GetField("v").Type;
            CtfStruct  extended = (CtfStruct)v.GetVariant("extended").Type;
            CtfStruct  compact  = (CtfStruct)v.GetVariant("compact").Type;

            ulong lowMask = 0, highMask = 0, overflowBit = 0;
            ulong lastTimestamp = 0;

            StringBuilder processName = new StringBuilder();

            while (!_eof)
            {
                if (_readHeader)
                {
                    throw new InvalidOperationException("Must read an events data before reading the header again.");
                }

                _header.Clear();
                ResetBuffer();

                object[] result = ReadStruct(header);
                if (_eof)
                {
                    break;
                }

                ulong   timestamp;
                CtfEnum en       = (CtfEnum)header.GetField("id").Type;
                uint    event_id = header.GetFieldValue <uint>(result, "id");

                result = header.GetFieldValue <object[]>(result, "v");
                if (en.GetName((int)event_id) == "extended")
                {
                    event_id  = extended.GetFieldValue <uint>(result, "id");
                    timestamp = extended.GetFieldValue <ulong>(result, "timestamp");
                }
                else
                {
                    if (overflowBit == 0)
                    {
                        CtfInteger compactTimestamp = (CtfInteger)compact.GetField("timestamp").Type;
                        overflowBit = (1ul << compactTimestamp.Size);
                        lowMask     = overflowBit - 1;
                        highMask    = ~lowMask;
                    }

                    ulong uint27timestamp = compact.GetFieldValue <ulong>(result, "timestamp");
                    ulong prevLowerBits   = lastTimestamp & lowMask;

                    if (prevLowerBits < uint27timestamp)
                    {
                        timestamp = (lastTimestamp & highMask) | uint27timestamp;
                    }
                    else
                    {
                        timestamp  = (lastTimestamp & highMask) | uint27timestamp;
                        timestamp += overflowBit;
                    }
                }

                lastTimestamp = timestamp;

                CtfEvent evt = _streamDefinition.Events[(int)event_id];
                _header.Event     = evt;
                _header.Timestamp = timestamp;

                CtfStruct eventContext = _streamDefinition.EventContext;
                if (eventContext != null)
                {
                    result      = ReadStruct(eventContext);
                    _header.Pid = eventContext.GetFieldValue <int>(result, "_vpid");
                    _header.Tid = eventContext.GetFieldValue <int>(result, "_vtid");

                    int      procnameIndex = eventContext.GetFieldIndex("_procname");
                    object[] procname      = (object[])(result[procnameIndex]);
                    processName.Clear();
                    for (int i = 0; i < 17; i++)
                    {
                        sbyte b = (sbyte)procname[i];
                        if (b == 0)
                        {
                            break;
                        }

                        processName.Append((char)b);
                    }

                    _header.ProcessName = processName.ToString();
                }

                _readHeader = true;
                yield return(_header);
            }
        }