549 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			549 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package cbor
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"io"
 | 
						|
	"math"
 | 
						|
	"strconv"
 | 
						|
	"time"
 | 
						|
	"unicode/utf8"
 | 
						|
)
 | 
						|
 | 
						|
var decodeTimeZone *time.Location
 | 
						|
 | 
						|
const hexTable = "0123456789abcdef"
 | 
						|
 | 
						|
func decodeIntAdditonalType(src []byte, minor byte) (int64, uint, error) {
 | 
						|
	val := int64(0)
 | 
						|
	bytesRead := 0
 | 
						|
	if minor <= 23 {
 | 
						|
		val = int64(minor)
 | 
						|
		bytesRead = 0
 | 
						|
	} else {
 | 
						|
		switch minor {
 | 
						|
		case additionalTypeIntUint8:
 | 
						|
			bytesRead = 1
 | 
						|
		case additionalTypeIntUint16:
 | 
						|
			bytesRead = 2
 | 
						|
		case additionalTypeIntUint32:
 | 
						|
			bytesRead = 4
 | 
						|
		case additionalTypeIntUint64:
 | 
						|
			bytesRead = 8
 | 
						|
		default:
 | 
						|
			return 0, 0, fmt.Errorf("Invalid Additional Type: %d in decodeInteger (expected <28)", minor)
 | 
						|
		}
 | 
						|
		for i := 0; i < bytesRead; i++ {
 | 
						|
			val = val * 256
 | 
						|
			val += int64(src[i])
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return val, uint(bytesRead), nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeInteger(src []byte) (int64, uint, error) {
 | 
						|
	major := src[0] & maskOutAdditionalType
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeUnsignedInt && major != majorTypeNegativeInt {
 | 
						|
		return 0, 0, fmt.Errorf("Major type is: %d in decodeInteger!! (expected 0 or 1)", major)
 | 
						|
	}
 | 
						|
	val, bytesRead, err := decodeIntAdditonalType(src[1:], minor)
 | 
						|
	if err != nil {
 | 
						|
		return 0, 0, err
 | 
						|
	}
 | 
						|
	if major == 0 {
 | 
						|
		return val, 1 + bytesRead, nil
 | 
						|
	}
 | 
						|
	return (-1 - val), 1 + bytesRead, nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeFloat(src []byte) (float64, uint, error) {
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeSimpleAndFloat {
 | 
						|
		return 0, 0, fmt.Errorf("Incorrect Major type is: %d in decodeFloat", major)
 | 
						|
	}
 | 
						|
 | 
						|
	switch minor {
 | 
						|
	case additionalTypeFloat16:
 | 
						|
		return 0, 0, fmt.Errorf("float16 is not suppported in decodeFloat")
 | 
						|
	case additionalTypeFloat32:
 | 
						|
		switch string(src[1:5]) {
 | 
						|
		case float32Nan:
 | 
						|
			return math.NaN(), 5, nil
 | 
						|
		case float32PosInfinity:
 | 
						|
			return math.Inf(0), 5, nil
 | 
						|
		case float32NegInfinity:
 | 
						|
			return math.Inf(-1), 5, nil
 | 
						|
		}
 | 
						|
		n := uint32(0)
 | 
						|
		for i := 0; i < 4; i++ {
 | 
						|
			n = n * 256
 | 
						|
			n += uint32(src[i+1])
 | 
						|
		}
 | 
						|
		val := math.Float32frombits(n)
 | 
						|
		return float64(val), 5, nil
 | 
						|
	case additionalTypeFloat64:
 | 
						|
		switch string(src[1:9]) {
 | 
						|
		case float64Nan:
 | 
						|
			return math.NaN(), 9, nil
 | 
						|
		case float64PosInfinity:
 | 
						|
			return math.Inf(0), 9, nil
 | 
						|
		case float64NegInfinity:
 | 
						|
			return math.Inf(-1), 9, nil
 | 
						|
		}
 | 
						|
		n := uint64(0)
 | 
						|
		for i := 0; i < 8; i++ {
 | 
						|
			n = n * 256
 | 
						|
			n += uint64(src[i+1])
 | 
						|
		}
 | 
						|
		val := math.Float64frombits(n)
 | 
						|
		return val, 9, nil
 | 
						|
	}
 | 
						|
	return 0, 0, fmt.Errorf("Invalid Additional Type: %d in decodeFloat", minor)
 | 
						|
}
 | 
						|
 | 
						|
func decodeStringComplex(dst []byte, s string, pos uint) []byte {
 | 
						|
	i := int(pos)
 | 
						|
	const hex = "0123456789abcdef"
 | 
						|
	start := 0
 | 
						|
 | 
						|
	for i < len(s) {
 | 
						|
		b := s[i]
 | 
						|
		if b >= utf8.RuneSelf {
 | 
						|
			r, size := utf8.DecodeRuneInString(s[i:])
 | 
						|
			if r == utf8.RuneError && size == 1 {
 | 
						|
				// In case of error, first append previous simple characters to
 | 
						|
				// the byte slice if any and append a replacement character code
 | 
						|
				// in place of the invalid sequence.
 | 
						|
				if start < i {
 | 
						|
					dst = append(dst, s[start:i]...)
 | 
						|
				}
 | 
						|
				dst = append(dst, `\ufffd`...)
 | 
						|
				i += size
 | 
						|
				start = i
 | 
						|
				continue
 | 
						|
			}
 | 
						|
			i += size
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		if b >= 0x20 && b <= 0x7e && b != '\\' && b != '"' {
 | 
						|
			i++
 | 
						|
			continue
 | 
						|
		}
 | 
						|
		// We encountered a character that needs to be encoded.
 | 
						|
		// Let's append the previous simple characters to the byte slice
 | 
						|
		// and switch our operation to read and encode the remainder
 | 
						|
		// characters byte-by-byte.
 | 
						|
		if start < i {
 | 
						|
			dst = append(dst, s[start:i]...)
 | 
						|
		}
 | 
						|
		switch b {
 | 
						|
		case '"', '\\':
 | 
						|
			dst = append(dst, '\\', b)
 | 
						|
		case '\b':
 | 
						|
			dst = append(dst, '\\', 'b')
 | 
						|
		case '\f':
 | 
						|
			dst = append(dst, '\\', 'f')
 | 
						|
		case '\n':
 | 
						|
			dst = append(dst, '\\', 'n')
 | 
						|
		case '\r':
 | 
						|
			dst = append(dst, '\\', 'r')
 | 
						|
		case '\t':
 | 
						|
			dst = append(dst, '\\', 't')
 | 
						|
		default:
 | 
						|
			dst = append(dst, '\\', 'u', '0', '0', hex[b>>4], hex[b&0xF])
 | 
						|
		}
 | 
						|
		i++
 | 
						|
		start = i
 | 
						|
	}
 | 
						|
	if start < len(s) {
 | 
						|
		dst = append(dst, s[start:]...)
 | 
						|
	}
 | 
						|
	return dst
 | 
						|
}
 | 
						|
 | 
						|
func decodeString(src []byte, noQuotes bool) ([]byte, uint, error) {
 | 
						|
	major := src[0] & maskOutAdditionalType
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeByteString {
 | 
						|
		return []byte{}, 0, fmt.Errorf("Major type is: %d in decodeString", major)
 | 
						|
	}
 | 
						|
	result := []byte{'"'}
 | 
						|
	if noQuotes {
 | 
						|
		result = []byte{}
 | 
						|
	}
 | 
						|
	length, bytesRead, err := decodeIntAdditonalType(src[1:], minor)
 | 
						|
	if err != nil {
 | 
						|
		return []byte{}, 0, err
 | 
						|
	}
 | 
						|
	bytesRead++
 | 
						|
	st := bytesRead
 | 
						|
	len := uint(length)
 | 
						|
	bytesRead += len
 | 
						|
 | 
						|
	result = append(result, src[st:st+len]...)
 | 
						|
	if noQuotes {
 | 
						|
		return result, bytesRead, nil
 | 
						|
	}
 | 
						|
	return append(result, '"'), bytesRead, nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeUTF8String(src []byte) ([]byte, uint, error) {
 | 
						|
	major := src[0] & maskOutAdditionalType
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeUtf8String {
 | 
						|
		return []byte{}, 0, fmt.Errorf("Major type is: %d in decodeUTF8String", major)
 | 
						|
	}
 | 
						|
	result := []byte{'"'}
 | 
						|
	length, bytesRead, err := decodeIntAdditonalType(src[1:], minor)
 | 
						|
	if err != nil {
 | 
						|
		return []byte{}, 0, err
 | 
						|
	}
 | 
						|
	bytesRead++
 | 
						|
	st := bytesRead
 | 
						|
	len := uint(length)
 | 
						|
	bytesRead += len
 | 
						|
 | 
						|
	for i := st; i < bytesRead; i++ {
 | 
						|
		// Check if the character needs encoding. Control characters, slashes,
 | 
						|
		// and the double quote need json encoding. Bytes above the ascii
 | 
						|
		// boundary needs utf8 encoding.
 | 
						|
		if src[i] < 0x20 || src[i] > 0x7e || src[i] == '\\' || src[i] == '"' {
 | 
						|
			// We encountered a character that needs to be encoded. Switch
 | 
						|
			// to complex version of the algorithm.
 | 
						|
			dst := []byte{'"'}
 | 
						|
			dst = decodeStringComplex(dst, string(src[st:st+len]), i-st)
 | 
						|
			return append(dst, '"'), bytesRead, nil
 | 
						|
		}
 | 
						|
	}
 | 
						|
	// The string has no need for encoding an therefore is directly
 | 
						|
	// appended to the byte slice.
 | 
						|
	result = append(result, src[st:st+len]...)
 | 
						|
	return append(result, '"'), bytesRead, nil
 | 
						|
}
 | 
						|
 | 
						|
func array2Json(src []byte, dst io.Writer) (uint, error) {
 | 
						|
	dst.Write([]byte{'['})
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeArray {
 | 
						|
		return 0, fmt.Errorf("Major type is: %d in array2Json", major)
 | 
						|
	}
 | 
						|
	len := 0
 | 
						|
	bytesRead := uint(0)
 | 
						|
	unSpecifiedCount := false
 | 
						|
	if minor == additionalTypeInfiniteCount {
 | 
						|
		unSpecifiedCount = true
 | 
						|
		bytesRead = 1
 | 
						|
	} else {
 | 
						|
		var length int64
 | 
						|
		var err error
 | 
						|
		length, bytesRead, err = decodeIntAdditonalType(src[1:], minor)
 | 
						|
		if err != nil {
 | 
						|
			fmt.Println("Error!!!")
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
		len = int(length)
 | 
						|
		bytesRead++
 | 
						|
	}
 | 
						|
	curPos := bytesRead
 | 
						|
	for i := 0; unSpecifiedCount || i < len; i++ {
 | 
						|
		bc, err := Cbor2JsonOneObject(src[curPos:], dst)
 | 
						|
		if err != nil {
 | 
						|
			if src[curPos] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
 | 
						|
				bytesRead++
 | 
						|
				break
 | 
						|
			}
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
		curPos += bc
 | 
						|
		bytesRead += bc
 | 
						|
		if unSpecifiedCount {
 | 
						|
			if src[curPos] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
 | 
						|
				bytesRead++
 | 
						|
				break
 | 
						|
			}
 | 
						|
			dst.Write([]byte{','})
 | 
						|
		} else if i+1 < len {
 | 
						|
			dst.Write([]byte{','})
 | 
						|
		}
 | 
						|
	}
 | 
						|
	dst.Write([]byte{']'})
 | 
						|
	return bytesRead, nil
 | 
						|
}
 | 
						|
 | 
						|
func map2Json(src []byte, dst io.Writer) (uint, error) {
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeMap {
 | 
						|
		return 0, fmt.Errorf("Major type is: %d in map2Json", major)
 | 
						|
	}
 | 
						|
	len := 0
 | 
						|
	bytesRead := uint(0)
 | 
						|
	unSpecifiedCount := false
 | 
						|
	if minor == additionalTypeInfiniteCount {
 | 
						|
		unSpecifiedCount = true
 | 
						|
		bytesRead = 1
 | 
						|
	} else {
 | 
						|
		var length int64
 | 
						|
		var err error
 | 
						|
		length, bytesRead, err = decodeIntAdditonalType(src[1:], minor)
 | 
						|
		if err != nil {
 | 
						|
			fmt.Println("Error!!!")
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
		len = int(length)
 | 
						|
		bytesRead++
 | 
						|
	}
 | 
						|
	if len%2 == 1 {
 | 
						|
		return 0, fmt.Errorf("Invalid Length of map %d - has to be even", len)
 | 
						|
	}
 | 
						|
	dst.Write([]byte{'{'})
 | 
						|
	curPos := bytesRead
 | 
						|
	for i := 0; unSpecifiedCount || i < len; i++ {
 | 
						|
		bc, err := Cbor2JsonOneObject(src[curPos:], dst)
 | 
						|
		if err != nil {
 | 
						|
			//We hit the BREAK
 | 
						|
			if src[curPos] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
 | 
						|
				bytesRead++
 | 
						|
				break
 | 
						|
			}
 | 
						|
			return 0, err
 | 
						|
		}
 | 
						|
		curPos += bc
 | 
						|
		bytesRead += bc
 | 
						|
		if i%2 == 0 {
 | 
						|
			//Even position values are keys
 | 
						|
			dst.Write([]byte{':'})
 | 
						|
		} else {
 | 
						|
			if unSpecifiedCount {
 | 
						|
				if src[curPos] == byte(majorTypeSimpleAndFloat|additionalTypeBreak) {
 | 
						|
					bytesRead++
 | 
						|
					break
 | 
						|
				}
 | 
						|
				dst.Write([]byte{','})
 | 
						|
			} else if i+1 < len {
 | 
						|
				dst.Write([]byte{','})
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
	dst.Write([]byte{'}'})
 | 
						|
	return bytesRead, nil
 | 
						|
}
 | 
						|
 | 
						|
func decodeTagData(src []byte) ([]byte, uint, error) {
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeTags {
 | 
						|
		return nil, 0, fmt.Errorf("Major type is: %d in decodeTagData", major)
 | 
						|
	}
 | 
						|
	if minor == additionalTypeTimestamp {
 | 
						|
		tsMajor := src[1] & maskOutAdditionalType
 | 
						|
		if tsMajor == majorTypeUnsignedInt || tsMajor == majorTypeNegativeInt {
 | 
						|
			n, bc, err := decodeInteger(src[1:])
 | 
						|
			if err != nil {
 | 
						|
				return []byte{}, 0, err
 | 
						|
			}
 | 
						|
			t := time.Unix(n, 0)
 | 
						|
			if decodeTimeZone != nil {
 | 
						|
				t = t.In(decodeTimeZone)
 | 
						|
			} else {
 | 
						|
				t = t.In(time.UTC)
 | 
						|
			}
 | 
						|
			tsb := []byte{}
 | 
						|
			tsb = append(tsb, '"')
 | 
						|
			tsb = t.AppendFormat(tsb, IntegerTimeFieldFormat)
 | 
						|
			tsb = append(tsb, '"')
 | 
						|
			return tsb, 1 + bc, nil
 | 
						|
		} else if tsMajor == majorTypeSimpleAndFloat {
 | 
						|
			n, bc, err := decodeFloat(src[1:])
 | 
						|
			if err != nil {
 | 
						|
				return []byte{}, 0, err
 | 
						|
			}
 | 
						|
			secs := int64(n)
 | 
						|
			n -= float64(secs)
 | 
						|
			n *= float64(1e9)
 | 
						|
			t := time.Unix(secs, int64(n))
 | 
						|
			if decodeTimeZone != nil {
 | 
						|
				t = t.In(decodeTimeZone)
 | 
						|
			} else {
 | 
						|
				t = t.In(time.UTC)
 | 
						|
			}
 | 
						|
			tsb := []byte{}
 | 
						|
			tsb = append(tsb, '"')
 | 
						|
			tsb = t.AppendFormat(tsb, NanoTimeFieldFormat)
 | 
						|
			tsb = append(tsb, '"')
 | 
						|
			return tsb, 1 + bc, nil
 | 
						|
		} else {
 | 
						|
			return nil, 0, fmt.Errorf("TS format is neigther int nor float: %d", tsMajor)
 | 
						|
		}
 | 
						|
	} else if minor == additionalTypeEmbeddedJSON {
 | 
						|
		dataMajor := src[1] & maskOutAdditionalType
 | 
						|
		if dataMajor == majorTypeByteString {
 | 
						|
			emb, bc, err := decodeString(src[1:], true)
 | 
						|
			if err != nil {
 | 
						|
				return nil, 0, err
 | 
						|
			}
 | 
						|
			return emb, 1 + bc, nil
 | 
						|
		}
 | 
						|
		return nil, 0, fmt.Errorf("Unsupported embedded Type: %d in decodeEmbeddedJSON", dataMajor)
 | 
						|
	} else if minor == additionalTypeIntUint16 {
 | 
						|
            val,_,_ := decodeIntAdditonalType(src[1:], minor)
 | 
						|
            if uint16(val) == additionalTypeTagHexString {
 | 
						|
                emb, bc, _ := decodeString(src[3:], true)
 | 
						|
                dst := []byte{'"'}
 | 
						|
                for _, v := range emb {
 | 
						|
                        dst = append(dst, hexTable[v>>4], hexTable[v&0x0f])
 | 
						|
                }
 | 
						|
                return append(dst, '"'), 3+bc, nil
 | 
						|
            }
 | 
						|
        }
 | 
						|
	return nil, 0, fmt.Errorf("Unsupported Additional Type: %d in decodeTagData", minor)
 | 
						|
}
 | 
						|
 | 
						|
func decodeSimpleFloat(src []byte) ([]byte, uint, error) {
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	minor := src[0] & maskOutMajorType
 | 
						|
	if major != majorTypeSimpleAndFloat {
 | 
						|
		return nil, 0, fmt.Errorf("Major type is: %d in decodeSimpleFloat", major)
 | 
						|
	}
 | 
						|
	switch minor {
 | 
						|
	case additionalTypeBoolTrue:
 | 
						|
		return []byte("true"), 1, nil
 | 
						|
	case additionalTypeBoolFalse:
 | 
						|
		return []byte("false"), 1, nil
 | 
						|
	case additionalTypeNull:
 | 
						|
		return []byte("null"), 1, nil
 | 
						|
 | 
						|
	case additionalTypeFloat16:
 | 
						|
		fallthrough
 | 
						|
	case additionalTypeFloat32:
 | 
						|
		fallthrough
 | 
						|
	case additionalTypeFloat64:
 | 
						|
		v, bc, err := decodeFloat(src)
 | 
						|
		if err != nil {
 | 
						|
			return nil, 0, err
 | 
						|
		}
 | 
						|
		ba := []byte{}
 | 
						|
		switch {
 | 
						|
		case math.IsNaN(v):
 | 
						|
			return []byte("\"NaN\""), bc, nil
 | 
						|
		case math.IsInf(v, 1):
 | 
						|
			return []byte("\"+Inf\""), bc, nil
 | 
						|
		case math.IsInf(v, -1):
 | 
						|
			return []byte("\"-Inf\""), bc, nil
 | 
						|
		}
 | 
						|
		if bc == 5 {
 | 
						|
			ba = strconv.AppendFloat(ba, v, 'f', -1, 32)
 | 
						|
		} else {
 | 
						|
			ba = strconv.AppendFloat(ba, v, 'f', -1, 64)
 | 
						|
		}
 | 
						|
		return ba, bc, nil
 | 
						|
	default:
 | 
						|
		return nil, 0, fmt.Errorf("Invalid Additional Type: %d in decodeSimpleFloat", minor)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// Cbor2JsonOneObject takes in byte array and decodes ONE CBOR Object
 | 
						|
// usually a MAP. Use this when only ONE CBOR object needs decoding.
 | 
						|
// Decoded string is written to the dst.
 | 
						|
// Returns the bytes decoded and if any error was encountered.
 | 
						|
func Cbor2JsonOneObject(src []byte, dst io.Writer) (uint, error) {
 | 
						|
	var err error
 | 
						|
	major := (src[0] & maskOutAdditionalType)
 | 
						|
	bc := uint(0)
 | 
						|
	var s []byte
 | 
						|
	switch major {
 | 
						|
	case majorTypeUnsignedInt:
 | 
						|
		fallthrough
 | 
						|
	case majorTypeNegativeInt:
 | 
						|
		var n int64
 | 
						|
		n, bc, err = decodeInteger(src)
 | 
						|
		dst.Write([]byte(strconv.Itoa(int(n))))
 | 
						|
 | 
						|
	case majorTypeByteString:
 | 
						|
		s, bc, err = decodeString(src, false)
 | 
						|
		dst.Write(s)
 | 
						|
 | 
						|
	case majorTypeUtf8String:
 | 
						|
		s, bc, err = decodeUTF8String(src)
 | 
						|
		dst.Write(s)
 | 
						|
 | 
						|
	case majorTypeArray:
 | 
						|
		bc, err = array2Json(src, dst)
 | 
						|
 | 
						|
	case majorTypeMap:
 | 
						|
		bc, err = map2Json(src, dst)
 | 
						|
 | 
						|
	case majorTypeTags:
 | 
						|
		s, bc, err = decodeTagData(src)
 | 
						|
		dst.Write(s)
 | 
						|
 | 
						|
	case majorTypeSimpleAndFloat:
 | 
						|
		s, bc, err = decodeSimpleFloat(src)
 | 
						|
		dst.Write(s)
 | 
						|
	}
 | 
						|
	return bc, err
 | 
						|
}
 | 
						|
 | 
						|
// Cbor2JsonManyObjects decodes all the CBOR Objects present in the
 | 
						|
// source byte array. It keeps on decoding until it runs out of bytes.
 | 
						|
// Decoded string is written to the dst. At the end of every CBOR Object
 | 
						|
// newline is written to the output stream.
 | 
						|
// Returns the number of bytes decoded and if any error was encountered.
 | 
						|
func Cbor2JsonManyObjects(src []byte, dst io.Writer) (uint, error) {
 | 
						|
	curPos := uint(0)
 | 
						|
	totalBytes := uint(len(src))
 | 
						|
	for curPos < totalBytes {
 | 
						|
		bc, err := Cbor2JsonOneObject(src[curPos:], dst)
 | 
						|
		if err != nil {
 | 
						|
			return curPos, err
 | 
						|
		}
 | 
						|
		dst.Write([]byte("\n"))
 | 
						|
		curPos += bc
 | 
						|
	}
 | 
						|
	return curPos, nil
 | 
						|
}
 | 
						|
 | 
						|
// Detect if the bytes to be printed is Binary or not.
 | 
						|
func binaryFmt(p []byte) bool {
 | 
						|
	if len(p) > 0 && p[0] > 0x7F {
 | 
						|
		return true
 | 
						|
	}
 | 
						|
	return false
 | 
						|
}
 | 
						|
 | 
						|
// DecodeIfBinaryToString converts a binary formatted log msg to a
 | 
						|
// JSON formatted String Log message - suitable for printing to Console/Syslog.
 | 
						|
func DecodeIfBinaryToString(in []byte) string {
 | 
						|
	if binaryFmt(in) {
 | 
						|
		var b bytes.Buffer
 | 
						|
		Cbor2JsonManyObjects(in, &b)
 | 
						|
		return b.String()
 | 
						|
	}
 | 
						|
	return string(in)
 | 
						|
}
 | 
						|
 | 
						|
// DecodeObjectToStr checks if the input is a binary format, if so,
 | 
						|
// it will decode a single Object and return the decoded string.
 | 
						|
func DecodeObjectToStr(in []byte) string {
 | 
						|
	if binaryFmt(in) {
 | 
						|
		var b bytes.Buffer
 | 
						|
		Cbor2JsonOneObject(in, &b)
 | 
						|
		return b.String()
 | 
						|
	}
 | 
						|
	return string(in)
 | 
						|
}
 | 
						|
 | 
						|
// DecodeIfBinaryToBytes checks if the input is a binary format, if so,
 | 
						|
// it will decode all Objects and return the decoded string as byte array.
 | 
						|
func DecodeIfBinaryToBytes(in []byte) []byte {
 | 
						|
	if binaryFmt(in) {
 | 
						|
		var b bytes.Buffer
 | 
						|
		Cbor2JsonManyObjects(in, &b)
 | 
						|
		return b.Bytes()
 | 
						|
	}
 | 
						|
	return in
 | 
						|
}
 |