bytestring.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (c) Faye Amacker. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. package cbor
  4. import (
  5. "errors"
  6. )
  7. // ByteString represents CBOR byte string (major type 2). ByteString can be used
  8. // when using a Go []byte is not possible or convenient. For example, Go doesn't
  9. // allow []byte as map key, so ByteString can be used to support data formats
  10. // having CBOR map with byte string keys. ByteString can also be used to
  11. // encode invalid UTF-8 string as CBOR byte string.
  12. // See DecOption.MapKeyByteStringMode for more details.
  13. type ByteString string
  14. // Bytes returns bytes representing ByteString.
  15. func (bs ByteString) Bytes() []byte {
  16. return []byte(bs)
  17. }
  18. // MarshalCBOR encodes ByteString as CBOR byte string (major type 2).
  19. func (bs ByteString) MarshalCBOR() ([]byte, error) {
  20. e := getEncodeBuffer()
  21. defer putEncodeBuffer(e)
  22. // Encode length
  23. encodeHead(e, byte(cborTypeByteString), uint64(len(bs)))
  24. // Encode data
  25. buf := make([]byte, e.Len()+len(bs))
  26. n := copy(buf, e.Bytes())
  27. copy(buf[n:], bs)
  28. return buf, nil
  29. }
  30. // UnmarshalCBOR decodes CBOR byte string (major type 2) to ByteString.
  31. // Decoding CBOR null and CBOR undefined sets ByteString to be empty.
  32. //
  33. // Deprecated: No longer used by this codec; kept for compatibility
  34. // with user apps that directly call this function.
  35. func (bs *ByteString) UnmarshalCBOR(data []byte) error {
  36. if bs == nil {
  37. return errors.New("cbor.ByteString: UnmarshalCBOR on nil pointer")
  38. }
  39. d := decoder{data: data, dm: defaultDecMode}
  40. // Check well-formedness of CBOR data item.
  41. // ByteString.UnmarshalCBOR() is exported, so
  42. // the codec needs to support same behavior for:
  43. // - Unmarshal(data, *ByteString)
  44. // - ByteString.UnmarshalCBOR(data)
  45. err := d.wellformed(false, false)
  46. if err != nil {
  47. return err
  48. }
  49. return bs.unmarshalCBOR(data)
  50. }
  51. // unmarshalCBOR decodes CBOR byte string (major type 2) to ByteString.
  52. // Decoding CBOR null and CBOR undefined sets ByteString to be empty.
  53. // This function assumes data is well-formed, and does not perform bounds checking.
  54. // This function is called by Unmarshal().
  55. func (bs *ByteString) unmarshalCBOR(data []byte) error {
  56. if bs == nil {
  57. return errors.New("cbor.ByteString: UnmarshalCBOR on nil pointer")
  58. }
  59. // Decoding CBOR null and CBOR undefined to ByteString resets data.
  60. // This behavior is similar to decoding CBOR null and CBOR undefined to []byte.
  61. if len(data) == 1 && (data[0] == 0xf6 || data[0] == 0xf7) {
  62. *bs = ""
  63. return nil
  64. }
  65. d := decoder{data: data, dm: defaultDecMode}
  66. // Check if CBOR data type is byte string
  67. if typ := d.nextCBORType(); typ != cborTypeByteString {
  68. return &UnmarshalTypeError{CBORType: typ.String(), GoType: typeByteString.String()}
  69. }
  70. b, _ := d.parseByteString()
  71. *bs = ByteString(b)
  72. return nil
  73. }