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); } } }
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); }
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)); }
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); }