mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 12:18:16 +00:00 
			
		
		
		
	This library release makes a number of behaviors configurable in ways that are required for CBOR support in Kubernetes.
		
			
				
	
	
		
			183 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			183 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) Faye Amacker. All rights reserved.
 | 
						|
// Licensed under the MIT License. See LICENSE in the project root for license information.
 | 
						|
 | 
						|
package cbor
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"strconv"
 | 
						|
)
 | 
						|
 | 
						|
type cborType uint8
 | 
						|
 | 
						|
const (
 | 
						|
	cborTypePositiveInt cborType = 0x00
 | 
						|
	cborTypeNegativeInt cborType = 0x20
 | 
						|
	cborTypeByteString  cborType = 0x40
 | 
						|
	cborTypeTextString  cborType = 0x60
 | 
						|
	cborTypeArray       cborType = 0x80
 | 
						|
	cborTypeMap         cborType = 0xa0
 | 
						|
	cborTypeTag         cborType = 0xc0
 | 
						|
	cborTypePrimitives  cborType = 0xe0
 | 
						|
)
 | 
						|
 | 
						|
func (t cborType) String() string {
 | 
						|
	switch t {
 | 
						|
	case cborTypePositiveInt:
 | 
						|
		return "positive integer"
 | 
						|
	case cborTypeNegativeInt:
 | 
						|
		return "negative integer"
 | 
						|
	case cborTypeByteString:
 | 
						|
		return "byte string"
 | 
						|
	case cborTypeTextString:
 | 
						|
		return "UTF-8 text string"
 | 
						|
	case cborTypeArray:
 | 
						|
		return "array"
 | 
						|
	case cborTypeMap:
 | 
						|
		return "map"
 | 
						|
	case cborTypeTag:
 | 
						|
		return "tag"
 | 
						|
	case cborTypePrimitives:
 | 
						|
		return "primitives"
 | 
						|
	default:
 | 
						|
		return "Invalid type " + strconv.Itoa(int(t))
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
type additionalInformation uint8
 | 
						|
 | 
						|
const (
 | 
						|
	maxAdditionalInformationWithoutArgument = 23
 | 
						|
	additionalInformationWith1ByteArgument  = 24
 | 
						|
	additionalInformationWith2ByteArgument  = 25
 | 
						|
	additionalInformationWith4ByteArgument  = 26
 | 
						|
	additionalInformationWith8ByteArgument  = 27
 | 
						|
 | 
						|
	// For major type 7.
 | 
						|
	additionalInformationAsFalse     = 20
 | 
						|
	additionalInformationAsTrue      = 21
 | 
						|
	additionalInformationAsNull      = 22
 | 
						|
	additionalInformationAsUndefined = 23
 | 
						|
	additionalInformationAsFloat16   = 25
 | 
						|
	additionalInformationAsFloat32   = 26
 | 
						|
	additionalInformationAsFloat64   = 27
 | 
						|
 | 
						|
	// For major type 2, 3, 4, 5.
 | 
						|
	additionalInformationAsIndefiniteLengthFlag = 31
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	maxSimpleValueInAdditionalInformation = 23
 | 
						|
	minSimpleValueIn1ByteArgument         = 32
 | 
						|
)
 | 
						|
 | 
						|
func (ai additionalInformation) isIndefiniteLength() bool {
 | 
						|
	return ai == additionalInformationAsIndefiniteLengthFlag
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	// From RFC 8949 Section 3:
 | 
						|
	//   "The initial byte of each encoded data item contains both information about the major type
 | 
						|
	//   (the high-order 3 bits, described in Section 3.1) and additional information
 | 
						|
	//   (the low-order 5 bits)."
 | 
						|
 | 
						|
	// typeMask is used to extract major type in initial byte of encoded data item.
 | 
						|
	typeMask = 0xe0
 | 
						|
 | 
						|
	// additionalInformationMask is used to extract additional information in initial byte of encoded data item.
 | 
						|
	additionalInformationMask = 0x1f
 | 
						|
)
 | 
						|
 | 
						|
func getType(raw byte) cborType {
 | 
						|
	return cborType(raw & typeMask)
 | 
						|
}
 | 
						|
 | 
						|
func getAdditionalInformation(raw byte) byte {
 | 
						|
	return raw & additionalInformationMask
 | 
						|
}
 | 
						|
 | 
						|
func isBreakFlag(raw byte) bool {
 | 
						|
	return raw == cborBreakFlag
 | 
						|
}
 | 
						|
 | 
						|
func parseInitialByte(b byte) (t cborType, ai byte) {
 | 
						|
	return getType(b), getAdditionalInformation(b)
 | 
						|
}
 | 
						|
 | 
						|
const (
 | 
						|
	tagNumRFC3339Time                    = 0
 | 
						|
	tagNumEpochTime                      = 1
 | 
						|
	tagNumUnsignedBignum                 = 2
 | 
						|
	tagNumNegativeBignum                 = 3
 | 
						|
	tagNumExpectedLaterEncodingBase64URL = 21
 | 
						|
	tagNumExpectedLaterEncodingBase64    = 22
 | 
						|
	tagNumExpectedLaterEncodingBase16    = 23
 | 
						|
	tagNumSelfDescribedCBOR              = 55799
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	cborBreakFlag                          = byte(0xff)
 | 
						|
	cborByteStringWithIndefiniteLengthHead = byte(0x5f)
 | 
						|
	cborTextStringWithIndefiniteLengthHead = byte(0x7f)
 | 
						|
	cborArrayWithIndefiniteLengthHead      = byte(0x9f)
 | 
						|
	cborMapWithIndefiniteLengthHead        = byte(0xbf)
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	cborFalse            = []byte{0xf4}
 | 
						|
	cborTrue             = []byte{0xf5}
 | 
						|
	cborNil              = []byte{0xf6}
 | 
						|
	cborNaN              = []byte{0xf9, 0x7e, 0x00}
 | 
						|
	cborPositiveInfinity = []byte{0xf9, 0x7c, 0x00}
 | 
						|
	cborNegativeInfinity = []byte{0xf9, 0xfc, 0x00}
 | 
						|
)
 | 
						|
 | 
						|
// validBuiltinTag checks that supported built-in tag numbers are followed by expected content types.
 | 
						|
func validBuiltinTag(tagNum uint64, contentHead byte) error {
 | 
						|
	t := getType(contentHead)
 | 
						|
	switch tagNum {
 | 
						|
	case tagNumRFC3339Time:
 | 
						|
		// Tag content (date/time text string in RFC 3339 format) must be string type.
 | 
						|
		if t != cborTypeTextString {
 | 
						|
			return newInadmissibleTagContentTypeError(
 | 
						|
				tagNumRFC3339Time,
 | 
						|
				"text string",
 | 
						|
				t.String())
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
 | 
						|
	case tagNumEpochTime:
 | 
						|
		// Tag content (epoch date/time) must be uint, int, or float type.
 | 
						|
		if t != cborTypePositiveInt && t != cborTypeNegativeInt && (contentHead < 0xf9 || contentHead > 0xfb) {
 | 
						|
			return newInadmissibleTagContentTypeError(
 | 
						|
				tagNumEpochTime,
 | 
						|
				"integer or floating-point number",
 | 
						|
				t.String())
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
 | 
						|
	case tagNumUnsignedBignum, tagNumNegativeBignum:
 | 
						|
		// Tag content (bignum) must be byte type.
 | 
						|
		if t != cborTypeByteString {
 | 
						|
			return newInadmissibleTagContentTypeErrorf(
 | 
						|
				fmt.Sprintf(
 | 
						|
					"tag number %d or %d must be followed by byte string, got %s",
 | 
						|
					tagNumUnsignedBignum,
 | 
						|
					tagNumNegativeBignum,
 | 
						|
					t.String(),
 | 
						|
				))
 | 
						|
		}
 | 
						|
		return nil
 | 
						|
 | 
						|
	case tagNumExpectedLaterEncodingBase64URL, tagNumExpectedLaterEncodingBase64, tagNumExpectedLaterEncodingBase16:
 | 
						|
		// From RFC 8949 3.4.5.2:
 | 
						|
		//   The data item tagged can be a byte string or any other data item. In the latter
 | 
						|
		//   case, the tag applies to all of the byte string data items contained in the data
 | 
						|
		//   item, except for those contained in a nested data item tagged with an expected
 | 
						|
		//   conversion.
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 |