Skip to content

Commit

Permalink
Merge pull request #554 from fxamacker/fxamacker/rename-bytestringmode
Browse files Browse the repository at this point in the history
Rename ByteSliceMode to ByteSliceLaterFormatMode, etc
  • Loading branch information
fxamacker authored Jun 10, 2024
2 parents 8ac5347 + d1b2399 commit 878cfef
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 122 deletions.
2 changes: 1 addition & 1 deletion decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4922,7 +4922,7 @@ func TestDecOptions(t *testing.T) {
NaN: NaNDecodeForbidden,
Inf: InfDecodeForbidden,
ByteStringToTime: ByteStringToTimeAllowed,
ByteStringExpectedFormat: ByteSliceToByteStringWithExpectedConversionToBase64,
ByteStringExpectedFormat: ByteStringExpectedBase64URL,
BignumTag: BignumTagForbidden,
BinaryUnmarshaler: BinaryUnmarshalerNone,
}
Expand Down
180 changes: 93 additions & 87 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

// 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

// 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

// 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
// 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

// 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

// 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

// 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.
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand All @@ -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
}
Expand All @@ -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()
Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
58 changes: 29 additions & 29 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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++ {
Expand Down Expand Up @@ -4519,21 +4519,21 @@ func TestSortModeFastShuffle(t *testing.T) {
}
}

func TestInvalidByteSlice(t *testing.T) {
func TestInvalidByteSliceExpectedFormat(t *testing.T) {
for _, tc := range []struct {
name string
opts EncOptions
wantErrorMsg string
}{
{
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) {
Expand Down Expand Up @@ -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},
},
Expand Down
Loading

0 comments on commit 878cfef

Please sign in to comment.