Exemplo n.º 1
0
        private DynamicTraceEventData NewTemplate(Guid providerId, string providerName, uint eventId, string eventName, Tuple <TypeCode, string>[] parameterDefinitions)
        {
            int    opcode;
            string opcodeName;

            GetOpcodeFromEventName(eventName, out opcode, out opcodeName);

            var template = new DynamicTraceEventData(null, (int)eventId, 0, eventName, Guid.Empty, opcode, opcodeName, providerId, providerName);

            if (parameterDefinitions != null && parameterDefinitions.Length > 0)
            {
                template.payloadNames   = new string[parameterDefinitions.Length];
                template.payloadFetches = new DynamicTraceEventData.PayloadFetch[parameterDefinitions.Length];

                ushort offset = 0;
                for (int i = 0; i < parameterDefinitions.Length; i++)
                {
                    template.payloadNames[i] = parameterDefinitions[i].Item2;
                    var fetch = new DynamicTraceEventData.PayloadFetch();

                    switch (parameterDefinitions[i].Item1)
                    {
                    case TypeCode.Boolean:
                    {
                        fetch.Type   = typeof(bool);
                        fetch.Size   = 4;       // We follow windows conventions and use 4 bytes for bool.
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Char:
                    {
                        fetch.Type   = typeof(char);
                        fetch.Size   = sizeof(char);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.SByte:
                    {
                        fetch.Type   = typeof(SByte);
                        fetch.Size   = sizeof(SByte);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Byte:
                    {
                        fetch.Type   = typeof(byte);
                        fetch.Size   = sizeof(byte);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Int16:
                    {
                        fetch.Type   = typeof(Int16);
                        fetch.Size   = sizeof(Int16);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.UInt16:
                    {
                        fetch.Type   = typeof(UInt16);
                        fetch.Size   = sizeof(UInt16);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Int32:
                    {
                        fetch.Type   = typeof(Int32);
                        fetch.Size   = sizeof(Int32);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.UInt32:
                    {
                        fetch.Type   = typeof(UInt32);
                        fetch.Size   = sizeof(UInt32);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Int64:
                    {
                        fetch.Type   = typeof(Int64);
                        fetch.Size   = sizeof(Int64);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.UInt64:
                    {
                        fetch.Type   = typeof(UInt64);
                        fetch.Size   = sizeof(UInt64);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Single:
                    {
                        fetch.Type   = typeof(Single);
                        fetch.Size   = sizeof(Single);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Double:
                    {
                        fetch.Type   = typeof(Double);
                        fetch.Size   = sizeof(Double);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.Decimal:
                    {
                        fetch.Type   = typeof(Decimal);
                        fetch.Size   = sizeof(Decimal);
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.DateTime:
                    {
                        fetch.Type   = typeof(DateTime);
                        fetch.Size   = 8;
                        fetch.Offset = offset;
                        break;
                    }

                    case TypeCode.String:
                    {
                        fetch.Type   = typeof(String);
                        fetch.Size   = DynamicTraceEventData.NULL_TERMINATED;
                        fetch.Offset = offset;
                        break;
                    }

                    default:
                    {
                        throw new NotSupportedException($"{parameterDefinitions[i].Item1} is not supported.");
                    }
                    }

                    if (fetch.Size >= DynamicTraceEventData.SPECIAL_SIZES || offset == ushort.MaxValue)
                    {
                        offset = ushort.MaxValue;           // Indicate that the offset must be computed at run time.
                    }
                    else
                    {
                        offset += fetch.Size;
                    }

                    template.payloadFetches[i] = fetch;
                }
            }
            else
            {
                template.payloadNames   = new string[0];
                template.payloadFetches = new DynamicTraceEventData.PayloadFetch[0];
            }

            return(template);
        }
Exemplo n.º 2
0
        private DynamicTraceEventData.PayloadFetchClassInfo ParseFields(PinnedStreamReader reader, int numFields)
        {
            string[] fieldNames = new string[numFields];
            DynamicTraceEventData.PayloadFetch[] fieldFetches = new DynamicTraceEventData.PayloadFetch[numFields];

            ushort offset = 0;

            for (int fieldIndex = 0; fieldIndex < numFields; fieldIndex++)
            {
                DynamicTraceEventData.PayloadFetch payloadFetch = new DynamicTraceEventData.PayloadFetch();

                // Read the TypeCode for the current field.
                TypeCode typeCode = (TypeCode)reader.ReadInt32();

                // Fill out the payload fetch object based on the TypeCode.
                switch (typeCode)
                {
                case TypeCode.Boolean:
                {
                    payloadFetch.Type   = typeof(bool);
                    payloadFetch.Size   = 4;       // We follow windows conventions and use 4 bytes for bool.
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Char:
                {
                    payloadFetch.Type   = typeof(char);
                    payloadFetch.Size   = sizeof(char);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.SByte:
                {
                    payloadFetch.Type   = typeof(SByte);
                    payloadFetch.Size   = sizeof(SByte);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Byte:
                {
                    payloadFetch.Type   = typeof(byte);
                    payloadFetch.Size   = sizeof(byte);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Int16:
                {
                    payloadFetch.Type   = typeof(Int16);
                    payloadFetch.Size   = sizeof(Int16);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.UInt16:
                {
                    payloadFetch.Type   = typeof(UInt16);
                    payloadFetch.Size   = sizeof(UInt16);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Int32:
                {
                    payloadFetch.Type   = typeof(Int32);
                    payloadFetch.Size   = sizeof(Int32);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.UInt32:
                {
                    payloadFetch.Type   = typeof(UInt32);
                    payloadFetch.Size   = sizeof(UInt32);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Int64:
                {
                    payloadFetch.Type   = typeof(Int64);
                    payloadFetch.Size   = sizeof(Int64);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.UInt64:
                {
                    payloadFetch.Type   = typeof(UInt64);
                    payloadFetch.Size   = sizeof(UInt64);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Single:
                {
                    payloadFetch.Type   = typeof(Single);
                    payloadFetch.Size   = sizeof(Single);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Double:
                {
                    payloadFetch.Type   = typeof(Double);
                    payloadFetch.Size   = sizeof(Double);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Decimal:
                {
                    payloadFetch.Type   = typeof(Decimal);
                    payloadFetch.Size   = sizeof(Decimal);
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.DateTime:
                {
                    payloadFetch.Type   = typeof(DateTime);
                    payloadFetch.Size   = 8;
                    payloadFetch.Offset = offset;
                    break;
                }

                case EventPipeEventSource.GuidTypeCode:
                {
                    payloadFetch.Type   = typeof(Guid);
                    payloadFetch.Size   = 16;
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.String:
                {
                    payloadFetch.Type   = typeof(String);
                    payloadFetch.Size   = DynamicTraceEventData.NULL_TERMINATED;
                    payloadFetch.Offset = offset;
                    break;
                }

                case TypeCode.Object:
                {
                    // TypeCode.Object represents an embedded struct.

                    // Read the number of fields in the struct.  Each of these fields could be an embedded struct,
                    // but these embedded structs are still counted as single fields.  They will be expanded when they are handled.
                    int structFieldCount = reader.ReadInt32();
                    DynamicTraceEventData.PayloadFetchClassInfo embeddedStructClassInfo = ParseFields(reader, structFieldCount);
                    if (embeddedStructClassInfo == null)
                    {
                        throw new Exception("Unable to parse metadata for embedded struct.");
                    }
                    payloadFetch = DynamicTraceEventData.PayloadFetch.StructPayloadFetch(offset, embeddedStructClassInfo);
                    break;
                }

                default:
                {
                    throw new NotSupportedException($"{typeCode} is not supported.");
                }
                }

                // Read the string name of the event payload field.
                fieldNames[fieldIndex] = reader.ReadNullTerminatedUnicodeString();

                // Update the offset into the event for the next payload fetch.
                if (payloadFetch.Size >= DynamicTraceEventData.SPECIAL_SIZES || offset == ushort.MaxValue)
                {
                    offset = ushort.MaxValue;           // Indicate that the offset must be computed at run time.
                }
                else
                {
                    offset += payloadFetch.Size;
                }

                // Save the current payload fetch.
                fieldFetches[fieldIndex] = payloadFetch;
            }

            return(new DynamicTraceEventData.PayloadFetchClassInfo()
            {
                FieldNames = fieldNames,
                FieldFetches = fieldFetches
            });
        }