diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpLogSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpLogSerializer.cs index c6304b2324e..0d18cf9b151 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpLogSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpLogSerializer.cs @@ -62,13 +62,13 @@ internal static int TryWriteResourceLogs(ref byte[] buffer, int writePosition, S try { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpLogFieldNumberConstants.LogsData_Resource_Logs, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpLogFieldNumberConstants.LogsData_Resource_Logs, ProtobufWireType.LEN); int logsDataLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteResourceLogs(buffer, writePosition, sdkLimitOptions, experimentalOptions, resource, scopeLogs); - ProtobufSerializer.WriteReservedLength(buffer, logsDataLengthPosition, writePosition - (logsDataLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(logsDataLengthPosition), writePosition - (logsDataLengthPosition + ReserveSizeForLength)); // Serialization succeeded, return the final write position return writePosition; @@ -129,12 +129,12 @@ internal static int WriteScopeLogs(byte[] buffer, int writePosition, SdkLimitOpt { foreach (KeyValuePair> entry in scopeLogs) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpLogFieldNumberConstants.ResourceLogs_Scope_Logs, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpLogFieldNumberConstants.ResourceLogs_Scope_Logs, ProtobufWireType.LEN); int resourceLogsScopeLogsLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteScopeLog(buffer, writePosition, sdkLimitOptions, experimentalOptions, entry.Value[0].Logger.Name, entry.Value); - ProtobufSerializer.WriteReservedLength(buffer, resourceLogsScopeLogsLengthPosition, writePosition - (resourceLogsScopeLogsLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(resourceLogsScopeLogsLengthPosition), writePosition - (resourceLogsScopeLogsLengthPosition + ReserveSizeForLength)); } } @@ -148,8 +148,8 @@ internal static int WriteScopeLog(byte[] buffer, int writePosition, SdkLimitOpti var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); // numberOfUtf8CharsInString + tagSize + length field size. - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpLogFieldNumberConstants.ScopeLogs_Scope, ProtobufWireType.LEN); - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, numberOfUtf8CharsInString, value); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpLogFieldNumberConstants.ScopeLogs_Scope, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, numberOfUtf8CharsInString, value); for (int i = 0; i < logRecords.Count; i++) { @@ -175,23 +175,23 @@ internal static int WriteLogRecord(byte[] buffer, int writePosition, SdkLimitOpt ref var otlpTagWriterState = ref state.TagWriterState; - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.ScopeLogs_Log_Records, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.ScopeLogs_Log_Records, ProtobufWireType.LEN); int logRecordLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; var timestamp = (ulong)logRecord.Timestamp.ToUnixTimeNanoseconds(); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteFixed64WithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Time_Unix_Nano, timestamp); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteFixed64WithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Observed_Time_Unix_Nano, timestamp); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteFixed64WithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Time_Unix_Nano, timestamp); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteFixed64WithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Observed_Time_Unix_Nano, timestamp); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteEnumWithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Number, logRecord.Severity.HasValue ? (int)logRecord.Severity : 0); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteEnumWithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Number, logRecord.Severity.HasValue ? (int)logRecord.Severity : 0); if (!string.IsNullOrWhiteSpace(logRecord.SeverityText)) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Text, logRecord.SeverityText!); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Text, logRecord.SeverityText!); } else if (logRecord.Severity.HasValue) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Text, logRecord.Severity.Value.ToShortName()); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Severity_Text, logRecord.Severity.Value.ToShortName()); } if (experimentalOptions.EmitLogEventAttributes) @@ -248,30 +248,29 @@ internal static int WriteLogRecord(byte[] buffer, int writePosition, SdkLimitOpt if (logRecord.TraceId != default && logRecord.SpanId != default) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTagAndLength(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, TraceIdSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Trace_Id, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTagAndLength(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), TraceIdSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Trace_Id, ProtobufWireType.LEN); otlpTagWriterState.WritePosition = ProtobufOtlpTraceSerializer.WriteTraceId(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, logRecord.TraceId); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTagAndLength(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, SpanIdSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Span_Id, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTagAndLength(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), SpanIdSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Span_Id, ProtobufWireType.LEN); otlpTagWriterState.WritePosition = ProtobufOtlpTraceSerializer.WriteSpanId(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, logRecord.SpanId); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteFixed32WithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Flags, (uint)logRecord.TraceFlags); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteFixed32WithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Flags, (uint)logRecord.TraceFlags); } if (logRecord.EventId.Name != null) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Event_Name, logRecord.EventId.Name!); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteStringWithTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Event_Name, logRecord.EventId.Name!); } logRecord.ForEachScope(ProcessScope, state); if (otlpTagWriterState.DroppedTagCount > 0) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Dropped_Attributes_Count, ProtobufWireType.VARINT); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)otlpTagWriterState.DroppedTagCount); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(otlpTagWriterState.WritePosition), (uint)otlpTagWriterState.DroppedTagCount); } - ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, logRecordLengthPosition, otlpTagWriterState.WritePosition - (logRecordLengthPosition + ReserveSizeForLength)); - + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer.AsSpan(logRecordLengthPosition), otlpTagWriterState.WritePosition - (logRecordLengthPosition + ReserveSizeForLength)); return otlpTagWriterState.WritePosition; static void ProcessScope(LogRecordScope scope, SerializationState state) @@ -314,8 +313,9 @@ private static int WriteLogRecordBody(byte[] buffer, int writePosition, ReadOnly var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); // length = numberOfUtf8CharsInString + tagSize + length field size. - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Body, ProtobufWireType.LEN); - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); + + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpLogFieldNumberConstants.LogRecord_Body, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); return writePosition; } @@ -332,14 +332,14 @@ private static void AddLogAttribute(SerializationState state, string key, object } else { - state.TagWriterState.WritePosition = ProtobufSerializer.WriteTag(state.TagWriterState.Buffer, state.TagWriterState.WritePosition, ProtobufOtlpLogFieldNumberConstants.LogRecord_Attributes, ProtobufWireType.LEN); + state.TagWriterState.WritePosition += ProtobufSerializer.WriteTag(state.TagWriterState.Buffer.AsSpan(state.TagWriterState.WritePosition), ProtobufOtlpLogFieldNumberConstants.LogRecord_Attributes, ProtobufWireType.LEN); int logAttributesLengthPosition = state.TagWriterState.WritePosition; state.TagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref state.TagWriterState, key, value, state.AttributeValueLengthLimit); var logAttributesLength = state.TagWriterState.WritePosition - (logAttributesLengthPosition + ReserveSizeForLength); - ProtobufSerializer.WriteReservedLength(state.TagWriterState.Buffer, logAttributesLengthPosition, logAttributesLength); + ProtobufSerializer.WriteReservedLength(state.TagWriterState.Buffer.AsSpan(logAttributesLengthPosition), logAttributesLength); state.TagWriterState.TagCount++; } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpMetricSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpMetricSerializer.cs index 47873bc4c83..87cac46ae09 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpMetricSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpMetricSerializer.cs @@ -50,13 +50,13 @@ internal static int TryWriteResourceMetrics(ref byte[] buffer, int writePosition try { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.MetricsData_Resource_Metrics, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.MetricsData_Resource_Metrics, ProtobufWireType.LEN); int mericsDataLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteResourceMetrics(buffer, writePosition, resource, scopeMetrics); - ProtobufSerializer.WriteReservedLength(buffer, mericsDataLengthPosition, writePosition - (mericsDataLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(mericsDataLengthPosition), writePosition - (mericsDataLengthPosition + ReserveSizeForLength)); // Serialization succeeded, return the final write position return writePosition; @@ -65,7 +65,6 @@ internal static int TryWriteResourceMetrics(ref byte[] buffer, int writePosition { // Reset write position and attempt to increase the buffer size writePosition = entryWritePosition; - if (!ProtobufSerializer.IncreaseBufferSize(ref buffer, OtlpSignalType.Metrics)) { throw; @@ -102,13 +101,13 @@ private static int WriteScopeMetrics(byte[] buffer, int writePosition, Dictionar { foreach (KeyValuePair> entry in scopeMetrics) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ResourceMetrics_Scope_Metrics, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ResourceMetrics_Scope_Metrics, ProtobufWireType.LEN); int resourceMetricsScopeMetricsLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteScopeMetric(buffer, writePosition, entry.Key, entry.Value); - ProtobufSerializer.WriteReservedLength(buffer, resourceMetricsScopeMetricsLengthPosition, writePosition - (resourceMetricsScopeMetricsLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(resourceMetricsScopeMetricsLengthPosition), writePosition - (resourceMetricsScopeMetricsLengthPosition + ReserveSizeForLength)); } } @@ -117,7 +116,7 @@ private static int WriteScopeMetrics(byte[] buffer, int writePosition, Dictionar private static int WriteScopeMetric(byte[] buffer, int writePosition, string meterName, List metrics) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ScopeMetrics_Scope, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ScopeMetrics_Scope, ProtobufWireType.LEN); int instrumentationScopeLengthPosition = writePosition; writePosition += ReserveSizeForLength; @@ -125,10 +124,10 @@ private static int WriteScopeMetric(byte[] buffer, int writePosition, string met var meterVersion = metrics[0].MeterVersion; var meterTags = metrics[0].MeterTags; - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, meterName); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, meterName); if (meterVersion != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Version, meterVersion); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Version, meterVersion); } if (meterTags != null) @@ -149,7 +148,7 @@ private static int WriteScopeMetric(byte[] buffer, int writePosition, string met } } - ProtobufSerializer.WriteReservedLength(buffer, instrumentationScopeLengthPosition, writePosition - (instrumentationScopeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(instrumentationScopeLengthPosition), writePosition - (instrumentationScopeLengthPosition + ReserveSizeForLength)); for (int i = 0; i < metrics.Count; i++) { @@ -161,20 +160,20 @@ private static int WriteScopeMetric(byte[] buffer, int writePosition, string met private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ScopeMetrics_Metrics, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ScopeMetrics_Metrics, ProtobufWireType.LEN); int metricLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Name, metric.Name); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Name, metric.Name); if (metric.Description != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Description, metric.Description); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Description, metric.Description); } if (metric.Unit != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Unit, metric.Unit); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Unit, metric.Unit); } var aggregationValue = metric.Temporality == AggregationTemporality.Cumulative @@ -186,12 +185,12 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) case MetricType.LongSum: case MetricType.LongSumNonMonotonic: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Sum, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Sum, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteBoolWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Is_Monotonic, metric.MetricType == MetricType.LongSum); - writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Aggregation_Temporality, aggregationValue); + writePosition += ProtobufSerializer.WriteBoolWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Sum_Is_Monotonic, metric.MetricType == MetricType.LongSum); + writePosition += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Sum_Aggregation_Temporality, aggregationValue); foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { @@ -199,19 +198,19 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) writePosition = WriteNumberDataPoint(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Data_Points, in metricPoint, sum); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } case MetricType.DoubleSum: case MetricType.DoubleSumNonMonotonic: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Sum, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Sum, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteBoolWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Is_Monotonic, metric.MetricType == MetricType.DoubleSum); - writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Aggregation_Temporality, aggregationValue); + writePosition += ProtobufSerializer.WriteBoolWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Sum_Is_Monotonic, metric.MetricType == MetricType.DoubleSum); + writePosition += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Sum_Aggregation_Temporality, aggregationValue); foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { @@ -219,13 +218,13 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) writePosition = WriteNumberDataPoint(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Sum_Data_Points, in metricPoint, sum); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } case MetricType.LongGauge: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Gauge, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Gauge, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; @@ -235,13 +234,13 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) writePosition = WriteNumberDataPoint(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Gauge_Data_Points, in metricPoint, lastValue); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } case MetricType.DoubleGauge: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Gauge, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Gauge, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; @@ -251,29 +250,29 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) writePosition = WriteNumberDataPoint(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Gauge_Data_Points, in metricPoint, lastValue); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } case MetricType.Histogram: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Histogram, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Histogram, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Histogram_Aggregation_Temporality, aggregationValue); + writePosition += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Histogram_Aggregation_Temporality, aggregationValue); foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Histogram_Data_Points, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Histogram_Data_Points, ProtobufWireType.LEN); int dataPointLengthPosition = writePosition; writePosition += ReserveSizeForLength; var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Start_Time_Unix_Nano, startTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Start_Time_Unix_Nano, startTime); var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Time_Unix_Nano, endTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Time_Unix_Nano, endTime); foreach (var tag in metricPoint.Tags) { @@ -281,56 +280,56 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) } var count = (ulong)metricPoint.GetHistogramCount(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Count, count); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Count, count); var sum = metricPoint.GetHistogramSum(); - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Sum, sum); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Sum, sum); if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) { - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Min, min); - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Max, max); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Min, min); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Max, max); } foreach (var histogramMeasurement in metricPoint.GetHistogramBuckets()) { var bucketCount = (ulong)histogramMeasurement.BucketCount; - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Bucket_Counts, bucketCount); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Bucket_Counts, bucketCount); if (histogramMeasurement.ExplicitBound != double.PositiveInfinity) { - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Explicit_Bounds, histogramMeasurement.ExplicitBound); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Explicit_Bounds, histogramMeasurement.ExplicitBound); } } writePosition = WriteDoubleExemplars(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.HistogramDataPoint_Exemplars, in metricPoint); - ProtobufSerializer.WriteReservedLength(buffer, dataPointLengthPosition, writePosition - (dataPointLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(dataPointLengthPosition), writePosition - (dataPointLengthPosition + ReserveSizeForLength)); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } case MetricType.ExponentialHistogram: { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Exponential_Histogram, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Metric_Data_Exponential_Histogram, ProtobufWireType.LEN); int metricTypeLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogram_Aggregation_Temporality, aggregationValue); + writePosition += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogram_Aggregation_Temporality, aggregationValue); foreach (ref readonly var metricPoint in metric.GetMetricPoints()) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogram_Data_Points, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogram_Data_Points, ProtobufWireType.LEN); int dataPointLengthPosition = writePosition; writePosition += ReserveSizeForLength; var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Start_Time_Unix_Nano, startTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Start_Time_Unix_Nano, startTime); var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Time_Unix_Nano, endTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Time_Unix_Nano, endTime); foreach (var tag in metricPoint.Tags) { @@ -338,64 +337,64 @@ private static int WriteMetric(byte[] buffer, int writePosition, Metric metric) } var sum = metricPoint.GetHistogramSum(); - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Sum, sum); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Sum, sum); var count = (ulong)metricPoint.GetHistogramCount(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Count, count); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Count, count); if (metricPoint.TryGetHistogramMinMaxValues(out double min, out double max)) { - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Min, min); - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Max, max); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Min, min); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Max, max); } var exponentialHistogramData = metricPoint.GetExponentialHistogramData(); - writePosition = ProtobufSerializer.WriteSInt32WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Scale, exponentialHistogramData.Scale); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Zero_Count, (ulong)exponentialHistogramData.ZeroCount); + writePosition += ProtobufSerializer.WriteSInt32WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Scale, exponentialHistogramData.Scale); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Zero_Count, (ulong)exponentialHistogramData.ZeroCount); - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Positive, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Positive, ProtobufWireType.LEN); int positiveBucketsLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteSInt32WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Buckets_Offset, exponentialHistogramData.PositiveBuckets.Offset); + writePosition += ProtobufSerializer.WriteSInt32WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Buckets_Offset, exponentialHistogramData.PositiveBuckets.Offset); foreach (var bucketCount in exponentialHistogramData.PositiveBuckets) { - writePosition = ProtobufSerializer.WriteInt64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Buckets_Bucket_Counts, (ulong)bucketCount); + writePosition += ProtobufSerializer.WriteInt64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Buckets_Bucket_Counts, (ulong)bucketCount); } - ProtobufSerializer.WriteReservedLength(buffer, positiveBucketsLengthPosition, writePosition - (positiveBucketsLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(positiveBucketsLengthPosition), writePosition - (positiveBucketsLengthPosition + ReserveSizeForLength)); writePosition = WriteDoubleExemplars(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.ExponentialHistogramDataPoint_Exemplars, in metricPoint); - ProtobufSerializer.WriteReservedLength(buffer, dataPointLengthPosition, writePosition - (dataPointLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(dataPointLengthPosition), writePosition - (dataPointLengthPosition + ReserveSizeForLength)); } - ProtobufSerializer.WriteReservedLength(buffer, metricTypeLengthPosition, writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricTypeLengthPosition), writePosition - (metricTypeLengthPosition + ReserveSizeForLength)); break; } } - ProtobufSerializer.WriteReservedLength(buffer, metricLengthPosition, writePosition - (metricLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(metricLengthPosition), writePosition - (metricLengthPosition + ReserveSizeForLength)); return writePosition; } private static int WriteNumberDataPoint(byte[] buffer, int writePosition, int fieldNumber, in MetricPoint metricPoint, long value) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), fieldNumber, ProtobufWireType.LEN); int dataPointLengthPosition = writePosition; writePosition += ReserveSizeForLength; // Casting to ulong is ok here as the bit representation for long versus ulong will be the same // The difference would in the way the bit representation is interpreted on decoding side (signed versus unsigned) - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Value_As_Int, (ulong)value); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Value_As_Int, (ulong)value); var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Start_Time_Unix_Nano, startTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Start_Time_Unix_Nano, startTime); var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Time_Unix_Nano, endTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Time_Unix_Nano, endTime); foreach (var tag in metricPoint.Tags) { @@ -411,28 +410,28 @@ private static int WriteNumberDataPoint(byte[] buffer, int writePosition, int fi writePosition, in exemplar, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Exemplars, - static (byte[] buffer, int writePosition, in Exemplar exemplar) => ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Value_As_Int, (ulong)exemplar.LongValue)); + static (byte[] buffer, int writePosition, in Exemplar exemplar) => ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Exemplar_Value_As_Int, (ulong)exemplar.LongValue)); } } - ProtobufSerializer.WriteReservedLength(buffer, dataPointLengthPosition, writePosition - (dataPointLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(dataPointLengthPosition), writePosition - (dataPointLengthPosition + ReserveSizeForLength)); return writePosition; } private static int WriteNumberDataPoint(byte[] buffer, int writePosition, int fieldNumber, in MetricPoint metricPoint, double value) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), fieldNumber, ProtobufWireType.LEN); int dataPointLengthPosition = writePosition; writePosition += ReserveSizeForLength; // Using a func here to avoid boxing/unboxing. - writePosition = ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Value_As_Double, value); + writePosition += ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Value_As_Double, value); var startTime = (ulong)metricPoint.StartTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Start_Time_Unix_Nano, startTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Start_Time_Unix_Nano, startTime); var endTime = (ulong)metricPoint.EndTime.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Time_Unix_Nano, endTime); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Time_Unix_Nano, endTime); foreach (var tag in metricPoint.Tags) { @@ -441,7 +440,7 @@ private static int WriteNumberDataPoint(byte[] buffer, int writePosition, int fi writePosition = WriteDoubleExemplars(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.NumberDataPoint_Exemplars, in metricPoint); - ProtobufSerializer.WriteReservedLength(buffer, dataPointLengthPosition, writePosition - (dataPointLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(dataPointLengthPosition), writePosition - (dataPointLengthPosition + ReserveSizeForLength)); return writePosition; } @@ -453,13 +452,13 @@ private static int WriteTag(byte[] buffer, int writePosition, KeyValuePair ProtobufSerializer.WriteDoubleWithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Value_As_Double, exemplar.DoubleValue)); + static (byte[] buffer, int writePosition, in Exemplar exemplar) => ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Exemplar_Value_As_Double, exemplar.DoubleValue)); } } @@ -483,7 +482,7 @@ private static int WriteDoubleExemplars(byte[] buffer, int writePosition, int fi private static int WriteExemplar(byte[] buffer, int writePosition, in Exemplar exemplar, int fieldNumber, WriteExemplarFunc writeValueFunc) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), fieldNumber, ProtobufWireType.LEN); int exemplarLengthPosition = writePosition; writePosition += ReserveSizeForLength; @@ -492,25 +491,25 @@ private static int WriteExemplar(byte[] buffer, int writePosition, in Exemplar e writePosition = WriteTag(buffer, writePosition, tag, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Filtered_Attributes); } - writePosition = writeValueFunc(buffer, writePosition, in exemplar); + writePosition += writeValueFunc(buffer, writePosition, in exemplar); var time = (ulong)exemplar.Timestamp.ToUnixTimeNanoseconds(); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Time_Unix_Nano, time); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpMetricFieldNumberConstants.Exemplar_Time_Unix_Nano, time); if (exemplar.SpanId != default) { - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Span_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), SpanIdSize, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Span_Id, ProtobufWireType.LEN); var spanIdBytes = new Span(buffer, writePosition, SpanIdSize); exemplar.SpanId.CopyTo(spanIdBytes); writePosition += SpanIdSize; - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, TraceIdSize, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Trace_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), TraceIdSize, ProtobufOtlpMetricFieldNumberConstants.Exemplar_Trace_Id, ProtobufWireType.LEN); var traceIdBytes = new Span(buffer, writePosition, TraceIdSize); exemplar.TraceId.CopyTo(traceIdBytes); writePosition += TraceIdSize; } - ProtobufSerializer.WriteReservedLength(buffer, exemplarLengthPosition, writePosition - (exemplarLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(exemplarLengthPosition), writePosition - (exemplarLengthPosition + ReserveSizeForLength)); return writePosition; } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs index d12099bec02..e6f8f61f2fb 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpResourceSerializer.cs @@ -17,7 +17,7 @@ internal static int WriteResource(byte[] buffer, int writePosition, Resource? re WritePosition = writePosition, }; - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.ResourceSpans_Resource, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.ResourceSpans_Resource, ProtobufWireType.LEN); int resourceLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; @@ -40,20 +40,20 @@ internal static int WriteResource(byte[] buffer, int writePosition, Resource? re } var resourceLength = otlpTagWriterState.WritePosition - (resourceLengthPosition + ReserveSizeForLength); - ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, resourceLengthPosition, resourceLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer.AsSpan(resourceLengthPosition), resourceLength); return otlpTagWriterState.WritePosition; } private static void ProcessResourceAttribute(ref ProtobufOtlpTagWriter.OtlpTagWriterState otlpTagWriterState, KeyValuePair attribute) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Resource_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Resource_Attributes, ProtobufWireType.LEN); int resourceAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, attribute.Key, attribute.Value); var resourceAttributesLength = otlpTagWriterState.WritePosition - (resourceAttributesLengthPosition + ReserveSizeForLength); - ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, resourceAttributesLengthPosition, resourceAttributesLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer.AsSpan(resourceAttributesLengthPosition), resourceAttributesLength); } } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs index 04e60fa0db7..5acb431d12a 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTagWriter.cs @@ -18,59 +18,59 @@ private ProtobufOtlpTagWriter() protected override void WriteIntegralTag(ref OtlpTagWriterState state, string key, long value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); // Write KeyValue.Value tag, length and value. var size = ProtobufSerializer.ComputeVarInt64Size((ulong)value) + 1; // ComputeVarint64Size(ulong) + TagSize - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, size, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteInt64WithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Int_Value, (ulong)value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), size, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteInt64WithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Int_Value, (ulong)value); } protected override void WriteFloatingPointTag(ref OtlpTagWriterState state, string key, double value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); // Write KeyValue.Value tag, length and value. - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 9, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 8 + TagSize - state.WritePosition = ProtobufSerializer.WriteDoubleWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Double_Value, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 9, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 8 + TagSize + state.WritePosition += ProtobufSerializer.WriteDoubleWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Double_Value, value); } protected override void WriteBooleanTag(ref OtlpTagWriterState state, string key, bool value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); // Write KeyValue.Value tag, length and value. - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 2, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 1 + TagSize - state.WritePosition = ProtobufSerializer.WriteBoolWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bool_Value, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 2, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // 1 + TagSize + state.WritePosition += ProtobufSerializer.WriteBoolWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bool_Value, value); } protected override void WriteStringTag(ref OtlpTagWriterState state, string key, ReadOnlySpan value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); // Write KeyValue.Value tag, length and value. var numberOfUtf8CharsInString = ProtobufSerializer.GetNumberOfUtf8CharsInString(value); var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); // length = numberOfUtf8CharsInString + tagSize + length field size. - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); } protected override void WriteArrayTag(ref OtlpTagWriterState state, string key, ref OtlpTagWriterArrayState value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); // Write KeyValue.Value tag and length var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)value.WritePosition); - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, value.WritePosition + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // Array content length + Array tag size + length field size + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), value.WritePosition + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); // Array content length + Array tag size + length field size // Write Array tag and length - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, value.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Array_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), value.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Array_Value, ProtobufWireType.LEN); Buffer.BlockCopy(value.Buffer, 0, state.Buffer, state.WritePosition, value.WritePosition); state.WritePosition += value.WritePosition; } @@ -83,21 +83,21 @@ protected override void OnUnsupportedTagDropped( protected override bool TryWriteEmptyTag(ref OtlpTagWriterState state, string key, object? value) { - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 0, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 0, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); return true; } protected override bool TryWriteByteArrayTag(ref OtlpTagWriterState state, string key, ReadOnlySpan value) { // Write KeyValue tag - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key); + state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Key, key.AsSpan()); var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)value.Length); // length = value.Length + tagSize + length field size. - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, value.Length + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteByteArrayWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bytes_Value, value); + state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), value.Length + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.KeyValue_Value, ProtobufWireType.LEN); + state.WritePosition = ProtobufSerializer.WriteByteArrayWithTag(state.Buffer.AsSpan(), state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bytes_Value, value); return true; } @@ -135,26 +135,26 @@ public override OtlpTagWriterArrayState BeginWriteArray() public override void WriteNullValue(ref OtlpTagWriterArrayState state) { - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 0, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 0, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); } public override void WriteIntegralValue(ref OtlpTagWriterArrayState state, long value) { var size = ProtobufSerializer.ComputeVarInt64Size((ulong)value) + 1; - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, size, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteInt64WithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Int_Value, (ulong)value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), size, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteInt64WithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Int_Value, (ulong)value); } public override void WriteFloatingPointValue(ref OtlpTagWriterArrayState state, double value) { - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 9, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteDoubleWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Double_Value, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 9, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteDoubleWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Double_Value, value); } public override void WriteBooleanValue(ref OtlpTagWriterArrayState state, bool value) { - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, 2, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteBoolWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bool_Value, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), 2, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteBoolWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_Bool_Value, value); } public override void WriteStringValue(ref OtlpTagWriterArrayState state, ReadOnlySpan value) @@ -164,8 +164,8 @@ public override void WriteStringValue(ref OtlpTagWriterArrayState state, ReadOnl var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); // length = numberOfUtf8CharsInString + tagSize + length field size. - state.WritePosition = ProtobufSerializer.WriteTagAndLength(state.Buffer, state.WritePosition, numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); - state.WritePosition = ProtobufSerializer.WriteStringWithTag(state.Buffer, state.WritePosition, ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); + state.WritePosition += ProtobufSerializer.WriteTagAndLength(state.Buffer.AsSpan(state.WritePosition), numberOfUtf8CharsInString + 1 + serializedLengthSize, ProtobufOtlpCommonFieldNumberConstants.ArrayValue_Value, ProtobufWireType.LEN); + state.WritePosition += ProtobufSerializer.WriteStringWithTag(state.Buffer.AsSpan(state.WritePosition), ProtobufOtlpCommonFieldNumberConstants.AnyValue_String_Value, numberOfUtf8CharsInString, value); } public override void EndWriteArray(ref OtlpTagWriterArrayState state) diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs index 7fb7eb2b5ad..27dc4ae46d3 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufOtlpTraceSerializer.cs @@ -51,13 +51,13 @@ internal static int TryWriteResourceSpans(ref byte[] buffer, int writePosition, try { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.TracesData_Resource_Spans, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.TracesData_Resource_Spans, ProtobufWireType.LEN); int resourceSpansScopeSpansLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteResourceSpans(buffer, writePosition, sdkLimitOptions, resource); - ProtobufSerializer.WriteReservedLength(buffer, resourceSpansScopeSpansLengthPosition, writePosition - (resourceSpansScopeSpansLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(resourceSpansScopeSpansLengthPosition), writePosition - (resourceSpansScopeSpansLengthPosition + ReserveSizeForLength)); // Serialization succeeded, return the final write position return writePosition; @@ -107,12 +107,12 @@ internal static int WriteScopeSpans(byte[] buffer, int writePosition, SdkLimitOp { foreach (KeyValuePair> entry in scopeTracesList) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.ResourceSpans_Scope_Spans, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.ResourceSpans_Scope_Spans, ProtobufWireType.LEN); int resourceSpansScopeSpansLengthPosition = writePosition; writePosition += ReserveSizeForLength; writePosition = WriteScopeSpan(buffer, writePosition, sdkLimitOptions, entry.Value[0].Source, entry.Value); - ProtobufSerializer.WriteReservedLength(buffer, resourceSpansScopeSpansLengthPosition, writePosition - (resourceSpansScopeSpansLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(resourceSpansScopeSpansLengthPosition), writePosition - (resourceSpansScopeSpansLengthPosition + ReserveSizeForLength)); } } @@ -121,14 +121,14 @@ internal static int WriteScopeSpans(byte[] buffer, int writePosition, SdkLimitOp internal static int WriteScopeSpan(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, ActivitySource activitySource, List activities) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.ScopeSpans_Scope, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.ScopeSpans_Scope, ProtobufWireType.LEN); int instrumentationScopeLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, activitySource.Name); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Name, activitySource.Name); if (activitySource.Version != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Version, activitySource.Version); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Version, activitySource.Version); } if (activitySource.Tags != null) @@ -149,14 +149,14 @@ internal static int WriteScopeSpan(byte[] buffer, int writePosition, SdkLimitOpt { if (otlpTagWriterState.TagCount < maxAttributeCount) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Attributes, ProtobufWireType.LEN); int instrumentationScopeAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, activitySourceTagsList[i].Key, activitySourceTagsList[i].Value, maxAttributeValueLength); var instrumentationScopeAttributesLength = otlpTagWriterState.WritePosition - (instrumentationScopeAttributesLengthPosition + ReserveSizeForLength); - ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, instrumentationScopeAttributesLengthPosition, instrumentationScopeAttributesLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer.AsSpan(instrumentationScopeAttributesLengthPosition), instrumentationScopeAttributesLength); otlpTagWriterState.TagCount++; } else @@ -171,14 +171,14 @@ internal static int WriteScopeSpan(byte[] buffer, int writePosition, SdkLimitOpt { if (otlpTagWriterState.TagCount < maxAttributeCount) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Attributes, ProtobufWireType.LEN); int instrumentationScopeAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); var instrumentationScopeAttributesLength = otlpTagWriterState.WritePosition - (instrumentationScopeAttributesLengthPosition + ReserveSizeForLength); - ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer, instrumentationScopeAttributesLengthPosition, instrumentationScopeAttributesLength); + ProtobufSerializer.WriteReservedLength(otlpTagWriterState.Buffer.AsSpan(instrumentationScopeAttributesLengthPosition), instrumentationScopeAttributesLength); otlpTagWriterState.TagCount++; } else @@ -190,14 +190,14 @@ internal static int WriteScopeSpan(byte[] buffer, int writePosition, SdkLimitOpt if (otlpTagWriterState.DroppedTagCount > 0) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Dropped_Attributes_Count, ProtobufWireType.VARINT); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)otlpTagWriterState.DroppedTagCount); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpCommonFieldNumberConstants.InstrumentationScope_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(otlpTagWriterState.WritePosition), (uint)otlpTagWriterState.DroppedTagCount); } writePosition = otlpTagWriterState.WritePosition; } - ProtobufSerializer.WriteReservedLength(buffer, instrumentationScopeLengthPosition, writePosition - (instrumentationScopeLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(instrumentationScopeLengthPosition), writePosition - (instrumentationScopeLengthPosition + ReserveSizeForLength)); for (int i = 0; i < activities.Count; i++) { @@ -209,38 +209,38 @@ internal static int WriteScopeSpan(byte[] buffer, int writePosition, SdkLimitOpt internal static int WriteSpan(byte[] buffer, int writePosition, SdkLimitOptions sdkLimitOptions, Activity activity) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.ScopeSpans_Span, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.ScopeSpans_Span, ProtobufWireType.LEN); int spanLengthPosition = writePosition; writePosition += ReserveSizeForLength; - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, TraceIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Trace_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), TraceIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Trace_Id, ProtobufWireType.LEN); writePosition = WriteTraceId(buffer, writePosition, activity.TraceId); - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Span_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Span_Id, ProtobufWireType.LEN); writePosition = WriteSpanId(buffer, writePosition, activity.SpanId); if (activity.TraceStateString != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Trace_State, activity.TraceStateString); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Trace_State, activity.TraceStateString); } if (activity.ParentSpanId != default) { - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Parent_Span_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Span_Parent_Span_Id, ProtobufWireType.LEN); writePosition = WriteSpanId(buffer, writePosition, activity.ParentSpanId); } writePosition = WriteTraceFlags(buffer, writePosition, activity.ActivityTraceFlags, activity.HasRemoteParent, ProtobufOtlpTraceFieldNumberConstants.Span_Flags); - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Name, activity.DisplayName); - writePosition = ProtobufSerializer.WriteEnumWithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Kind, (int)activity.Kind + 1); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Start_Time_Unix_Nano, (ulong)activity.StartTimeUtc.ToUnixTimeNanoseconds()); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_End_Time_Unix_Nano, (ulong)(activity.StartTimeUtc.ToUnixTimeNanoseconds() + activity.Duration.ToNanoseconds())); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Name, activity.DisplayName); + writePosition += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Kind, (int)activity.Kind + 1); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Start_Time_Unix_Nano, (ulong)activity.StartTimeUtc.ToUnixTimeNanoseconds()); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_End_Time_Unix_Nano, (ulong)(activity.StartTimeUtc.ToUnixTimeNanoseconds() + activity.Duration.ToNanoseconds())); (writePosition, StatusCode? statusCode, string? statusMessage) = WriteActivityTags(buffer, writePosition, sdkLimitOptions, activity); writePosition = WriteSpanEvents(buffer, writePosition, sdkLimitOptions, activity); writePosition = WriteSpanLinks(buffer, writePosition, sdkLimitOptions, activity); writePosition = WriteSpanStatus(buffer, writePosition, activity, statusCode, statusMessage); - ProtobufSerializer.WriteReservedLength(buffer, spanLengthPosition, writePosition - (spanLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(spanLengthPosition), writePosition - (spanLengthPosition + ReserveSizeForLength)); return writePosition; } @@ -269,7 +269,7 @@ internal static int WriteTraceFlags(byte[] buffer, int position, ActivityTraceFl spanFlags |= 0x00000200; } - position = ProtobufSerializer.WriteFixed32WithTag(buffer, position, fieldNumber, spanFlags); + position += ProtobufSerializer.WriteFixed32WithTag(buffer.AsSpan(position), fieldNumber, spanFlags); return position; } @@ -314,13 +314,13 @@ not null when OkStatusCodeTagValue.Equals(tag.Value as string, StringComparison. if (otlpTagWriterState.TagCount < maxAttributeCount) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Attributes, ProtobufWireType.LEN); int spanAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); - ProtobufSerializer.WriteReservedLength(buffer, spanAttributesLengthPosition, otlpTagWriterState.WritePosition - (spanAttributesLengthPosition + 4)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(spanAttributesLengthPosition), otlpTagWriterState.WritePosition - (spanAttributesLengthPosition + 4)); otlpTagWriterState.TagCount++; } else @@ -331,8 +331,8 @@ not null when OkStatusCodeTagValue.Equals(tag.Value as string, StringComparison. if (otlpTagWriterState.DroppedTagCount > 0) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Attributes_Count, ProtobufWireType.VARINT); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)otlpTagWriterState.DroppedTagCount); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(otlpTagWriterState.WritePosition), (uint)otlpTagWriterState.DroppedTagCount); } return (otlpTagWriterState.WritePosition, statusCode, statusMessage); @@ -347,15 +347,15 @@ internal static int WriteSpanEvents(byte[] buffer, int writePosition, SdkLimitOp { if (eventCount < maxEventCountLimit) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Events, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Events, ProtobufWireType.LEN); int spanEventsLengthPosition = writePosition; writePosition += ReserveSizeForLength; // Reserve 4 bytes for length - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Event_Name, evnt.Name); - writePosition = ProtobufSerializer.WriteFixed64WithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Event_Time_Unix_Nano, (ulong)evnt.Timestamp.ToUnixTimeNanoseconds()); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Event_Name, evnt.Name); + writePosition += ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Event_Time_Unix_Nano, (ulong)evnt.Timestamp.ToUnixTimeNanoseconds()); writePosition = WriteEventAttributes(ref buffer, writePosition, sdkLimitOptions, evnt); - ProtobufSerializer.WriteReservedLength(buffer, spanEventsLengthPosition, writePosition - (spanEventsLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(spanEventsLengthPosition), writePosition - (spanEventsLengthPosition + ReserveSizeForLength)); eventCount++; } else @@ -366,8 +366,8 @@ internal static int WriteSpanEvents(byte[] buffer, int writePosition, SdkLimitOp if (droppedEventCount > 0) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Events_Count, ProtobufWireType.VARINT); - writePosition = ProtobufSerializer.WriteVarInt32(buffer, writePosition, (uint)droppedEventCount); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Events_Count, ProtobufWireType.VARINT); + writePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(writePosition), (uint)droppedEventCount); } return writePosition; @@ -390,11 +390,11 @@ internal static int WriteEventAttributes(ref byte[] buffer, int writePosition, S { if (otlpTagWriterState.TagCount < maxAttributeCount) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Event_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Event_Attributes, ProtobufWireType.LEN); int eventAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); - ProtobufSerializer.WriteReservedLength(buffer, eventAttributesLengthPosition, otlpTagWriterState.WritePosition - (eventAttributesLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(eventAttributesLengthPosition), otlpTagWriterState.WritePosition - (eventAttributesLengthPosition + ReserveSizeForLength)); otlpTagWriterState.TagCount++; } else @@ -405,8 +405,8 @@ internal static int WriteEventAttributes(ref byte[] buffer, int writePosition, S if (otlpTagWriterState.DroppedTagCount > 0) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Event_Dropped_Attributes_Count, ProtobufWireType.VARINT); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)otlpTagWriterState.DroppedTagCount); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Event_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(otlpTagWriterState.WritePosition), (uint)otlpTagWriterState.DroppedTagCount); } return otlpTagWriterState.WritePosition; @@ -422,23 +422,23 @@ internal static int WriteSpanLinks(byte[] buffer, int writePosition, SdkLimitOpt { if (linkCount < maxLinksCount) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Links, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Links, ProtobufWireType.LEN); int spanLinksLengthPosition = writePosition; writePosition += ReserveSizeForLength; // Reserve 4 bytes for length - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, TraceIdSize, ProtobufOtlpTraceFieldNumberConstants.Link_Trace_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), TraceIdSize, ProtobufOtlpTraceFieldNumberConstants.Link_Trace_Id, ProtobufWireType.LEN); writePosition = WriteTraceId(buffer, writePosition, link.Context.TraceId); - writePosition = ProtobufSerializer.WriteTagAndLength(buffer, writePosition, SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Link_Span_Id, ProtobufWireType.LEN); + writePosition += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(writePosition), SpanIdSize, ProtobufOtlpTraceFieldNumberConstants.Link_Span_Id, ProtobufWireType.LEN); writePosition = WriteSpanId(buffer, writePosition, link.Context.SpanId); if (link.Context.TraceState != null) { - writePosition = ProtobufSerializer.WriteStringWithTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Trace_State, link.Context.TraceState); + writePosition += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Trace_State, link.Context.TraceState); } writePosition = WriteLinkAttributes(buffer, writePosition, sdkLimitOptions, link); writePosition = WriteTraceFlags(buffer, writePosition, link.Context.TraceFlags, link.Context.IsRemote, ProtobufOtlpTraceFieldNumberConstants.Link_Flags); - ProtobufSerializer.WriteReservedLength(buffer, spanLinksLengthPosition, writePosition - (spanLinksLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(spanLinksLengthPosition), writePosition - (spanLinksLengthPosition + ReserveSizeForLength)); linkCount++; } else @@ -449,8 +449,8 @@ internal static int WriteSpanLinks(byte[] buffer, int writePosition, SdkLimitOpt if (droppedLinkCount > 0) { - writePosition = ProtobufSerializer.WriteTag(buffer, writePosition, ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Links_Count, ProtobufWireType.VARINT); - writePosition = ProtobufSerializer.WriteVarInt32(buffer, writePosition, (uint)droppedLinkCount); + writePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(writePosition), ProtobufOtlpTraceFieldNumberConstants.Span_Dropped_Links_Count, ProtobufWireType.VARINT); + writePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(writePosition), (uint)droppedLinkCount); } return writePosition; @@ -472,11 +472,11 @@ internal static int WriteLinkAttributes(byte[] buffer, int writePosition, SdkLim { if (otlpTagWriterState.TagCount < maxAttributeCount) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Link_Attributes, ProtobufWireType.LEN); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(otlpTagWriterState.Buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Link_Attributes, ProtobufWireType.LEN); int linkAttributesLengthPosition = otlpTagWriterState.WritePosition; otlpTagWriterState.WritePosition += ReserveSizeForLength; ProtobufOtlpTagWriter.Instance.TryWriteTag(ref otlpTagWriterState, tag.Key, tag.Value, maxAttributeValueLength); - ProtobufSerializer.WriteReservedLength(buffer, linkAttributesLengthPosition, otlpTagWriterState.WritePosition - (linkAttributesLengthPosition + ReserveSizeForLength)); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(linkAttributesLengthPosition), otlpTagWriterState.WritePosition - (linkAttributesLengthPosition + ReserveSizeForLength)); otlpTagWriterState.TagCount++; } else @@ -487,8 +487,8 @@ internal static int WriteLinkAttributes(byte[] buffer, int writePosition, SdkLim if (otlpTagWriterState.DroppedTagCount > 0) { - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteTag(buffer, otlpTagWriterState.WritePosition, ProtobufOtlpTraceFieldNumberConstants.Link_Dropped_Attributes_Count, ProtobufWireType.VARINT); - otlpTagWriterState.WritePosition = ProtobufSerializer.WriteVarInt32(buffer, otlpTagWriterState.WritePosition, (uint)otlpTagWriterState.DroppedTagCount); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteTag(buffer.AsSpan(otlpTagWriterState.WritePosition), ProtobufOtlpTraceFieldNumberConstants.Link_Dropped_Attributes_Count, ProtobufWireType.VARINT); + otlpTagWriterState.WritePosition += ProtobufSerializer.WriteVarInt32(buffer.AsSpan(otlpTagWriterState.WritePosition), (uint)otlpTagWriterState.DroppedTagCount); } return otlpTagWriterState.WritePosition; @@ -512,16 +512,16 @@ internal static int WriteSpanStatus(byte[] buffer, int position, Activity activi var serializedLengthSize = ProtobufSerializer.ComputeVarInt64Size((ulong)numberOfUtf8CharsInString); // length = numberOfUtf8CharsInString + Status_Message tag size + serializedLengthSize field size + Span_Status tag size + Span_Status length size. - position = ProtobufSerializer.WriteTagAndLength(buffer, position, numberOfUtf8CharsInString + 1 + serializedLengthSize + 2, ProtobufOtlpTraceFieldNumberConstants.Span_Status, ProtobufWireType.LEN); - position = ProtobufSerializer.WriteStringWithTag(buffer, position, ProtobufOtlpTraceFieldNumberConstants.Status_Message, numberOfUtf8CharsInString, descriptionSpan); + position += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(position), numberOfUtf8CharsInString + 1 + serializedLengthSize + 2, ProtobufOtlpTraceFieldNumberConstants.Span_Status, ProtobufWireType.LEN); + position += ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(position), ProtobufOtlpTraceFieldNumberConstants.Status_Message, numberOfUtf8CharsInString, descriptionSpan); } else { - position = ProtobufSerializer.WriteTagAndLength(buffer, position, 2, ProtobufOtlpTraceFieldNumberConstants.Span_Status, ProtobufWireType.LEN); + position += ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(position), 2, ProtobufOtlpTraceFieldNumberConstants.Span_Status, ProtobufWireType.LEN); } var finalStatusCode = useActivity ? (int)activity.Status : (statusCode != null && statusCode != StatusCode.Unset) ? (int)statusCode! : (int)StatusCode.Unset; - position = ProtobufSerializer.WriteEnumWithTag(buffer, position, ProtobufOtlpTraceFieldNumberConstants.Status_Code, finalStatusCode); + position += ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(position), ProtobufOtlpTraceFieldNumberConstants.Status_Code, finalStatusCode); return position; } diff --git a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs index deee79e77db..6c3b1981b5b 100644 --- a/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs +++ b/src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/Serializer/ProtobufSerializer.cs @@ -27,137 +27,133 @@ internal static class ProtobufSerializer internal static uint GetTagValue(int fieldNumber, ProtobufWireType wireType) => ((uint)(fieldNumber << 3)) | (uint)wireType; [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteTag(byte[] buffer, int writePosition, int fieldNumber, ProtobufWireType type) => WriteVarInt32(buffer, writePosition, GetTagValue(fieldNumber, type)); + internal static int WriteTag(Span buffer, int fieldNumber, ProtobufWireType type) => WriteVarInt32(buffer, GetTagValue(fieldNumber, type)); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteLength(byte[] buffer, int writePosition, int length) => WriteVarInt32(buffer, writePosition, (uint)length); + internal static int WriteLength(Span buffer, int length) => WriteVarInt32(buffer, (uint)length); [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteTagAndLength(byte[] buffer, int writePosition, int contentLength, int fieldNumber, ProtobufWireType type) + internal static int WriteTagAndLength(Span buffer, int contentLength, int fieldNumber, ProtobufWireType type) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, type); - writePosition = WriteLength(buffer, writePosition, contentLength); - - return writePosition; + var bytesWritten = WriteTag(buffer, fieldNumber, type); + bytesWritten += WriteLength(buffer.Slice(bytesWritten), contentLength); + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void WriteReservedLength(byte[] buffer, int writePosition, int length) + internal static void WriteReservedLength(Span buffer, int length) { - var slice = buffer.AsSpan(writePosition, 4); - slice[0] = (byte)((length & MaskBitsLow) | MaskBitHigh); - slice[1] = (byte)(((length >> 7) & MaskBitsLow) | MaskBitHigh); - slice[2] = (byte)(((length >> 14) & MaskBitsLow) | MaskBitHigh); - slice[3] = (byte)((length >> 21) & MaskBitsLow); + buffer[0] = (byte)((length & MaskBitsLow) | MaskBitHigh); + buffer[1] = (byte)(((length >> 7) & MaskBitsLow) | MaskBitHigh); + buffer[2] = (byte)(((length >> 14) & MaskBitsLow) | MaskBitHigh); + buffer[3] = (byte)((length >> 21) & MaskBitsLow); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteBoolWithTag(byte[] buffer, int writePosition, int fieldNumber, bool value) + internal static int WriteBoolWithTag(Span buffer, int fieldNumber, bool value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); - buffer[writePosition++] = value ? (byte)1 : (byte)0; - return writePosition; + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.VARINT); + buffer[bytesWritten] = value ? (byte)1 : (byte)0; + return bytesWritten + 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteEnumWithTag(byte[] buffer, int writePosition, int fieldNumber, int value) + internal static int WriteEnumWithTag(Span buffer, int fieldNumber, int value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); - buffer[writePosition++] = (byte)value; - return writePosition; + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.VARINT); + buffer[bytesWritten] = (byte)value; + return bytesWritten + 1; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteFixed32LittleEndianFormat(byte[] buffer, int writePosition, uint value) + internal static int WriteFixed32LittleEndianFormat(Span buffer, uint value) { - Span span = new(buffer, writePosition, Fixed32Size); + var span = buffer.Slice(0, Fixed32Size); BinaryPrimitives.WriteUInt32LittleEndian(span, value); - writePosition += Fixed32Size; - return writePosition; + return Fixed32Size; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteFixed64LittleEndianFormat(byte[] buffer, int writePosition, ulong value) + internal static int WriteFixed64LittleEndianFormat(Span buffer, ulong value) { - Span span = new(buffer, writePosition, Fixed64Size); + var span = buffer.Slice(0, Fixed64Size); BinaryPrimitives.WriteUInt64LittleEndian(span, value); - writePosition += Fixed64Size; - return writePosition; + return Fixed64Size; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteFixed32WithTag(byte[] buffer, int writePosition, int fieldNumber, uint value) + internal static int WriteFixed32WithTag(Span buffer, int fieldNumber, uint value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I32); - writePosition = WriteFixed32LittleEndianFormat(buffer, writePosition, value); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.I32); + bytesWritten += WriteFixed32LittleEndianFormat(buffer.Slice(bytesWritten), value); - return writePosition; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteFixed64WithTag(byte[] buffer, int writePosition, int fieldNumber, ulong value) + internal static int WriteFixed64WithTag(Span buffer, int fieldNumber, ulong value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I64); - writePosition = WriteFixed64LittleEndianFormat(buffer, writePosition, value); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.I64); + bytesWritten += WriteFixed64LittleEndianFormat(buffer.Slice(bytesWritten), value); - return writePosition; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteSInt32WithTag(byte[] buffer, int writePosition, int fieldNumber, int value) + internal static int WriteSInt32WithTag(Span buffer, int fieldNumber, int value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.VARINT); + bytesWritten += WriteVarInt32(buffer.Slice(bytesWritten), (uint)((value << 1) ^ (value >> 31))); - // https://protobuf.dev/programming-guides/encoding/#signed-ints - writePosition = WriteVarInt32(buffer, writePosition, (uint)((value << 1) ^ (value >> 31))); - - return writePosition; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteVarInt32(byte[] buffer, int writePosition, uint value) + internal static int WriteVarInt32(Span buffer, uint value) { + var bytesWritten = 0; while (value >= UInt128) { - buffer[writePosition++] = (byte)(MaskBitHigh | (value & MaskBitsLow)); + buffer[bytesWritten++] = (byte)(MaskBitHigh | (value & MaskBitsLow)); value >>= 7; } - buffer[writePosition++] = (byte)value; - return writePosition; + buffer[bytesWritten++] = (byte)value; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteVarInt64(byte[] buffer, int writePosition, ulong value) + internal static int WriteVarInt64(Span buffer, ulong value) { + var bytesWritten = 0; while (value >= ULong128) { - buffer[writePosition++] = (byte)(MaskBitHigh | (value & MaskBitsLow)); + buffer[bytesWritten++] = (byte)(MaskBitHigh | (value & MaskBitsLow)); value >>= 7; } - buffer[writePosition++] = (byte)value; - return writePosition; + buffer[bytesWritten++] = (byte)value; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteInt64WithTag(byte[] buffer, int writePosition, int fieldNumber, ulong value) + internal static int WriteInt64WithTag(Span buffer, int fieldNumber, ulong value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.VARINT); - writePosition = WriteVarInt64(buffer, writePosition, value); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.VARINT); + bytesWritten += WriteVarInt64(buffer.Slice(bytesWritten), value); - return writePosition; + return bytesWritten; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteDoubleWithTag(byte[] buffer, int writePosition, int fieldNumber, double value) + internal static int WriteDoubleWithTag(Span buffer, int fieldNumber, double value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.I64); - writePosition = WriteFixed64LittleEndianFormat(buffer, writePosition, (ulong)BitConverter.DoubleToInt64Bits(value)); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.I64); + bytesWritten += WriteFixed64LittleEndianFormat(buffer.Slice(bytesWritten), (ulong)BitConverter.DoubleToInt64Bits(value)); - return writePosition; + return bytesWritten; } /// @@ -232,22 +228,22 @@ internal static int ComputeVarInt64Size(ulong value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteByteArrayWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan value) + internal static int WriteByteArrayWithTag(Span buffer, int writePosition, int fieldNumber, ReadOnlySpan value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); - writePosition = WriteLength(buffer, writePosition, value.Length); - value.CopyTo(buffer.AsSpan(writePosition)); + writePosition = WriteTag(buffer.Slice(writePosition), fieldNumber, ProtobufWireType.LEN); + writePosition = WriteLength(buffer.Slice(writePosition), value.Length); + value.CopyTo(buffer.Slice(writePosition)); writePosition += value.Length; return writePosition; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, string value) + internal static int WriteStringWithTag(Span buffer, int fieldNumber, string value) { Debug.Assert(value != null, "value was null"); - return WriteStringWithTag(buffer, writePosition, fieldNumber, value.AsSpan()); + return WriteStringWithTag(buffer, fieldNumber, value.AsSpan()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -269,20 +265,20 @@ internal static int GetNumberOfUtf8CharsInString(ReadOnlySpan value) } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, ReadOnlySpan value) + internal static int WriteStringWithTag(Span buffer, int fieldNumber, ReadOnlySpan value) { var numberOfUtf8CharsInString = GetNumberOfUtf8CharsInString(value); - return WriteStringWithTag(buffer, writePosition, fieldNumber, numberOfUtf8CharsInString, value); + return WriteStringWithTag(buffer, fieldNumber, numberOfUtf8CharsInString, value); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fieldNumber, int numberOfUtf8CharsInString, ReadOnlySpan value) + internal static int WriteStringWithTag(Span buffer, int fieldNumber, int numberOfUtf8CharsInString, ReadOnlySpan value) { - writePosition = WriteTag(buffer, writePosition, fieldNumber, ProtobufWireType.LEN); - writePosition = WriteLength(buffer, writePosition, numberOfUtf8CharsInString); + var bytesWritten = WriteTag(buffer, fieldNumber, ProtobufWireType.LEN); + bytesWritten += WriteLength(buffer.Slice(bytesWritten), numberOfUtf8CharsInString); #if NETFRAMEWORK || NETSTANDARD2_0 - if (buffer.Length - writePosition < numberOfUtf8CharsInString) + if (buffer.Length - bytesWritten < numberOfUtf8CharsInString) { // Note: Validate there is enough space in the buffer to hold the // string otherwise throw to trigger a resize of the buffer. @@ -297,18 +293,18 @@ internal static int WriteStringWithTag(byte[] buffer, int writePosition, int fie { fixed (byte* bufferPtr = buffer) { - var bytesWritten = Utf8Encoding.GetBytes(strPtr, value.Length, bufferPtr + writePosition, numberOfUtf8CharsInString); - Debug.Assert(bytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); + var utf8EncodingBytesWritten = Utf8Encoding.GetBytes(strPtr, value.Length, bufferPtr + bytesWritten, numberOfUtf8CharsInString); + Debug.Assert(utf8EncodingBytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); } } } #else - var bytesWritten = Utf8Encoding.GetBytes(value, buffer.AsSpan(writePosition)); - Debug.Assert(bytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); + var utf8EncodingBytesWritten = Utf8Encoding.GetBytes(value, buffer.Slice(bytesWritten)); + Debug.Assert(utf8EncodingBytesWritten == numberOfUtf8CharsInString, "bytesWritten did not match numberOfUtf8CharsInString"); #endif - writePosition += numberOfUtf8CharsInString; - return writePosition; + bytesWritten += numberOfUtf8CharsInString; + return bytesWritten; } internal static bool IncreaseBufferSize(ref byte[] buffer, OtlpSignalType otlpSignalType) diff --git a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs index 6c202b528e7..e8d82654724 100644 --- a/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/Implementation/Serializer/ProtobufSerializerTests.cs @@ -21,7 +21,7 @@ public void GetTagValue_ReturnsCorrectValue() public void WriteTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteTag(buffer, 0, 1, ProtobufWireType.VARINT); + int position = ProtobufSerializer.WriteTag(buffer.AsSpan(0), 1, ProtobufWireType.VARINT); Assert.Equal(1, position); Assert.Equal(8, buffer[0]); } @@ -30,7 +30,7 @@ public void WriteTag_WritesCorrectly() public void WriteLength_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteLength(buffer, 0, 300); + int position = ProtobufSerializer.WriteLength(buffer.AsSpan(0), 300); Assert.Equal(2, position); Assert.Equal(0xAC, buffer[0]); Assert.Equal(0x02, buffer[1]); @@ -40,7 +40,7 @@ public void WriteLength_WritesCorrectly() public void WriteBoolWithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteBoolWithTag(buffer, 0, 1, true); + int position = ProtobufSerializer.WriteBoolWithTag(buffer.AsSpan(0), 1, true); Assert.Equal(2, position); Assert.Equal(8, buffer[0]); Assert.Equal(1, buffer[1]); @@ -50,7 +50,7 @@ public void WriteBoolWithTag_WritesCorrectly() public void WriteFixed32WithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteFixed32WithTag(buffer, 0, 1, 0x12345678); + int position = ProtobufSerializer.WriteFixed32WithTag(buffer.AsSpan(0), 1, 0x12345678); Assert.Equal(5, position); Assert.Equal(13, buffer[0]); Assert.Equal(0x78, buffer[1]); @@ -63,7 +63,7 @@ public void WriteFixed32WithTag_WritesCorrectly() public void WriteFixed64WithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteFixed64WithTag(buffer, 0, 1, 0x123456789ABCDEF0); + int position = ProtobufSerializer.WriteFixed64WithTag(buffer.AsSpan(0), 1, 0x123456789ABCDEF0); Assert.Equal(9, position); Assert.Equal(9, buffer[0]); // Tag Assert.Equal(0xF0, buffer[1]); @@ -80,7 +80,7 @@ public void WriteFixed64WithTag_WritesCorrectly() public void WriteStringWithTag_WritesCorrectly() { byte[] buffer = new byte[20]; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, "Hello"); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, "Hello"); Assert.Equal(7, position); Assert.Equal(10, buffer[0]); Assert.Equal(5, buffer[1]); @@ -111,7 +111,7 @@ public void WriteReservedLength_WritesCorrectly(int length, byte[] expectedBytes } #endif byte[] buffer = new byte[10]; - ProtobufSerializer.WriteReservedLength(buffer, 0, length); + ProtobufSerializer.WriteReservedLength(buffer.AsSpan(), length); for (int i = 0; i < expectedBytes.Length; i++) { @@ -123,7 +123,7 @@ public void WriteReservedLength_WritesCorrectly(int length, byte[] expectedBytes public void WriteTagAndLength_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteTagAndLength(buffer, 0, 300, 1, ProtobufWireType.LEN); + int position = ProtobufSerializer.WriteTagAndLength(buffer.AsSpan(0), 300, 1, ProtobufWireType.LEN); Assert.Equal(3, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(0xAC, buffer[1]); // Length (300 in varint encoding) @@ -134,7 +134,7 @@ public void WriteTagAndLength_WritesCorrectly() public void WriteEnumWithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteEnumWithTag(buffer, 0, 1, 5); + int position = ProtobufSerializer.WriteEnumWithTag(buffer.AsSpan(0), 1, 5); Assert.Equal(2, position); Assert.Equal(8, buffer[0]); // Tag Assert.Equal(5, buffer[1]); // Enum value @@ -144,7 +144,7 @@ public void WriteEnumWithTag_WritesCorrectly() public void WriteVarInt64_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteVarInt64(buffer, 0, 300); + int position = ProtobufSerializer.WriteVarInt64(buffer.AsSpan(0), 300); Assert.Equal(2, position); Assert.Equal(0xAC, buffer[0]); Assert.Equal(0x02, buffer[1]); @@ -154,7 +154,7 @@ public void WriteVarInt64_WritesCorrectly() public void WriteInt64WithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteInt64WithTag(buffer, 0, 1, 300); + int position = ProtobufSerializer.WriteInt64WithTag(buffer.AsSpan(0), 1, 300); Assert.Equal(3, position); Assert.Equal(8, buffer[0]); // Tag Assert.Equal(0xAC, buffer[1]); @@ -165,7 +165,7 @@ public void WriteInt64WithTag_WritesCorrectly() public void WriteDoubleWithTag_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteDoubleWithTag(buffer, 0, 1, 123.456); + int position = ProtobufSerializer.WriteDoubleWithTag(buffer.AsSpan(0), 1, 123.456); Assert.Equal(9, position); Assert.Equal(9, buffer[0]); // Tag @@ -184,14 +184,14 @@ public void WriteDoubleWithTag_WritesCorrectly() public void WriteSignedInt32_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteSInt32WithTag(buffer, 0, 1, 300); + int position = ProtobufSerializer.WriteSInt32WithTag(buffer.AsSpan(0), 1, 300); Assert.Equal(3, position); Assert.Equal(8, buffer[0]); // Tag Assert.Equal(0xD8, buffer[1]); Assert.Equal(0x04, buffer[2]); buffer = new byte[10]; - position = ProtobufSerializer.WriteSInt32WithTag(buffer, 0, 1, -300); + position = ProtobufSerializer.WriteSInt32WithTag(buffer.AsSpan(0), 1, -300); Assert.Equal(3, position); Assert.Equal(8, buffer[0]); // Tag Assert.Equal(0xD7, buffer[1]); @@ -202,7 +202,7 @@ public void WriteSignedInt32_WritesCorrectly() public void WriteVarInt32_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteVarInt32(buffer, 0, 300); + int position = ProtobufSerializer.WriteVarInt32(buffer.AsSpan(0), 300); Assert.Equal(2, position); Assert.Equal(0xAC, buffer[0]); Assert.Equal(0x02, buffer[1]); @@ -212,7 +212,7 @@ public void WriteVarInt32_WritesCorrectly() public void WriteVarInt32_MaxValue_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteVarInt32(buffer, 0, uint.MaxValue); + int position = ProtobufSerializer.WriteVarInt32(buffer.AsSpan(0), uint.MaxValue); Assert.Equal(5, position); Assert.Equal(0xFF, buffer[0]); Assert.Equal(0xFF, buffer[1]); @@ -225,7 +225,7 @@ public void WriteVarInt32_MaxValue_WritesCorrectly() public void WriteVarInt64_MaxValue_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteVarInt64(buffer, 0, ulong.MaxValue); + int position = ProtobufSerializer.WriteVarInt64(buffer.AsSpan(0), ulong.MaxValue); Assert.Equal(10, position); for (int i = 0; i < 9; i++) { @@ -239,7 +239,7 @@ public void WriteVarInt64_MaxValue_WritesCorrectly() public void WriteStringWithTag_EmptyString_WritesCorrectly() { byte[] buffer = new byte[10]; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, string.Empty); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, string.Empty); Assert.Equal(2, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(0, buffer[1]); // Length @@ -249,7 +249,7 @@ public void WriteStringWithTag_EmptyString_WritesCorrectly() public void WriteStringWithTag_ASCIIString_WritesCorrectly() { byte[] buffer = new byte[20]; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, "Hello"); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, "Hello"); Assert.Equal(7, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(5, buffer[1]); // Length @@ -265,7 +265,7 @@ public void WriteStringWithTag_UnicodeString_WritesCorrectly() { byte[] buffer = new byte[20]; string unicodeString = "\u3053\u3093\u306b\u3061\u306f"; // "Hello" in Japanese - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, unicodeString); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, unicodeString); Assert.Equal(17, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(15, buffer[1]); // Length (3 bytes per character in UTF-8) @@ -281,7 +281,7 @@ public void WriteStringWithTag_LongString_WritesCorrectly() { string longString = new string('a', 1000); byte[] buffer = new byte[1100]; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, longString); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, longString); Assert.Equal(1003, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(0xE8, buffer[1]); // Length (1000 in varint encoding) @@ -298,7 +298,7 @@ public void WriteStringWithTag_MixedEncodingString_WritesCorrectly() { byte[] buffer = new byte[30]; string mixedString = "Hello\u4e16\u754c"; // "Hello World" with "World" in Chinese - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, mixedString); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, mixedString); Assert.Equal(13, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(11, buffer[1]); // Length (5 for "Hello" + 6 for Chinese "World" in UTF-8) @@ -314,7 +314,7 @@ public void WriteStringWithTag_StringWithSpecialCharacters_WritesCorrectly() { byte[] buffer = new byte[30]; string specialString = "Hello\n\t\"World\""; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, specialString); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, specialString); Assert.Equal(16, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(14, buffer[1]); // Length @@ -330,7 +330,7 @@ public void WriteStringWithTag_StringWithNullCharacters_WritesCorrectly() { byte[] buffer = new byte[20]; string stringWithNull = "Hello\0World"; - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, stringWithNull); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, stringWithNull); Assert.Equal(13, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(11, buffer[1]); // Length @@ -346,7 +346,7 @@ public void WriteStringWithTag_SurrogatePairs_WritesCorrectly() { byte[] buffer = new byte[20]; string surrogatePairString = "\uD83D\uDCD6"; // Books emoji - int position = ProtobufSerializer.WriteStringWithTag(buffer, 0, 1, surrogatePairString); + int position = ProtobufSerializer.WriteStringWithTag(buffer.AsSpan(0), 1, surrogatePairString); Assert.Equal(6, position); Assert.Equal(10, buffer[0]); // Tag Assert.Equal(4, buffer[1]); // Length (4 bytes for the surrogate pair in UTF-8)