private static unsafe void GenerateMetadataForProperty(PropertyAnalysis property, byte *pMetadataBlob, ref uint offset, uint blobSize)
        {
            Debug.Assert(property != null);
            Debug.Assert(pMetadataBlob != null);

            // Check if this property is a nested struct.
            InvokeTypeInfo invokeTypeInfo = property.typeInfo as InvokeTypeInfo;

            if (invokeTypeInfo != null)
            {
                // Each nested struct is serialized as:
                //     TypeCode.Object              : 4 bytes
                //     Number of properties         : 4 bytes
                //     Property description 0...N
                //     Nested struct property name  : NULL-terminated string.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object);

                // Get the set of properties to be serialized.
                PropertyAnalysis[] properties = invokeTypeInfo.properties;
                if (properties != null)
                {
                    // Write the count of serializable properties.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length);

                    foreach (PropertyAnalysis prop in properties)
                    {
                        GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize);
                    }
                }
                else
                {
                    // This struct has zero serializable properties so we just write the property count.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0);
                }

                // Write the property name.
                fixed(char *pPropertyName = property.name)
                {
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pPropertyName, ((uint)property.name.Length + 1) * 2);
                }
            }
            else
            {
                // Each primitive type is serialized as:
                //     TypeCode : 4 bytes
                //     PropertyName : NULL-terminated string
                TypeCode typeCode = GetTypeCodeExtended(property.typeInfo.DataType);
                Debug.Assert(typeCode != TypeCode.Object);

                // Write the type code.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode);

                // Write the property name.
                fixed(char *pPropertyName = property.name)
                {
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pPropertyName, ((uint)property.name.Length + 1) * 2);
                }
            }
        }
示例#2
0
        internal unsafe bool GenerateMetadata(byte *pMetadataBlob, ref uint offset, uint blobSize)
        {
            TypeCode typeCode = GetTypeCodeExtended(ParameterType);

            if (typeCode == TypeCode.Object)
            {
                // Each nested struct is serialized as:
                //     TypeCode.Object              : 4 bytes
                //     Number of properties         : 4 bytes
                //     Property description 0...N
                //     Nested struct property name  : NULL-terminated string.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object);

                if (!(TypeInfo is InvokeTypeInfo invokeTypeInfo))
                {
                    return(false);
                }

                // Get the set of properties to be serialized.
                PropertyAnalysis[]? properties = invokeTypeInfo.properties;
                if (properties != null)
                {
                    // Write the count of serializable properties.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length);

                    foreach (PropertyAnalysis prop in properties)
                    {
                        if (!GenerateMetadataForProperty(prop, pMetadataBlob, ref offset, blobSize))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    // This struct has zero serializable properties so we just write the property count.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0);
                }

                // Top-level structs don't have a property name, but for simplicity we write a NULL-char to represent the name.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, '\0');
            }
            else
            {
                // Write parameter type.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode);

                // Write parameter name.
                fixed(char *pParameterName = ParameterName)
                {
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pParameterName, ((uint)ParameterName.Length + 1) * 2);
                }
            }
            return(true);
        }
示例#3
0
        private static unsafe bool GenerateMetadataForNamedTypeV2(string name, TraceLoggingTypeInfo typeInfo, byte *pMetadataBlob, ref uint offset, uint blobSize)
        {
            Debug.Assert(pMetadataBlob != null);

            if (!GetMetadataLengthForNamedTypeV2(name, typeInfo, out uint length))
            {
                return(false);
            }

            EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, length);

            // Write the property name.
            fixed(char *pPropertyName = name)
            {
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (byte *)pPropertyName, ((uint)name.Length + 1) * 2);
            }

            return(GenerateMetadataForTypeV2(typeInfo, pMetadataBlob, ref offset, blobSize));
        }
示例#4
0
        private static unsafe bool GenerateMetadataForTypeV2(TraceLoggingTypeInfo?typeInfo, byte *pMetadataBlob, ref uint offset, uint blobSize)
        {
            Debug.Assert(typeInfo != null);
            Debug.Assert(pMetadataBlob != null);

            // Check if this type is a nested struct.
            if (typeInfo is InvokeTypeInfo invokeTypeInfo)
            {
                // Each nested struct is serialized as:
                //     TypeCode.Object              : 4 bytes
                //     Number of properties         : 4 bytes
                //     Property description 0...N
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)TypeCode.Object);

                // Get the set of properties to be serialized.
                PropertyAnalysis[]? properties = invokeTypeInfo.properties;
                if (properties != null)
                {
                    // Write the count of serializable properties.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)properties.Length);

                    foreach (PropertyAnalysis prop in properties)
                    {
                        if (!GenerateMetadataForNamedTypeV2(prop.name, prop.typeInfo, pMetadataBlob, ref offset, blobSize))
                        {
                            return(false);
                        }
                    }
                }
                else
                {
                    // This struct has zero serializable properties so we just write the property count.
                    EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)0);
                }
            }
            else if (typeInfo is EnumerableTypeInfo enumerableTypeInfo)
            {
                // Each enumerable is serialized as:
                //     TypeCode.Array               : 4 bytes
                //     ElementType                  : N bytes
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, EventPipeTypeCodeArray);
                GenerateMetadataForTypeV2(enumerableTypeInfo.ElementInfo, pMetadataBlob, ref offset, blobSize);
            }
            else if (typeInfo is ScalarArrayTypeInfo arrayTypeInfo)
            {
                // Each enumerable is serialized as:
                //     TypeCode.Array               : 4 bytes
                //     ElementType                  : N bytes
                if (!arrayTypeInfo.DataType.HasElementType)
                {
                    return(false);
                }

                TraceLoggingTypeInfo?elementTypeInfo;
                if (!GetTypeInfoFromType(arrayTypeInfo.DataType.GetElementType(), out elementTypeInfo))
                {
                    return(false);
                }

                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, EventPipeTypeCodeArray);
                GenerateMetadataForTypeV2(elementTypeInfo, pMetadataBlob, ref offset, blobSize);
            }
            else
            {
                // Each primitive type is serialized as:
                //     TypeCode : 4 bytes
                TypeCode typeCode = GetTypeCodeExtended(typeInfo.DataType);

                // EventPipe does not support this type.  Throw, which will cause no metadata to be registered for this event.
                if (typeCode == TypeCode.Object)
                {
                    return(false);
                }

                // Write the type code.
                EventPipeMetadataGenerator.WriteToBuffer(pMetadataBlob, blobSize, ref offset, (uint)typeCode);
            }
            return(true);
        }