Rename ByteSliceMode to ByteSliceLaterFormatMode

Also renamed related options to be consistent.
This commit is contained in:
Faye Amacker 2024-06-09 21:16:42 -05:00
parent ed38331613
commit d1b239987b
5 changed files with 125 additions and 119 deletions

View File

@ -4922,7 +4922,7 @@ func TestDecOptions(t *testing.T) {
NaN: NaNDecodeForbidden,
Inf: InfDecodeForbidden,
ByteStringToTime: ByteStringToTimeAllowed,
ByteStringExpectedFormat: ByteSliceToByteStringWithExpectedConversionToBase64,
ByteStringExpectedFormat: ByteStringExpectedBase64URL,
BignumTag: BignumTagForbidden,
BinaryUnmarshaler: BinaryUnmarshalerNone,
}

174
encode.go
View File

@ -403,44 +403,46 @@ func (fnm FieldNameMode) valid() bool {
return fnm >= 0 && fnm < maxFieldNameMode
}
// ByteSliceMode specifies how to encode slices of bytes.
type ByteSliceMode int
// ByteSliceLaterFormatMode specifies which later format conversion hint (CBOR tag 21-23)
// to include (if any) when encoding Go byte slice to CBOR byte string. The encoder will
// always encode unmodified bytes from the byte slice and just wrap it within
// CBOR tag 21, 22, or 23 if specified.
// See "Expected Later Encoding for CBOR-to-JSON Converters" in RFC 8949 Section 3.4.5.2.
type ByteSliceLaterFormatMode int
const (
// ByteSliceToByteString encodes slices of bytes to CBOR byte string (major type 2).
ByteSliceToByteString = iota
// ByteSliceLaterFormatNone encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
// without adding CBOR tag 21, 22, or 23.
ByteSliceLaterFormatNone ByteSliceLaterFormatMode = iota
// ByteSliceToByteStringWithExpectedConversionToBase64URL encodes slices of bytes to CBOR
// byte string (major type 2) inside tag 21 (expected conversion to base64url encoding, see
// RFC 8949 Section 3.4.5.2).
ByteSliceToByteStringWithExpectedConversionToBase64URL
// ByteSliceLaterFormatBase64URL encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
// inside CBOR tag 21 (expected later conversion to base64url encoding, see RFC 8949 Section 3.4.5.2).
ByteSliceLaterFormatBase64URL
// ByteSliceToByteStringWithExpectedConversionToBase64 encodes slices of bytes to CBOR byte
// string (major type 2) inside tag 22 (expected conversion to base64 encoding, see RFC 8949
// Section 3.4.5.2).
ByteSliceToByteStringWithExpectedConversionToBase64
// ByteSliceLaterFormatBase64 encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
// inside CBOR tag 22 (expected later conversion to base64 encoding, see RFC 8949 Section 3.4.5.2).
ByteSliceLaterFormatBase64
// ByteSliceToByteStringWithExpectedConversionToBase16 encodes slices of bytes to CBOR byte
// string (major type 2) inside tag 23 (expected conversion to base16 encoding, see RFC 8949
// Section 3.4.5.2).
ByteSliceToByteStringWithExpectedConversionToBase16
// ByteSliceLaterFormatBase16 encodes unmodified bytes from Go byte slice to CBOR byte string (major type 2)
// inside CBOR tag 23 (expected later conversion to base16 encoding, see RFC 8949 Section 3.4.5.2).
ByteSliceLaterFormatBase16
)
func (bsm ByteSliceMode) encodingTag() (uint64, error) {
switch bsm {
case ByteSliceToByteString:
func (bsefm ByteSliceLaterFormatMode) encodingTag() (uint64, error) {
switch bsefm {
case ByteSliceLaterFormatNone:
return 0, nil
case ByteSliceToByteStringWithExpectedConversionToBase64URL:
case ByteSliceLaterFormatBase64URL:
return tagNumExpectedLaterEncodingBase64URL, nil
case ByteSliceToByteStringWithExpectedConversionToBase64:
case ByteSliceLaterFormatBase64:
return tagNumExpectedLaterEncodingBase64, nil
case ByteSliceToByteStringWithExpectedConversionToBase16:
case ByteSliceLaterFormatBase16:
return tagNumExpectedLaterEncodingBase16, nil
}
return 0, errors.New("cbor: invalid ByteSlice " + strconv.Itoa(int(bsm)))
return 0, errors.New("cbor: invalid ByteSliceLaterFormat " + strconv.Itoa(int(bsefm)))
}
// ByteArrayMode specifies how to encode byte arrays.
@ -449,7 +451,7 @@ type ByteArrayMode int
const (
// ByteArrayToByteSlice encodes byte arrays the same way that a byte slice with identical
// length and contents is encoded.
ByteArrayToByteSlice = iota
ByteArrayToByteSlice ByteArrayMode = iota
// ByteArrayToArray encodes byte arrays to the CBOR array type with one unsigned integer
// item for each byte in the array.
@ -524,8 +526,12 @@ type EncOptions struct {
// FieldName specifies the CBOR type to use when encoding struct field names.
FieldName FieldNameMode
// ByteSlice specifies how to encode byte slices.
ByteSlice ByteSliceMode
// ByteSliceLaterFormat specifies which later format conversion hint (CBOR tag 21-23)
// to include (if any) when encoding Go byte slice to CBOR byte string. The encoder will
// always encode unmodified bytes from the byte slice and just wrap it within
// CBOR tag 21, 22, or 23 if specified.
// See "Expected Later Encoding for CBOR-to-JSON Converters" in RFC 8949 Section 3.4.5.2.
ByteSliceLaterFormat ByteSliceLaterFormatMode
// ByteArray specifies how to encode byte arrays.
ByteArray ByteArrayMode
@ -732,7 +738,7 @@ func (opts EncOptions) encMode() (*encMode, error) { //nolint:gocritic // ignore
if !opts.FieldName.valid() {
return nil, errors.New("cbor: invalid FieldName " + strconv.Itoa(int(opts.FieldName)))
}
byteSliceEncodingTag, err := opts.ByteSlice.encodingTag()
byteSliceLaterEncodingTag, err := opts.ByteSliceLaterFormat.encodingTag()
if err != nil {
return nil, err
}
@ -743,24 +749,24 @@ func (opts EncOptions) encMode() (*encMode, error) { //nolint:gocritic // ignore
return nil, errors.New("cbor: invalid BinaryMarshaler " + strconv.Itoa(int(opts.BinaryMarshaler)))
}
em := encMode{
sort: opts.Sort,
shortestFloat: opts.ShortestFloat,
nanConvert: opts.NaNConvert,
infConvert: opts.InfConvert,
bigIntConvert: opts.BigIntConvert,
time: opts.Time,
timeTag: opts.TimeTag,
indefLength: opts.IndefLength,
nilContainers: opts.NilContainers,
tagsMd: opts.TagsMd,
omitEmpty: opts.OmitEmpty,
stringType: opts.String,
stringMajorType: stringMajorType,
fieldName: opts.FieldName,
byteSlice: opts.ByteSlice,
byteSliceEncodingTag: byteSliceEncodingTag,
byteArray: opts.ByteArray,
binaryMarshaler: opts.BinaryMarshaler,
sort: opts.Sort,
shortestFloat: opts.ShortestFloat,
nanConvert: opts.NaNConvert,
infConvert: opts.InfConvert,
bigIntConvert: opts.BigIntConvert,
time: opts.Time,
timeTag: opts.TimeTag,
indefLength: opts.IndefLength,
nilContainers: opts.NilContainers,
tagsMd: opts.TagsMd,
omitEmpty: opts.OmitEmpty,
stringType: opts.String,
stringMajorType: stringMajorType,
fieldName: opts.FieldName,
byteSliceLaterFormat: opts.ByteSliceLaterFormat,
byteSliceLaterEncodingTag: byteSliceLaterEncodingTag,
byteArray: opts.ByteArray,
binaryMarshaler: opts.BinaryMarshaler,
}
return &em, nil
}
@ -787,25 +793,25 @@ type UserBufferEncMode interface {
}
type encMode struct {
tags tagProvider
sort SortMode
shortestFloat ShortestFloatMode
nanConvert NaNConvertMode
infConvert InfConvertMode
bigIntConvert BigIntConvertMode
time TimeMode
timeTag EncTagMode
indefLength IndefLengthMode
nilContainers NilContainersMode
tagsMd TagsMode
omitEmpty OmitEmptyMode
stringType StringMode
stringMajorType cborType
fieldName FieldNameMode
byteSlice ByteSliceMode
byteSliceEncodingTag uint64
byteArray ByteArrayMode
binaryMarshaler BinaryMarshalerMode
tags tagProvider
sort SortMode
shortestFloat ShortestFloatMode
nanConvert NaNConvertMode
infConvert InfConvertMode
bigIntConvert BigIntConvertMode
time TimeMode
timeTag EncTagMode
indefLength IndefLengthMode
nilContainers NilContainersMode
tagsMd TagsMode
omitEmpty OmitEmptyMode
stringType StringMode
stringMajorType cborType
fieldName FieldNameMode
byteSliceLaterFormat ByteSliceLaterFormatMode
byteSliceLaterEncodingTag uint64
byteArray ByteArrayMode
binaryMarshaler BinaryMarshalerMode
}
var defaultEncMode, _ = EncOptions{}.encMode()
@ -882,22 +888,22 @@ func getMarshalerDecMode(indefLength IndefLengthMode, tagsMd TagsMode) *decMode
// EncOptions returns user specified options used to create this EncMode.
func (em *encMode) EncOptions() EncOptions {
return EncOptions{
Sort: em.sort,
ShortestFloat: em.shortestFloat,
NaNConvert: em.nanConvert,
InfConvert: em.infConvert,
BigIntConvert: em.bigIntConvert,
Time: em.time,
TimeTag: em.timeTag,
IndefLength: em.indefLength,
NilContainers: em.nilContainers,
TagsMd: em.tagsMd,
OmitEmpty: em.omitEmpty,
String: em.stringType,
FieldName: em.fieldName,
ByteSlice: em.byteSlice,
ByteArray: em.byteArray,
BinaryMarshaler: em.binaryMarshaler,
Sort: em.sort,
ShortestFloat: em.shortestFloat,
NaNConvert: em.nanConvert,
InfConvert: em.infConvert,
BigIntConvert: em.bigIntConvert,
Time: em.time,
TimeTag: em.timeTag,
IndefLength: em.indefLength,
NilContainers: em.nilContainers,
TagsMd: em.tagsMd,
OmitEmpty: em.omitEmpty,
String: em.stringType,
FieldName: em.fieldName,
ByteSliceLaterFormat: em.byteSliceLaterFormat,
ByteArray: em.byteArray,
BinaryMarshaler: em.binaryMarshaler,
}
}
@ -1198,8 +1204,8 @@ func encodeByteString(e *bytes.Buffer, em *encMode, v reflect.Value) error {
e.Write(cborNil)
return nil
}
if vk == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && em.byteSliceEncodingTag != 0 {
encodeHead(e, byte(cborTypeTag), em.byteSliceEncodingTag)
if vk == reflect.Slice && v.Type().Elem().Kind() == reflect.Uint8 && em.byteSliceLaterEncodingTag != 0 {
encodeHead(e, byte(cborTypeTag), em.byteSliceLaterEncodingTag)
}
if b := em.encTagBytes(v.Type()); b != nil {
e.Write(b)
@ -1710,8 +1716,8 @@ func encodeTag(e *bytes.Buffer, em *encMode, v reflect.Value) error {
vem.stringType = StringToTextString
vem.stringMajorType = cborTypeTextString
case tagNumUnsignedBignum, tagNumNegativeBignum:
vem.byteSlice = ByteSliceToByteString
vem.byteSliceEncodingTag = 0
vem.byteSliceLaterFormat = ByteSliceLaterFormatNone
vem.byteSliceLaterEncodingTag = 0
}
// Marshal tag content

View File

@ -3764,22 +3764,22 @@ func TestEncOptionsTagsForbidden(t *testing.T) {
func TestEncOptions(t *testing.T) {
opts1 := EncOptions{
Sort: SortBytewiseLexical,
ShortestFloat: ShortestFloat16,
NaNConvert: NaNConvertPreserveSignal,
InfConvert: InfConvertNone,
BigIntConvert: BigIntConvertNone,
Time: TimeRFC3339Nano,
TimeTag: EncTagRequired,
IndefLength: IndefLengthForbidden,
NilContainers: NilContainerAsEmpty,
TagsMd: TagsAllowed,
OmitEmpty: OmitEmptyGoValue,
String: StringToByteString,
FieldName: FieldNameToByteString,
ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase16,
ByteArray: ByteArrayToArray,
BinaryMarshaler: BinaryMarshalerNone,
Sort: SortBytewiseLexical,
ShortestFloat: ShortestFloat16,
NaNConvert: NaNConvertPreserveSignal,
InfConvert: InfConvertNone,
BigIntConvert: BigIntConvertNone,
Time: TimeRFC3339Nano,
TimeTag: EncTagRequired,
IndefLength: IndefLengthForbidden,
NilContainers: NilContainerAsEmpty,
TagsMd: TagsAllowed,
OmitEmpty: OmitEmptyGoValue,
String: StringToByteString,
FieldName: FieldNameToByteString,
ByteSliceLaterFormat: ByteSliceLaterFormatBase16,
ByteArray: ByteArrayToArray,
BinaryMarshaler: BinaryMarshalerNone,
}
ov := reflect.ValueOf(opts1)
for i := 0; i < ov.NumField(); i++ {
@ -4519,7 +4519,7 @@ func TestSortModeFastShuffle(t *testing.T) {
}
}
func TestInvalidByteSlice(t *testing.T) {
func TestInvalidByteSliceExpectedFormat(t *testing.T) {
for _, tc := range []struct {
name string
opts EncOptions
@ -4527,13 +4527,13 @@ func TestInvalidByteSlice(t *testing.T) {
}{
{
name: "below range of valid modes",
opts: EncOptions{ByteSlice: -1},
wantErrorMsg: "cbor: invalid ByteSlice -1",
opts: EncOptions{ByteSliceLaterFormat: -1},
wantErrorMsg: "cbor: invalid ByteSliceLaterFormat -1",
},
{
name: "above range of valid modes",
opts: EncOptions{ByteSlice: 101},
wantErrorMsg: "cbor: invalid ByteSlice 101",
opts: EncOptions{ByteSliceLaterFormat: 101},
wantErrorMsg: "cbor: invalid ByteSliceLaterFormat 101",
},
} {
t.Run(tc.name, func(t *testing.T) {
@ -4641,53 +4641,53 @@ func TestMarshalByteSliceMode(t *testing.T) {
},
{
name: "byte slice marshals to byte string by with ByteSliceToByteString",
opts: EncOptions{ByteSlice: ByteSliceToByteString},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatNone},
in: []byte{0xbb},
expected: []byte{0x41, 0xbb},
},
{
name: "byte slice marshaled to byte string enclosed in base64url expected encoding tag",
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase64URL},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase64URL},
in: []byte{0xbb},
expected: []byte{0xd5, 0x41, 0xbb},
},
{
name: "byte slice marshaled to byte string enclosed in base64 expected encoding tag",
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase64},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase64},
in: []byte{0xbb},
expected: []byte{0xd6, 0x41, 0xbb},
},
{
name: "byte slice marshaled to byte string enclosed in base16 expected encoding tag",
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase16},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase16},
in: []byte{0xbb},
expected: []byte{0xd7, 0x41, 0xbb},
},
{
name: "user-registered tag numbers are encoded with no expected encoding tag",
tags: ts,
opts: EncOptions{ByteSlice: ByteSliceToByteString},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatNone},
in: namedByteSlice{0xbb},
expected: []byte{0xd8, 0xcc, 0x41, 0xbb},
},
{
name: "user-registered tag numbers are encoded after base64url expected encoding tag",
tags: ts,
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase64URL},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase64URL},
in: namedByteSlice{0xbb},
expected: []byte{0xd5, 0xd8, 0xcc, 0x41, 0xbb},
},
{
name: "user-registered tag numbers are encoded after base64 expected encoding tag",
tags: ts,
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase64},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase64},
in: namedByteSlice{0xbb},
expected: []byte{0xd6, 0xd8, 0xcc, 0x41, 0xbb},
},
{
name: "user-registered tag numbers are encoded after base16 expected encoding tag",
tags: ts,
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase16},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase16},
in: namedByteSlice{0xbb},
expected: []byte{0xd7, 0xd8, 0xcc, 0x41, 0xbb},
},

View File

@ -15,9 +15,9 @@ func TestStdlibJSONCompatibility(t *testing.T) {
// configurations to users.
enc, err := cbor.EncOptions{
ByteSlice: cbor.ByteSliceToByteStringWithExpectedConversionToBase64,
String: cbor.StringToByteString,
ByteArray: cbor.ByteArrayToArray,
ByteSliceLaterFormat: cbor.ByteSliceLaterFormatBase64,
String: cbor.StringToByteString,
ByteArray: cbor.ByteArrayToArray,
}.EncMode()
if err != nil {
t.Fatal(err)

View File

@ -1503,13 +1503,13 @@ func TestEncodeBuiltinTag(t *testing.T) {
{
name: "unsigned bignum content not enclosed in expected encoding tag",
tag: Tag{Number: tagNumUnsignedBignum, Content: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase16},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase16},
want: []byte{0xc2, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
{
name: "negative bignum content not enclosed in expected encoding tag",
tag: Tag{Number: tagNumNegativeBignum, Content: []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
opts: EncOptions{ByteSlice: ByteSliceToByteStringWithExpectedConversionToBase16},
opts: EncOptions{ByteSliceLaterFormat: ByteSliceLaterFormatBase16},
want: []byte{0xc3, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
},
{