|
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- // Copyright 2017 Google LLC
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
-
- // Package tracecontext provides encoders and decoders for Stackdriver Trace contexts.
- package tracecontext
-
- import "encoding/binary"
-
- const (
- versionID = 0
- traceIDField = 0
- spanIDField = 1
- optsField = 2
-
- traceIDLen = 16
- spanIDLen = 8
- optsLen = 1
-
- // Len represents the length of trace context.
- Len = 1 + 1 + traceIDLen + 1 + spanIDLen + 1 + optsLen
- )
-
- // Encode encodes trace ID, span ID and options into dst. The number of bytes
- // written will be returned. If len(dst) isn't big enough to fit the trace context,
- // a negative number is returned.
- func Encode(dst []byte, traceID []byte, spanID uint64, opts byte) (n int) {
- if len(dst) < Len {
- return -1
- }
- var offset = 0
- putByte := func(b byte) { dst[offset] = b; offset++ }
- putUint64 := func(u uint64) { binary.LittleEndian.PutUint64(dst[offset:], u); offset += 8 }
-
- putByte(versionID)
- putByte(traceIDField)
- for _, b := range traceID {
- putByte(b)
- }
- putByte(spanIDField)
- putUint64(spanID)
- putByte(optsField)
- putByte(opts)
-
- return offset
- }
-
- // Decode decodes the src into a trace ID, span ID and options. If src doesn't
- // contain a valid trace context, ok = false is returned.
- func Decode(src []byte) (traceID []byte, spanID uint64, opts byte, ok bool) {
- if len(src) < Len {
- return traceID, spanID, 0, false
- }
- var offset = 0
- readByte := func() byte { b := src[offset]; offset++; return b }
- readUint64 := func() uint64 { v := binary.LittleEndian.Uint64(src[offset:]); offset += 8; return v }
-
- if readByte() != versionID {
- return traceID, spanID, 0, false
- }
- for offset < len(src) {
- switch readByte() {
- case traceIDField:
- traceID = src[offset : offset+traceIDLen]
- offset += traceIDLen
- case spanIDField:
- spanID = readUint64()
- case optsField:
- opts = readByte()
- }
- }
- return traceID, spanID, opts, true
- }
|