Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rename ByteSliceMode to ByteSliceLaterFormatMode, etc #554

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Comment on lines -406 to +411
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helped. Thanks for adding more comments.


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
Comment on lines +811 to +812
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency, should byteSliceLaterEncodingTag be renamed to byteSliceLaterFormatTag?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Encoding tag makes more sense to me because it is about CBOR tag number to be encoding.

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
Loading