[
  {
    "path": ".github/release.yml",
    "content": "changelog:\n  exclude:\n    labels:\n      - tagpr\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: Mark stale issues and pull requests\n\n# on:\n#  schedule:\n#    - cron: '30 11 * * *'\n\njobs:\n  stale:\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n\n    steps:\n      - uses: actions/stale@v3\n        with:\n          days-before-issue-stale: 30\n          days-before-issue-close: 14\n          stale-issue-label: \"stale\"\n          stale-issue-message: \"This issue is stale because it has been open for 30 days with no activity.\"\n          close-issue-message: \"This issue was closed because it has been inactive for 14 days since being marked as stale.\"\n          days-before-pr-stale: -1\n          days-before-pr-close: -1\n          repo-token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/tagpr.yml",
    "content": "name: tagpr\n\non:\n  push:\n    branches: [\"main\"]\n\njobs:\n  tagpr:\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n      issues: read\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          persist-credentials: false\n      - uses: Songmu/tagpr@v1\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: test\n\non: [push, pull_request]\n\nenv:\n  GOPATH: ${{ github.workspace }}\n  WORKSPACE: ${{ github.workspace }}/src/github.com/${{ github.repository }}\n\njobs:\n  test:\n    defaults:\n      run:\n        working-directory: ${{ env.WORKSPACE }}\n    strategy:\n      matrix:\n        os: [ubuntu-latest, macos-latest, windows-latest]\n        go: [\"1.23\", \"1.24\", \"1.25\", \"1.26\"]\n    name: ${{ matrix.os }} @ Go ${{ matrix.go }}\n    runs-on: ${{ matrix.os }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          path: ${{ env.WORKSPACE }}\n\n      - name: Set up Go ${{ matrix.go }}\n        uses: actions/setup-go@v5\n        with:\n          go-version: ${{ matrix.go }}\n\n      - name: Cache\n        uses: actions/cache@v4\n        with:\n          path: ~/go/pkg/mod\n          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n          restore-keys: |\n            ${{ runner.os }}-go-\n\n      - name: Build\n        run: go build -v ./...\n\n      - name: Test\n        run: go test -v --coverpkg=github.com/shamaton/msgpack/... --coverprofile=coverage.coverprofile.tmp --covermode=atomic ./...\n\n      - name: Remove testutil from coverage\n        shell: bash\n        run: |\n          cat coverage.coverprofile.tmp | grep -v testutil > coverage.coverprofile\n          rm coverage.coverprofile.tmp\n\n      - name: Upload coverage to Codecov\n        if: success() && matrix.go == '1.25' && matrix.os == 'ubuntu-latest'\n        uses: codecov/codecov-action@v4\n        with:\n          token: ${{ secrets.CODECOV_TOKEN }}\n          fail_ci_if_error: false\n          working-directory: ${{ env.WORKSPACE }}\n\n  lint:\n    needs: test\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v4\n        with:\n          path: ${{ env.WORKSPACE }}\n      - name: golangci-lint\n        uses: reviewdog/action-golangci-lint@v2\n        with:\n          workdir: ${{ env.WORKSPACE }}\n          level: warning\n          reporter: github-pr-review\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\n# coverage\n*.coverprofile\n\n.DS_Store\n.idea\n.vscode\n"
  },
  {
    "path": ".tagpr",
    "content": "[tagpr]\n    releaseBranch = main\n    versionFile = -\n    vPrefix = true\n    changelog = true\n    release = true\n    fixedMajorVersion = 3\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changelog\n\n## [v3.1.1](https://github.com/shamaton/msgpack/compare/v3.1.0...v3.1.1) - 2026-05-12\n- chore: isolate formatting cleanup from #60 by @shamaton in https://github.com/shamaton/msgpack/pull/61\n- Add tagpr configuration by @shamaton in https://github.com/shamaton/msgpack/pull/63\n- fix: validate ext frame bounds before byte-slice decode by @hyp3rd in https://github.com/shamaton/msgpack/pull/60\n\n## [v3.1.0](https://github.com/shamaton/msgpack/commits/v3.1.0) - 2026-02-06\n- Add embedded struct support with optimized fast path by @shamaton in https://github.com/shamaton/msgpack/pull/58\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2025 Masayuki Shamoto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# MessagePack for Golang\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/shamaton/msgpack.svg)](https://pkg.go.dev/github.com/shamaton/msgpack)\n![test](https://github.com/shamaton/msgpack/workflows/test/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/shamaton/msgpack)](https://goreportcard.com/report/github.com/shamaton/msgpack)\n[![codecov](https://codecov.io/gh/shamaton/msgpack/branch/master/graph/badge.svg?token=9PD2JUK5V3)](https://codecov.io/gh/shamaton/msgpack)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fshamaton%2Fmsgpack.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fshamaton%2Fmsgpack?ref=badge_shield)\n\n## 📣 Announcement: `time.Time` decoding defaults to **UTC** in v3\n\nStarting with **v3.0.0**, when decoding MessagePack **Timestamp** into Go’s `time.Time`,\nthe default `Location` will be **UTC** (previously `Local`). The instant is unchanged.\nTo keep the old behavior, use `SetDecodedTimeAsLocal()`.\n\n## Features\n\n* Supported types : primitive / array / slice / struct / map / interface{} and time.Time\n* Renaming fields via `msgpack:\"field_name\"`\n* Omitting fields via `msgpack:\"-\"`\n* Omitting empty fields via `msgpack:\"field_name,omitempty\"`\n* Supports extend encoder / decoder [(example)](./msgpack_example_test.go)\n* Can also Encoding / Decoding struct as array\n\n## Installation\n\nCurrent version is **msgpack/v3**.\n\n```sh\ngo get -u github.com/shamaton/msgpack/v3\n```\n\n### Upgrading from v2\n\nIf you are upgrading from v2, please note the `time.Time` decoding change mentioned in the announcement above.\nTo keep the v2 behavior, use `msgpack.SetDecodedTimeAsLocal()` after upgrading.\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n  \"github.com/shamaton/msgpack/v3\"\n  \"net/http\"\n)\n\ntype Struct struct {\n  String string\n}\n\n// simple\nfunc main() {\n  v := Struct{String: \"msgpack\"}\n\n  d, err := msgpack.Marshal(v)\n  if err != nil {\n    panic(err)\n  }\n  r := Struct{}\n  if err = msgpack.Unmarshal(d, &r); err != nil {\n    panic(err)\n  }\n}\n\n// streaming\nfunc handle(w http.ResponseWriter, r *http.Request) {\n  var body Struct\n  if err := msgpack.UnmarshalRead(r, &body); err != nil {\n    panic(err)\n  }\n  if err := msgpack.MarshalWrite(w, body); err != nil {\n    panic(err)\n  }\n}\n```\n\n## v3: `time.Time` decoding defaults to **UTC**\n\n**TL;DR:** Starting with **v3.0.0**, when decoding MessagePack **Timestamp** into Go’s `time.Time`, the default `Location` will be **UTC** (previously `Local`). The **instant** is unchanged—only the display/location changes. This avoids host-dependent differences and aligns with common distributed systems practice.\n\n### What is changing?\n\n* **Before (v2.x):** Decoded `time.Time` defaults to `Local`.\n* **After (v3.0.0):** Decoded `time.Time` defaults to **UTC**.\n\nMessagePack’s Timestamp encodes an **instant** (epoch seconds + nanoseconds) and does **not** carry timezone info. Your data’s point in time is the same; only `time.Time.Location()` differs.\n\n### Why?\n\n* Eliminate environment-dependent behavior, such as different hosts showing different local zones.\n* Make “UTC by default” the safe, predictable baseline for logs, APIs, and distributed apps.\n\n### Who is affected?\n\n* Apps that **display local time** without explicitly converting from UTC.\n* If your code already normalizes to UTC or explicitly sets a location, you’re likely unaffected.\n\n### Keep the old behavior (Local)\n\nIf you want the v2 behavior on v3:\n\n```go\nmsgpack.SetDecodedTimeAsLocal()\n```\n\nOr convert after the fact:\n\n```go\nvar t time.Time\n_ = msgpack.Unmarshal(data, &t)\nt = t.In(time.Local)\n```\n\n### Preview the new behavior on v2 (optional)\n\nYou can opt into UTC today on v2.x:\n\n```go\nmsgpack.SetDecodedTimeAsUTC()\n```\n\n## Benchmark\n\nThis result made from [shamaton/msgpack_bench](https://github.com/shamaton/msgpack_bench)\n\n![msgpack_bench](https://github.com/user-attachments/assets/ed5bc4c5-a149-4083-98b8-ee6820c00eae)\n\n## License\n\nThis library is under the MIT License.\n"
  },
  {
    "path": "codecov.yml",
    "content": "coverage:\n  status:\n    project: off\n    patch: off"
  },
  {
    "path": "crash_test.go",
    "content": "package msgpack_test\n\nimport (\n\t\"io\"\n\t\"os\"\n\t\"path/filepath\"\n\t\"runtime\"\n\t\"sync\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3\"\n)\n\nvar crashDir = filepath.Join(\"testdata\", \"crashers\")\n\nfunc TestCrashBinary(t *testing.T) {\n\tentries, err := os.ReadDir(crashDir)\n\tif err != nil {\n\t\tt.Fatalf(\"os.ReadDir error. err: %+v\", err)\n\t}\n\n\tch := make(chan string, len(entries))\n\n\t// worker\n\twg := sync.WaitGroup{}\n\tfor i := 0; i < runtime.NumCPU(); i++ {\n\t\twg.Add(1)\n\t\tgo check(t, &wg, ch)\n\t}\n\n\tfor _, entry := range entries {\n\t\tch <- filepath.Join(crashDir, entry.Name())\n\t}\n\tclose(ch)\n\twg.Wait()\n}\n\nfunc check(t *testing.T, wg *sync.WaitGroup, ch <-chan string) {\n\tvar (\n\t\tpath string\n\t\tok   bool\n\t\tdata []byte\n\t)\n\tt.Helper()\n\tdefer wg.Done()\n\tdefer func() {\n\t\tif e := recover(); e != nil {\n\t\t\tt.Logf(\"panic occurred.\\nfile: %s\\nlen: %d\\nbin: % x\\nerr: %+v\",\n\t\t\t\tpath, len(data), data, e,\n\t\t\t)\n\t\t}\n\t}()\n\n\tfor {\n\t\tpath, ok = <-ch // closeされると ok が false になる\n\t\tif !ok {\n\t\t\treturn\n\t\t}\n\n\t\tfile, err := os.Open(path)\n\t\tif err != nil {\n\t\t\tt.Logf(\"%s file open error. err: %+v\", path, err)\n\t\t\tt.Fail()\n\t\t\treturn\n\t\t}\n\n\t\tdata, err = io.ReadAll(file)\n\t\tif err != nil {\n\t\t\tt.Logf(\"%s io.ReadAll error. err: %+v\", path, err)\n\t\t\tt.Fail()\n\t\t\treturn\n\t\t}\n\n\t\tvar r interface{}\n\t\terr = msgpack.Unmarshal(data, &r)\n\t\tif err == nil {\n\t\t\tt.Logf(\"err should be occurred.\\nname: %s\\nlen: %d\\nbin: % x\",\n\t\t\t\tfile.Name(), len(data), data,\n\t\t\t)\n\t\t\tt.Fail()\n\t\t\treturn\n\t\t}\n\n\t\tpath = \"\"\n\t\tdata = nil\n\t}\n}\n"
  },
  {
    "path": "decode.go",
    "content": "package msgpack\n\nimport (\n\t\"io\"\n\n\t\"github.com/shamaton/msgpack/v3/internal/decoding\"\n\tstreamdecoding \"github.com/shamaton/msgpack/v3/internal/stream/decoding\"\n)\n\n// UnmarshalAsMap decodes data that is encoded as map format.\n// This is the same thing that StructAsArray sets false.\nfunc UnmarshalAsMap(data []byte, v interface{}) error {\n\treturn decoding.Decode(data, v, false)\n}\n\n// UnmarshalAsArray decodes data that is encoded as array format.\n// This is the same thing that StructAsArray sets true.\nfunc UnmarshalAsArray(data []byte, v interface{}) error {\n\treturn decoding.Decode(data, v, true)\n}\n\n// UnmarshalReadAsMap decodes from stream. stream data expects map format.\n// This is the same thing that StructAsArray sets false.\nfunc UnmarshalReadAsMap(r io.Reader, v interface{}) error {\n\treturn streamdecoding.Decode(r, v, false)\n}\n\n// UnmarshalReadAsArray decodes from stream. stream data expects array format.\n// This is the same thing that StructAsArray sets true.\nfunc UnmarshalReadAsArray(r io.Reader, v interface{}) error {\n\treturn streamdecoding.Decode(r, v, true)\n}\n"
  },
  {
    "path": "def/def.go",
    "content": "package def\n\n// IntSize : 32 or 64\nconst IntSize = 32 << (^uint(0) >> 63)\n\nvar IsIntSize32 = IntSize == 32\n\n// message pack format\nconst (\n\tPositiveFixIntMin = 0x00\n\tPositiveFixIntMax = 0x7f\n\n\tFixMap   = 0x80\n\tFixArray = 0x90\n\tFixStr   = 0xa0\n\n\tNil = 0xc0\n\n\tFalse = 0xc2\n\tTrue  = 0xc3\n\n\tBin8  = 0xc4\n\tBin16 = 0xc5\n\tBin32 = 0xc6\n\n\tExt8  = 0xc7\n\tExt16 = 0xc8\n\tExt32 = 0xc9\n\n\tFloat32 = 0xca\n\tFloat64 = 0xcb\n\n\tUint8  = 0xcc\n\tUint16 = 0xcd\n\tUint32 = 0xce\n\tUint64 = 0xcf\n\n\tInt8  = 0xd0\n\tInt16 = 0xd1\n\tInt32 = 0xd2\n\tInt64 = 0xd3\n\n\tFixext1  = 0xd4\n\tFixext2  = 0xd5\n\tFixext4  = 0xd6\n\tFixext8  = 0xd7\n\tFixext16 = 0xd8\n\n\tStr8  = 0xd9\n\tStr16 = 0xda\n\tStr32 = 0xdb\n\n\tArray16 = 0xdc\n\tArray32 = 0xdd\n\n\tMap16 = 0xde\n\tMap32 = 0xdf\n\n\tNegativeFixintMin = -32 // 0xe0\n\tNegativeFixintMax = -1  // 0xff\n)\n\n// byte\nconst (\n\tByte1 = 1 << iota\n\tByte2\n\tByte4\n\tByte8\n\tByte16\n\tByte32\n)\n\n// ext type\nconst (\n\tTimeStamp = -1\n)\n\n// ext type complex\nvar complexTypeCode = int8(-128)\n\n// ComplexTypeCode gets complexTypeCode\nfunc ComplexTypeCode() int8 { return complexTypeCode }\n\n// SetComplexTypeCode sets complexTypeCode\nfunc SetComplexTypeCode(code int8) {\n\tcomplexTypeCode = code\n}\n"
  },
  {
    "path": "def/error.go",
    "content": "package def\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar (\n\t// base errors\n\n\tErrMsgpack = errors.New(\"\")\n\n\t// decoding errors\n\n\tErrNoData                 = fmt.Errorf(\"%wno data\", ErrMsgpack)\n\tErrHasLeftOver            = fmt.Errorf(\"%wdata has left over\", ErrMsgpack)\n\tErrReceiverNotPointer     = fmt.Errorf(\"%wreceiver not pointer\", ErrMsgpack)\n\tErrNotMatchArrayElement   = fmt.Errorf(\"%wnot match array element\", ErrMsgpack)\n\tErrCanNotDecode           = fmt.Errorf(\"%winvalid code\", ErrMsgpack)\n\tErrCanNotSetSliceAsMapKey = fmt.Errorf(\"%wcan not set slice as map key\", ErrMsgpack)\n\tErrCanNotSetMapAsMapKey   = fmt.Errorf(\"%wcan not set map as map key\", ErrMsgpack)\n\n\t// encoding errors\n\n\tErrTooShortBytes         = fmt.Errorf(\"%wtoo short bytes\", ErrMsgpack)\n\tErrLackDataLengthToSlice = fmt.Errorf(\"%wdata length lacks to create slice\", ErrMsgpack)\n\tErrLackDataLengthToMap   = fmt.Errorf(\"%wdata length lacks to create map\", ErrMsgpack)\n\tErrUnsupportedType       = fmt.Errorf(\"%wunsupported type\", ErrMsgpack)\n\tErrUnsupportedLength     = fmt.Errorf(\"%wunsupported length\", ErrMsgpack)\n\tErrNotMatchLastIndex     = fmt.Errorf(\"%wnot match last index\", ErrMsgpack)\n)\n"
  },
  {
    "path": "encode.go",
    "content": "package msgpack\n\nimport (\n\t\"io\"\n\n\t\"github.com/shamaton/msgpack/v3/internal/encoding\"\n\tstreamencoding \"github.com/shamaton/msgpack/v3/internal/stream/encoding\"\n)\n\n// MarshalAsMap encodes data as map format.\n// This is the same thing that StructAsArray sets false.\nfunc MarshalAsMap(v interface{}) ([]byte, error) {\n\treturn encoding.Encode(v, false)\n}\n\n// MarshalAsArray encodes data as array format.\n// This is the same thing that StructAsArray sets true.\nfunc MarshalAsArray(v interface{}) ([]byte, error) {\n\treturn encoding.Encode(v, true)\n}\n\n// MarshalWriteAsMap writes map format encoded data to writer.\n// This is the same thing that StructAsArray sets false.\nfunc MarshalWriteAsMap(w io.Writer, v interface{}) error {\n\treturn streamencoding.Encode(w, v, false)\n}\n\n// MarshalWriteAsArray writes array format encoded data to writer.\n// This is the same thing that StructAsArray sets true.\nfunc MarshalWriteAsArray(w io.Writer, v interface{}) error {\n\treturn streamencoding.Encode(w, v, true)\n}\n"
  },
  {
    "path": "errors.go",
    "content": "package msgpack\n\nimport (\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\n// Error is used in all msgpack error as the based error.\nvar Error = def.ErrMsgpack\n"
  },
  {
    "path": "ext/decode.go",
    "content": "package ext\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\n// Decoder defines an interface for decoding values from bytes.\n// It provides methods to get the decoder type, check if the data matches the type,\n// and convert the data into a Go value.\ntype Decoder interface {\n\t// Code returns the unique code representing the decoder type.\n\tCode() int8\n\n\t// IsType checks if the data at the given offset matches the expected type.\n\t// Returns true if the type matches, false otherwise.\n\tIsType(offset int, d *[]byte) bool\n\n\t// AsValue decodes the data at the given offset into a Go value of the specified kind.\n\t// Returns the decoded value, the new offset, and an error if decoding fails.\n\tAsValue(offset int, k reflect.Kind, d *[]byte) (interface{}, int, error)\n}\n\n// DecoderCommon provides common utility methods for decoding data from bytes.\ntype DecoderCommon struct{}\n\n// ReadSize1 reads a single byte from the given index in the byte slice.\n// Returns the byte and the new index after reading.\nfunc (cd *DecoderCommon) ReadSize1(index int, d *[]byte) (byte, int) {\n\trb := def.Byte1\n\treturn (*d)[index], index + rb\n}\n\n// ReadSize2 reads two bytes from the given index in the byte slice.\n// Returns the bytes as a slice and the new index after reading.\nfunc (cd *DecoderCommon) ReadSize2(index int, d *[]byte) ([]byte, int) {\n\trb := def.Byte2\n\treturn (*d)[index : index+rb], index + rb\n}\n\n// ReadSize4 reads four bytes from the given index in the byte slice.\n// Returns the bytes as a slice and the new index after reading.\nfunc (cd *DecoderCommon) ReadSize4(index int, d *[]byte) ([]byte, int) {\n\trb := def.Byte4\n\treturn (*d)[index : index+rb], index + rb\n}\n\n// ReadSize8 reads eight bytes from the given index in the byte slice.\n// Returns the bytes as a slice and the new index after reading.\nfunc (cd *DecoderCommon) ReadSize8(index int, d *[]byte) ([]byte, int) {\n\trb := def.Byte8\n\treturn (*d)[index : index+rb], index + rb\n}\n\n// ReadSizeN reads a specified number of bytes (n) from the given index in the byte slice.\n// Returns the bytes as a slice and the new index after reading.\nfunc (cd *DecoderCommon) ReadSizeN(index, n int, d *[]byte) ([]byte, int) {\n\treturn (*d)[index : index+n], index + n\n}\n"
  },
  {
    "path": "ext/decoder_stream.go",
    "content": "package ext\n\nimport (\n\t\"reflect\"\n)\n\n// StreamDecoder defines an interface for decoding streams of data.\n// It provides methods to retrieve the decoder's code, check type compatibility,\n// and convert raw data into a Go value of a specified kind.\ntype StreamDecoder interface {\n\t// Code returns the unique identifier for the decoder.\n\tCode() int8\n\n\t// IsType checks if the provided code, inner type, and data length match the expected type.\n\t// Returns true if the type matches, otherwise false.\n\tIsType(code byte, innerType int8, dataLength int) bool\n\n\t// ToValue converts the raw data into a Go value of the specified kind.\n\t// Takes the code, raw data, and the target kind as input.\n\t// Returns the decoded value or an error if the conversion fails.\n\tToValue(code byte, data []byte, k reflect.Kind) (any, error)\n}\n"
  },
  {
    "path": "ext/encode.go",
    "content": "package ext\n\nimport (\n\t\"reflect\"\n)\n\n// Encoder defines an interface for encoding values into bytes.\n// It provides methods to get the encoding type, calculate the byte size of a value,\n// and write the encoded value into a byte slice.\ntype Encoder interface {\n\t// Code returns the unique code representing the encoder type.\n\tCode() int8\n\n\t// Type returns the reflect.Type of the value that the encoder handles.\n\tType() reflect.Type\n\n\t// CalcByteSize calculates the number of bytes required to encode the given value.\n\t// Returns the size and an error if the calculation fails.\n\tCalcByteSize(value reflect.Value) (int, error)\n\n\t// WriteToBytes encodes the given value into a byte slice starting at the specified offset.\n\t// Returns the new offset after writing the bytes.\n\tWriteToBytes(value reflect.Value, offset int, bytes *[]byte) int\n}\n\n// EncoderCommon provides utility methods for encoding various types of values into bytes.\n// It includes methods to encode integers and unsigned integers of different sizes,\n// as well as methods to write raw byte slices into a target byte slice.\ntype EncoderCommon struct{}\n\n// SetByte1Int64 encodes a single byte from the given int64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the byte.\nfunc (c *EncoderCommon) SetByte1Int64(value int64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value)\n\treturn offset + 1\n}\n\n// SetByte2Int64 encodes the lower two bytes of the given int64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte2Int64(value int64, offset int, d *[]byte) int {\n\t(*d)[offset+0] = byte(value >> 8)\n\t(*d)[offset+1] = byte(value)\n\treturn offset + 2\n}\n\n// SetByte4Int64 encodes the lower four bytes of the given int64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte4Int64(value int64, offset int, d *[]byte) int {\n\t(*d)[offset+0] = byte(value >> 24)\n\t(*d)[offset+1] = byte(value >> 16)\n\t(*d)[offset+2] = byte(value >> 8)\n\t(*d)[offset+3] = byte(value)\n\treturn offset + 4\n}\n\n// SetByte8Int64 encodes all eight bytes of the given int64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte8Int64(value int64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 56)\n\t(*d)[offset+1] = byte(value >> 48)\n\t(*d)[offset+2] = byte(value >> 40)\n\t(*d)[offset+3] = byte(value >> 32)\n\t(*d)[offset+4] = byte(value >> 24)\n\t(*d)[offset+5] = byte(value >> 16)\n\t(*d)[offset+6] = byte(value >> 8)\n\t(*d)[offset+7] = byte(value)\n\treturn offset + 8\n}\n\n// SetByte1Uint64 encodes a single byte from the given uint64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the byte.\nfunc (c *EncoderCommon) SetByte1Uint64(value uint64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value)\n\treturn offset + 1\n}\n\n// SetByte2Uint64 encodes the lower two bytes of the given uint64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte2Uint64(value uint64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 8)\n\t(*d)[offset+1] = byte(value)\n\treturn offset + 2\n}\n\n// SetByte4Uint64 encodes the lower four bytes of the given uint64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte4Uint64(value uint64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 24)\n\t(*d)[offset+1] = byte(value >> 16)\n\t(*d)[offset+2] = byte(value >> 8)\n\t(*d)[offset+3] = byte(value)\n\treturn offset + 4\n}\n\n// SetByte8Uint64 encodes all eight bytes of the given uint64 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte8Uint64(value uint64, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 56)\n\t(*d)[offset+1] = byte(value >> 48)\n\t(*d)[offset+2] = byte(value >> 40)\n\t(*d)[offset+3] = byte(value >> 32)\n\t(*d)[offset+4] = byte(value >> 24)\n\t(*d)[offset+5] = byte(value >> 16)\n\t(*d)[offset+6] = byte(value >> 8)\n\t(*d)[offset+7] = byte(value)\n\treturn offset + 8\n}\n\n// SetByte1Int encodes a single byte from the given int value into the byte slice at the specified offset.\n// Returns the new offset after writing the byte.\nfunc (c *EncoderCommon) SetByte1Int(code, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(code)\n\treturn offset + 1\n}\n\n// SetByte2Int encodes the lower two bytes of the given int value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte2Int(value int, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 8)\n\t(*d)[offset+1] = byte(value)\n\treturn offset + 2\n}\n\n// SetByte4Int encodes the lower four bytes of the given int value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte4Int(value int, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 24)\n\t(*d)[offset+1] = byte(value >> 16)\n\t(*d)[offset+2] = byte(value >> 8)\n\t(*d)[offset+3] = byte(value)\n\treturn offset + 4\n}\n\n// SetByte4Uint32 encodes the lower four bytes of the given uint32 value into the byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetByte4Uint32(value uint32, offset int, d *[]byte) int {\n\t(*d)[offset] = byte(value >> 24)\n\t(*d)[offset+1] = byte(value >> 16)\n\t(*d)[offset+2] = byte(value >> 8)\n\t(*d)[offset+3] = byte(value)\n\treturn offset + 4\n}\n\n// SetBytes writes the given byte slice `bs` into the target byte slice at the specified offset.\n// Returns the new offset after writing the bytes.\nfunc (c *EncoderCommon) SetBytes(bs []byte, offset int, d *[]byte) int {\n\tfor i := range bs {\n\t\t(*d)[offset+i] = bs[i]\n\t}\n\treturn offset + len(bs)\n}\n"
  },
  {
    "path": "ext/encode_stream.go",
    "content": "package ext\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\n// StreamEncoder is an interface that extended encoders should implement.\n// It defines methods for encoding data into a stream.\ntype StreamEncoder interface {\n\t// Code returns the unique code for the encoder.\n\tCode() int8\n\t// Type returns the reflect.Type of the value being encoded.\n\tType() reflect.Type\n\t// Write encodes the given value and writes it to the provided StreamWriter.\n\tWrite(w StreamWriter, value reflect.Value) error\n}\n\n// StreamWriter provides methods for writing data in extended formats.\n// It wraps an io.Writer and a buffer for efficient writing.\ntype StreamWriter struct {\n\tw   io.Writer      // The underlying writer to write data to.\n\tbuf *common.Buffer // A buffer used for temporary storage during writing.\n}\n\n// CreateStreamWriter creates and returns a new StreamWriter instance.\nfunc CreateStreamWriter(w io.Writer, buf *common.Buffer) StreamWriter {\n\treturn StreamWriter{w, buf}\n}\n\n// WriteByte1Int64 writes a single byte representation of an int64 value.\nfunc (w *StreamWriter) WriteByte1Int64(value int64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte2Int64 writes a two-byte representation of an int64 value.\nfunc (w *StreamWriter) WriteByte2Int64(value int64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte4Int64 writes a four-byte representation of an int64 value.\nfunc (w *StreamWriter) WriteByte4Int64(value int64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte8Int64 writes an eight-byte representation of an int64 value.\nfunc (w *StreamWriter) WriteByte8Int64(value int64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>56),\n\t\tbyte(value>>48),\n\t\tbyte(value>>40),\n\t\tbyte(value>>32),\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte1Uint64 writes a single byte representation of a uint64 value.\nfunc (w *StreamWriter) WriteByte1Uint64(value uint64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte2Uint64 writes a two-byte representation of a uint64 value.\nfunc (w *StreamWriter) WriteByte2Uint64(value uint64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte4Uint64 writes a four-byte representation of a uint64 value.\nfunc (w *StreamWriter) WriteByte4Uint64(value uint64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte8Uint64 writes an eight-byte representation of a uint64 value.\nfunc (w *StreamWriter) WriteByte8Uint64(value uint64) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>56),\n\t\tbyte(value>>48),\n\t\tbyte(value>>40),\n\t\tbyte(value>>32),\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte1Int writes a single byte representation of an int value.\nfunc (w *StreamWriter) WriteByte1Int(value int) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte2Int writes a two-byte representation of an int value.\nfunc (w *StreamWriter) WriteByte2Int(value int) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte4Int writes a four-byte representation of an int value.\nfunc (w *StreamWriter) WriteByte4Int(value int) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteByte4Uint32 writes a four-byte representation of a uint32 value.\nfunc (w *StreamWriter) WriteByte4Uint32(value uint32) error {\n\treturn w.buf.Write(w.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\n// WriteBytes writes a slice of bytes to the underlying writer.\nfunc (w *StreamWriter) WriteBytes(bs []byte) error {\n\treturn w.buf.Write(w.w, bs...)\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/shamaton/msgpack/v3\n\ngo 1.23\n"
  },
  {
    "path": "internal/common/buffer.go",
    "content": "package common\n\nimport (\n\t\"io\"\n\t\"sync\"\n)\n\ntype Buffer struct {\n\tData   []byte\n\tB1     []byte\n\tB2     []byte\n\tB4     []byte\n\tB8     []byte\n\tB16    []byte\n\toffset int\n}\n\nfunc (b *Buffer) Write(w io.Writer, vs ...byte) error {\n\tif len(b.Data) < b.offset+len(vs) {\n\t\t_, err := w.Write(b.Data[:b.offset])\n\t\tb.offset = 0\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif len(b.Data) < len(vs) {\n\t\t\tb.Data = append(b.Data, make([]byte, len(vs)-len(b.Data))...)\n\t\t}\n\t}\n\tfor i := range vs {\n\t\tb.Data[b.offset+i] = vs[i]\n\t}\n\tb.offset += len(vs)\n\treturn nil\n}\n\nfunc (b *Buffer) Flush(w io.Writer) error {\n\t_, err := w.Write(b.Data[:b.offset])\n\treturn err\n}\n\nvar bufPool = sync.Pool{\n\tNew: func() interface{} {\n\t\tdata := make([]byte, 64)\n\t\treturn &Buffer{\n\t\t\tData: data,\n\t\t\tB1:   data[:1],\n\t\t\tB2:   data[:2],\n\t\t\tB4:   data[:4],\n\t\t\tB8:   data[:8],\n\t\t\tB16:  data[:16],\n\t\t}\n\t},\n}\n\nfunc GetBuffer() *Buffer {\n\tbuf := bufPool.Get().(*Buffer)\n\tbuf.offset = 0\n\treturn buf\n}\n\nfunc PutBuffer(buf *Buffer) {\n\tbufPool.Put(buf)\n}\n"
  },
  {
    "path": "internal/common/common.go",
    "content": "package common\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n)\n\n// Common is used encoding/decoding\ntype Common struct{}\n\n// FieldInfo holds information about a struct field including its path for embedded structs\ntype FieldInfo struct {\n\tPath      []int   // path to reach this field (indices for embedded structs)\n\tName      string  // field name or tag\n\tOmit      bool    // omitempty flag\n\tTagged    bool    // tag name explicitly set\n\tOmitPaths [][]int // paths to embedded fields with omitempty\n}\n\n// CollectFields collects all fields from a struct, expanding embedded structs\n// following the same rules as encoding/json\nfunc (c *Common) CollectFields(t reflect.Type, path []int) []FieldInfo {\n\treturn c.collectFields(t, path, nil)\n}\n\nfunc (c *Common) collectFields(t reflect.Type, path []int, omitPaths [][]int) []FieldInfo {\n\tvar fields []FieldInfo\n\tvar embedded []FieldInfo // embedded fields to process later (lower priority)\n\n\tfor i := 0; i < t.NumField(); i++ {\n\t\tfield := t.Field(i)\n\n\t\t// Check field visibility and get omitempty flag\n\t\tpublic, omit, name := c.CheckField(field)\n\t\tif !public {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Get tag to check if embedded\n\t\ttag := field.Tag.Get(\"msgpack\")\n\t\t// Extract just the name part (before comma if any)\n\t\ttagName := tag\n\t\tfor j, ch := range tag {\n\t\t\tif ch == ',' {\n\t\t\t\ttagName = tag[:j]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\t// Check if this is an embedded struct\n\t\tisEmbedded := field.Anonymous && (tag == \"\" || tagName == \"\")\n\t\ttagged := tagName != \"\"\n\n\t\tif isEmbedded {\n\t\t\t// Get the actual type (dereference pointer if needed)\n\t\t\tfieldType := field.Type\n\t\t\tif fieldType.Kind() == reflect.Ptr {\n\t\t\t\tfieldType = fieldType.Elem()\n\t\t\t}\n\n\t\t\t// If it's a struct, expand its fields\n\t\t\tif fieldType.Kind() == reflect.Struct {\n\t\t\t\tnewPath := append(append([]int{}, path...), i)\n\t\t\t\tnextOmitPaths := omitPaths\n\t\t\t\tif omit {\n\t\t\t\t\tnextOmitPaths = appendOmitPath(omitPaths, newPath)\n\t\t\t\t}\n\t\t\t\tembeddedFields := c.collectFields(fieldType, newPath, nextOmitPaths)\n\t\t\t\tembedded = append(embedded, embeddedFields...)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Regular field or embedded non-struct\n\t\tnewPath := append(append([]int{}, path...), i)\n\t\tfields = append(fields, FieldInfo{\n\t\t\tPath:      newPath,\n\t\t\tName:      name,\n\t\t\tOmit:      omit,\n\t\t\tTagged:    tagged,\n\t\t\tOmitPaths: omitPaths,\n\t\t})\n\t}\n\n\t// Add embedded fields after regular fields (they have lower priority)\n\tfields = append(fields, embedded...)\n\n\t// Remove duplicates and handle ambiguous fields\n\treturn c.deduplicateFields(fields)\n}\n\nfunc appendOmitPath(paths [][]int, path []int) [][]int {\n\tif len(paths) == 0 {\n\t\treturn [][]int{path}\n\t}\n\tnewPaths := make([][]int, len(paths)+1)\n\tcopy(newPaths, paths)\n\tnewPaths[len(paths)] = path\n\treturn newPaths\n}\n\n// deduplicateFields removes duplicate fields and handles ambiguous fields\n// following encoding/json behavior\nfunc (c *Common) deduplicateFields(fields []FieldInfo) []FieldInfo {\n\t// Group fields by name and depth, preserving order\n\ttype fieldAtDepth struct {\n\t\tfield FieldInfo\n\t\tdepth int\n\t}\n\tfieldsByName := make(map[string][]fieldAtDepth)\n\tvar seenNames []string // To preserve order\n\n\tfor _, f := range fields {\n\t\tif _, seen := fieldsByName[f.Name]; !seen {\n\t\t\tseenNames = append(seenNames, f.Name)\n\t\t}\n\t\tfieldsByName[f.Name] = append(fieldsByName[f.Name], fieldAtDepth{\n\t\t\tfield: f,\n\t\t\tdepth: len(f.Path),\n\t\t})\n\t}\n\n\tvar result []FieldInfo\n\tfor _, name := range seenNames {\n\t\tfieldsWithDepth := fieldsByName[name]\n\n\t\t// Find minimum depth\n\t\tminDepth := fieldsWithDepth[0].depth\n\t\tfor _, fd := range fieldsWithDepth {\n\t\t\tif fd.depth < minDepth {\n\t\t\t\tminDepth = fd.depth\n\t\t\t}\n\t\t}\n\n\t\t// Count fields at minimum depth\n\t\tvar fieldsAtMinDepth []FieldInfo\n\t\tfor _, fd := range fieldsWithDepth {\n\t\t\tif fd.depth == minDepth {\n\t\t\t\tfieldsAtMinDepth = append(fieldsAtMinDepth, fd.field)\n\t\t\t}\n\t\t}\n\n\t\t// If there's exactly one field at minimum depth, use it\n\t\tif len(fieldsAtMinDepth) == 1 {\n\t\t\tresult = append(result, fieldsAtMinDepth[0])\n\t\t\tcontinue\n\t\t}\n\n\t\t// Prefer the tagged field if exactly one is tagged at minimum depth\n\t\tvar taggedFields []FieldInfo\n\t\tfor _, f := range fieldsAtMinDepth {\n\t\t\tif f.Tagged {\n\t\t\t\ttaggedFields = append(taggedFields, f)\n\t\t\t}\n\t\t}\n\t\tif len(taggedFields) == 1 {\n\t\t\tresult = append(result, taggedFields[0])\n\t\t}\n\t\t// else: ambiguous field, skip it (following encoding/json behavior)\n\t}\n\n\treturn result\n}\n\n// CheckField returns flag whether should encode/decode or not and field name\nfunc (c *Common) CheckField(field reflect.StructField) (public, omit bool, name string) {\n\t// A to Z\n\tif !c.isPublic(field.Name) {\n\t\treturn false, false, \"\"\n\t}\n\ttag := field.Tag.Get(\"msgpack\")\n\tif tag == \"\" {\n\t\treturn true, false, field.Name\n\t}\n\n\tparts := strings.Split(tag, \",\")\n\t// check ignore\n\tif parts[0] == \"-\" {\n\t\treturn false, false, \"\"\n\t}\n\t// check omitempty\n\tfor _, part := range parts[1:] {\n\t\tif part == \"omitempty\" {\n\t\t\tomit = true\n\t\t}\n\t}\n\t// check name\n\tname = field.Name\n\tif parts[0] != \"\" {\n\t\tname = parts[0]\n\t}\n\treturn true, omit, name\n}\n\nfunc (c *Common) isPublic(name string) bool {\n\treturn 0x41 <= name[0] && name[0] <= 0x5a\n}\n"
  },
  {
    "path": "internal/common/common_test.go",
    "content": "package common\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestCommon_CheckField(t *testing.T) {\n\tcommon := Common{}\n\n\tt.Run(\"tag:-\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\"-\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, false)\n\t\ttu.Equal(t, omit, false)\n\t\ttu.Equal(t, v, \"\")\n\t})\n\tt.Run(\"tag:,omitempty\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\",omitempty\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, true)\n\t\ttu.Equal(t, omit, true)\n\t\ttu.Equal(t, v, \"A\")\n\t})\n\tt.Run(\"tag:-,omitempty\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\"-,omitempty\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, false)\n\t\ttu.Equal(t, omit, false)\n\t\ttu.Equal(t, v, \"\")\n\t})\n\tt.Run(\"tag:B\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\"B\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, true)\n\t\ttu.Equal(t, omit, false)\n\t\ttu.Equal(t, v, \"B\")\n\t})\n\tt.Run(\"tag:B,omitempty\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\"B,omitempty\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, true)\n\t\ttu.Equal(t, omit, true)\n\t\ttu.Equal(t, v, \"B\")\n\t})\n\tt.Run(\"name:A\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"A\",\n\t\t\tTag:  `msgpack:\"\"`,\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, true)\n\t\ttu.Equal(t, omit, false)\n\t\ttu.Equal(t, v, \"A\")\n\t})\n\tt.Run(\"private\", func(t *testing.T) {\n\t\tfield := reflect.StructField{\n\t\t\tName: \"a\",\n\t\t}\n\t\tpublic, omit, v := common.CheckField(field)\n\t\ttu.Equal(t, public, false)\n\t\ttu.Equal(t, omit, false)\n\t\ttu.Equal(t, v, \"\")\n\t})\n}\n"
  },
  {
    "path": "internal/common/testutil/reader.go",
    "content": "package testutil\n\nimport (\n\t\"errors\"\n\t\"io\"\n)\n\nvar ErrReaderErr = errors.New(\"reader error\")\n\ntype ErrReader struct{}\n\nfunc NewErrReader() *ErrReader {\n\treturn &ErrReader{}\n}\n\nfunc (ErrReader) Read(_ []byte) (int, error) {\n\treturn 0, ErrReaderErr\n}\n\ntype TestReader struct {\n\ts     []byte\n\ti     int64 // current reading index\n\tcount int\n}\n\nfunc NewTestReader(b []byte) *TestReader {\n\treturn &TestReader{s: b, i: 0, count: 0}\n}\n\nfunc (r *TestReader) Read(b []byte) (n int, err error) {\n\tif r.i >= int64(len(r.s)) {\n\t\treturn 0, io.EOF\n\t}\n\tn = copy(b, r.s[r.i:])\n\tr.i += int64(n)\n\tr.count++\n\treturn\n}\n\nfunc (r *TestReader) Count() int {\n\treturn r.count\n}\n"
  },
  {
    "path": "internal/common/testutil/struct.go",
    "content": "package testutil\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"strconv\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\n// CreateStruct returns a struct that is made dynamically and encoded bytes.\nfunc CreateStruct(fieldNum int) (v any, asMapBytes []byte, asArrayBytes []byte) {\n\tif fieldNum < 0 {\n\t\tpanic(\"negative field number\")\n\t}\n\n\tfields := make([]reflect.StructField, 0, fieldNum)\n\tasMapBytes = make([]byte, 0, fieldNum*2)\n\tasArrayBytes = make([]byte, 0, fieldNum)\n\n\tfor i := 0; i < fieldNum; i++ {\n\t\t// create struct field\n\t\tname := \"A\" + strconv.Itoa(i)\n\t\ttyp := reflect.TypeOf(1)\n\t\tfield := reflect.StructField{\n\t\t\tName: name,\n\t\t\tType: typ,\n\t\t\tTag:  `json:\"B\"`,\n\t\t}\n\t\tfields = append(fields, field)\n\n\t\t// set encoded bytes\n\t\tif len(name) < 32 {\n\t\t\tasMapBytes = append(asMapBytes, def.FixStr+byte(len(name)))\n\t\t} else if len(name) < math.MaxUint8 {\n\t\t\tasMapBytes = append(asMapBytes, def.Str8)\n\t\t\tasMapBytes = append(asMapBytes, byte(len(name)))\n\t\t}\n\t\tfor _, c := range name {\n\t\t\tasMapBytes = append(asMapBytes, byte(c))\n\t\t}\n\t\tvalue := byte(i % 0x7f)\n\t\tasMapBytes = append(asMapBytes, value)\n\t\tasArrayBytes = append(asArrayBytes, value)\n\t}\n\tt := reflect.StructOf(fields)\n\n\t// set field values\n\tv = reflect.New(t).Interface()\n\trv := reflect.ValueOf(v)\n\tfor i := 0; i < rv.Elem().NumField(); i++ {\n\t\tfield := rv.Elem().Field(i)\n\t\tfield.SetInt(int64(i % 0x7f))\n\t}\n\treturn v, asMapBytes, asArrayBytes\n}\n"
  },
  {
    "path": "internal/common/testutil/testutil.go",
    "content": "package testutil\n\nimport (\n\t\"errors\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc NoError(t *testing.T, err error) {\n\tt.Helper()\n\tif err != nil {\n\t\tt.Fatalf(\"error is not nil: %v\", err)\n\t}\n}\n\nfunc Error(t *testing.T, err error) {\n\tt.Helper()\n\tif err == nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc IsError(t *testing.T, actual, expected error) {\n\tt.Helper()\n\tif !errors.Is(actual, expected) {\n\t\tt.Fatalf(\"not equal. actual: %v, expected: %v\", actual, expected)\n\t}\n}\n\nfunc ErrorContains(t *testing.T, err error, errStr string) {\n\tt.Helper()\n\tif err == nil {\n\t\tt.Fatal(\"error should occur\")\n\t}\n\tif !strings.Contains(err.Error(), errStr) {\n\t\tt.Fatalf(\"error does not contain '%s'. err: %v\", errStr, err)\n\t}\n}\n\nfunc Equal[T any](t *testing.T, actual, expected T) {\n\tt.Helper()\n\tif !reflect.DeepEqual(actual, expected) {\n\t\tt.Fatalf(\"not equal. actual: %v, expected: %v\", actual, expected)\n\t}\n}\n\nfunc EqualSlice[T comparable](t *testing.T, actual, expected []T) {\n\tt.Helper()\n\tif len(actual) != len(expected) {\n\t\tswitch a := any(actual).(type) {\n\t\tcase []byte:\n\t\t\te := any(expected).([]byte)\n\t\t\tt.Fatalf(\"diffrent length. actual: [% 02x], expected: [% 02x]\", a, e)\n\t\tdefault:\n\t\t\tt.Fatalf(\"diffrent length. actual: %v, expected: %v\", actual, expected)\n\t\t}\n\t}\n\tfor i := range actual {\n\t\tif !reflect.DeepEqual(actual[i], expected[i]) {\n\t\t\tswitch a := any(actual).(type) {\n\t\t\tcase []byte:\n\t\t\t\te := any(expected).([]byte)\n\t\t\t\tt.Fatalf(\"not equal. actual: [% 02x], expected: [% 02x]\", a, e)\n\t\t\tdefault:\n\t\t\t\tt.Fatalf(\"not equal. actual: %v, expected: %v\", actual, expected)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc EqualMap[K comparable, V comparable](t *testing.T, actual, expected map[K]V) {\n\tt.Helper()\n\tif len(actual) != len(expected) {\n\t\tt.Fatalf(\"diffrent length. actual: %v, expected: %v\", actual, expected)\n\t}\n\tfor k, v1 := range actual {\n\t\tif v2, ok := expected[k]; !ok || v1 != v2 {\n\t\t\tt.Fatalf(\"not equal. actual: %v, expected: %v\", actual, expected)\n\t\t}\n\t}\n}\n\ntype Equaler[T any] interface {\n\tEqual(other T) bool\n}\n\nfunc EqualEqualer[T Equaler[T]](t *testing.T, actual, expected T) {\n\tt.Helper()\n\tif !actual.Equal(expected) {\n\t\tt.Fatalf(\"not equal. actual: %v, expected: %v\", actual, expected)\n\t}\n}\n"
  },
  {
    "path": "internal/decoding/bin.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"unsafe\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) isCodeBin(v byte) bool {\n\tswitch v {\n\tcase def.Bin8, def.Bin16, def.Bin32:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (d *decoder) asBin(offset int, k reflect.Kind) ([]byte, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn emptyBytes, 0, err\n\t}\n\n\tswitch code {\n\tcase def.Bin8:\n\t\tl, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\tv, offset, err := d.readSizeN(offset, int(uint8(l)))\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\treturn v, offset, nil\n\tcase def.Bin16:\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\tv, offset, err := d.readSizeN(offset, int(binary.BigEndian.Uint16(bs)))\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\treturn v, offset, nil\n\tcase def.Bin32:\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\tv, offset, err := d.readSizeN(offset, int(binary.BigEndian.Uint32(bs)))\n\t\tif err != nil {\n\t\t\treturn emptyBytes, 0, err\n\t\t}\n\t\treturn v, offset, nil\n\t}\n\n\treturn emptyBytes, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asBinString(offset int, k reflect.Kind) (string, int, error) {\n\tbs, offset, err := d.asBin(offset, k)\n\treturn *(*string)(unsafe.Pointer(&bs)), offset, err\n}\n"
  },
  {
    "path": "internal/decoding/bin_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_isCodeBin(t *testing.T) {\n\td := decoder{}\n\tfor i := 0x00; i <= 0xff; i++ {\n\t\tv := byte(i)\n\t\tisBin := v == def.Bin8 || v == def.Bin16 || v == def.Bin32\n\t\ttu.Equal(t, d.isCodeBin(v), isBin)\n\t}\n}\n\nfunc Test_asBin(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) ([]byte, int, error) {\n\t\treturn d.asBin\n\t}\n\ttestcases := AsXXXTestCases[[]byte]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin8.error.size\",\n\t\t\tData:     []byte{def.Bin8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin8.error.data\",\n\t\t\tData:     []byte{def.Bin8, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin8.ok\",\n\t\t\tData:     []byte{def.Bin8, 1, 'a'},\n\t\t\tExpected: []byte{'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin16.error.size\",\n\t\t\tData:     []byte{def.Bin16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin16.error.data\",\n\t\t\tData:     []byte{def.Bin16, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin16.ok\",\n\t\t\tData:     []byte{def.Bin16, 0, 1, 'b'},\n\t\t\tExpected: []byte{'b'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin32.error.size\",\n\t\t\tData:     []byte{def.Bin32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin32.error.data\",\n\t\t\tData:     []byte{def.Bin32, 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin32.ok\",\n\t\t\tData:     []byte{def.Bin32, 0, 0, 0, 1, 'c'},\n\t\t\tExpected: []byte{'c'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/bool.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asBool(offset int, k reflect.Kind) (bool, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn false, 0, err\n\t}\n\n\tswitch code {\n\tcase def.True:\n\t\treturn true, offset, nil\n\tcase def.False:\n\t\treturn false, offset, nil\n\t}\n\treturn false, 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/decoding/bool_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asBool(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (bool, int, error) {\n\t\treturn d.asBool\n\t}\n\ttestcases := AsXXXTestCases[bool]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bool.false\",\n\t\t\tData:     []byte{def.False},\n\t\t\tExpected: false,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bool.true\",\n\t\t\tData:     []byte{def.True},\n\t\t\tExpected: true,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/complex.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asComplex64(offset int, k reflect.Kind) (complex64, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn complex(0, 0), 0, err\n\t}\n\n\tswitch code {\n\tcase def.Fixext8:\n\t\tt, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), 0, fmt.Errorf(\"fixext8. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tib, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tr := math.Float32frombits(binary.BigEndian.Uint32(rb))\n\t\ti := math.Float32frombits(binary.BigEndian.Uint32(ib))\n\t\treturn complex(r, i), offset, nil\n\n\tcase def.Fixext16:\n\t\tt, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), 0, fmt.Errorf(\"fixext16. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tib, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tr := math.Float64frombits(binary.BigEndian.Uint64(rb))\n\t\ti := math.Float64frombits(binary.BigEndian.Uint64(ib))\n\t\treturn complex64(complex(r, i)), offset, nil\n\n\t}\n\n\treturn complex(0, 0), 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asComplex128(offset int, k reflect.Kind) (complex128, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn complex(0, 0), 0, err\n\t}\n\n\tswitch code {\n\tcase def.Fixext8:\n\t\tt, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), 0, fmt.Errorf(\"fixext8. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tib, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tr := math.Float32frombits(binary.BigEndian.Uint32(rb))\n\t\ti := math.Float32frombits(binary.BigEndian.Uint32(ib))\n\t\treturn complex128(complex(r, i)), offset, nil\n\n\tcase def.Fixext16:\n\t\tt, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), 0, fmt.Errorf(\"fixext16. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tib, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), 0, err\n\t\t}\n\t\tr := math.Float64frombits(binary.BigEndian.Uint64(rb))\n\t\ti := math.Float64frombits(binary.BigEndian.Uint64(ib))\n\t\treturn complex(r, i), offset, nil\n\n\t}\n\n\treturn complex(0, 0), 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/decoding/complex_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asComplex64(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (complex64, int, error) {\n\t\treturn d.asComplex64\n\t}\n\ttestcases := AsXXXTestCases[complex64]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.type\",\n\t\t\tData:     []byte{def.Fixext8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.r\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode())},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.i\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.ok\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\tExpected: complex(1, 1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.type\",\n\t\t\tData:     []byte{def.Fixext16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.r\",\n\t\t\tData:     []byte{def.Fixext16, byte(def.ComplexTypeCode())},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.i\",\n\t\t\tData:     []byte{def.Fixext16, byte(def.ComplexTypeCode()), 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName: \"Fixext16.ok\",\n\t\t\tData: []byte{\n\t\t\t\tdef.Fixext16, byte(def.ComplexTypeCode()),\n\t\t\t\t63, 240, 0, 0, 0, 0, 0, 0, 63, 240, 0, 0, 0, 0, 0, 0,\n\t\t\t},\n\t\t\tExpected: complex(1, 1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asComplex128(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (complex128, int, error) {\n\t\treturn d.asComplex128\n\t}\n\ttestcases := AsXXXTestCases[complex128]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.type\",\n\t\t\tData:     []byte{def.Fixext8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.r\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode())},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.error.i\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.ok\",\n\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\tExpected: complex(1, 1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.type\",\n\t\t\tData:     []byte{def.Fixext16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.r\",\n\t\t\tData:     []byte{def.Fixext16, byte(def.ComplexTypeCode())},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.error.i\",\n\t\t\tData:     []byte{def.Fixext16, byte(def.ComplexTypeCode()), 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName: \"Fixext16.ok\",\n\t\t\tData: []byte{\n\t\t\t\tdef.Fixext16, byte(def.ComplexTypeCode()),\n\t\t\t\t63, 240, 0, 0, 0, 0, 0, 0, 63, 240, 0, 0, 0, 0, 0, 0,\n\t\t\t},\n\t\t\tExpected: complex(1, 1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/decoding.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype decoder struct {\n\tdata    []byte\n\tasArray bool\n\tcommon.Common\n}\n\n// Decode analyzes the MessagePack-encoded data and stores\n// the result into the pointer of v.\nfunc Decode(data []byte, v interface{}, asArray bool) error {\n\td := decoder{data: data, asArray: asArray}\n\n\tif len(d.data) < 1 {\n\t\treturn def.ErrNoData\n\t}\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"%w. v.(type): %T\", def.ErrReceiverNotPointer, v)\n\t}\n\n\trv = rv.Elem()\n\n\tlast, err := d.decode(rv, 0)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(data) != last {\n\t\treturn fmt.Errorf(\"%w size=%d, last=%d\", def.ErrHasLeftOver, len(data), last)\n\t}\n\treturn err\n}\n\nfunc (d *decoder) decode(rv reflect.Value, offset int) (int, error) {\n\tk := rv.Kind()\n\tswitch k {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tv, o, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetInt(v)\n\t\toffset = o\n\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\tv, o, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetUint(v)\n\t\toffset = o\n\n\tcase reflect.Float32:\n\t\tv, o, err := d.asFloat32(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetFloat(float64(v))\n\t\toffset = o\n\n\tcase reflect.Float64:\n\t\tv, o, err := d.asFloat64(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetFloat(v)\n\t\toffset = o\n\n\tcase reflect.String:\n\t\t// byte slice\n\t\tif d.isCodeBin(d.data[offset]) {\n\t\t\tv, offset, err := d.asBinString(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\trv.SetString(v)\n\t\t\treturn offset, nil\n\t\t}\n\t\tv, o, err := d.asString(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetString(v)\n\t\toffset = o\n\n\tcase reflect.Bool:\n\t\tv, o, err := d.asBool(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetBool(v)\n\t\toffset = o\n\n\tcase reflect.Slice:\n\t\t// nil\n\t\tif d.isCodeNil(d.data[offset]) {\n\t\t\toffset++\n\t\t\treturn offset, nil\n\t\t}\n\t\t// byte slice\n\t\tif d.isCodeBin(d.data[offset]) {\n\t\t\tbs, offset, err := d.asBin(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\trv.SetBytes(bs)\n\t\t\treturn offset, nil\n\t\t}\n\t\t// string to bytes\n\t\tif d.isCodeString(d.data[offset]) {\n\t\t\tl, offset, err := d.stringByteLength(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tbs, offset, err := d.asStringByteByLength(offset, l, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\trv.SetBytes(bs)\n\t\t\treturn offset, nil\n\t\t}\n\n\t\t// get slice length\n\t\tl, o, err := d.sliceLength(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tif err = d.hasRequiredLeastSliceSize(o, l); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// check fixed type\n\t\tfixedOffset, found, err := d.asFixedSlice(rv, o, l)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif found {\n\t\t\treturn fixedOffset, nil\n\t\t}\n\n\t\t// create slice dynamically\n\t\ttmpSlice := reflect.MakeSlice(rv.Type(), l, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tv := tmpSlice.Index(i)\n\t\t\tif v.Kind() == reflect.Struct {\n\t\t\t\to, err = d.setStruct(v, o, k)\n\t\t\t} else {\n\t\t\t\to, err = d.decode(v, o)\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\trv.Set(tmpSlice)\n\t\toffset = o\n\n\tcase reflect.Complex64:\n\t\tv, o, err := d.asComplex64(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetComplex(complex128(v))\n\t\toffset = o\n\n\tcase reflect.Complex128:\n\t\tv, o, err := d.asComplex128(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\trv.SetComplex(v)\n\t\toffset = o\n\n\tcase reflect.Array:\n\t\t// nil\n\t\tif d.isCodeNil(d.data[offset]) {\n\t\t\toffset++\n\t\t\treturn offset, nil\n\t\t}\n\t\t// byte slice\n\t\tif d.isCodeBin(d.data[offset]) {\n\t\t\tbs, offset, err := d.asBin(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tif len(bs) > rv.Len() {\n\t\t\t\treturn 0, fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), len(bs), def.ErrNotMatchArrayElement)\n\t\t\t}\n\t\t\tfor i, b := range bs {\n\t\t\t\trv.Index(i).SetUint(uint64(b))\n\t\t\t}\n\t\t\treturn offset, nil\n\t\t}\n\t\t// string to bytes\n\t\tif d.isCodeString(d.data[offset]) {\n\t\t\tl, offset, err := d.stringByteLength(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tif l > rv.Len() {\n\t\t\t\treturn 0, fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), l, def.ErrNotMatchArrayElement)\n\t\t\t}\n\t\t\tbs, offset, err := d.asStringByteByLength(offset, l, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tfor i, b := range bs {\n\t\t\t\trv.Index(i).SetUint(uint64(b))\n\t\t\t}\n\t\t\treturn offset, nil\n\t\t}\n\n\t\t// get slice length\n\t\tl, o, err := d.sliceLength(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tif l > rv.Len() {\n\t\t\treturn 0, fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), l, def.ErrNotMatchArrayElement)\n\t\t}\n\n\t\tif err = d.hasRequiredLeastSliceSize(o, l); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// create array dynamically\n\t\tfor i := 0; i < l; i++ {\n\t\t\to, err = d.decode(rv.Index(i), o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\toffset = o\n\n\tcase reflect.Map:\n\t\t// nil\n\t\tif d.isCodeNil(d.data[offset]) {\n\t\t\toffset++\n\t\t\treturn offset, nil\n\t\t}\n\n\t\t// get map length\n\t\tl, o, err := d.mapLength(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\tif err = d.hasRequiredLeastMapSize(o, l); err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// check fixed type\n\t\tfixedOffset, found, err := d.asFixedMap(rv, o, l)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif found {\n\t\t\treturn fixedOffset, nil\n\t\t}\n\n\t\t// create dynamically\n\t\tkey := rv.Type().Key()\n\t\tvalue := rv.Type().Elem()\n\t\tif rv.IsNil() {\n\t\t\trv.Set(reflect.MakeMapWithSize(rv.Type(), l))\n\t\t}\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk := reflect.New(key).Elem()\n\t\t\tv := reflect.New(value).Elem()\n\t\t\to, err = d.decode(k, o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\to, err = d.decode(v, o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\trv.SetMapIndex(k, v)\n\t\t}\n\t\toffset = o\n\n\tcase reflect.Struct:\n\t\to, err := d.setStruct(rv, offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\toffset = o\n\n\tcase reflect.Ptr:\n\t\t// nil\n\t\tif d.isCodeNil(d.data[offset]) {\n\t\t\toffset++\n\t\t\treturn offset, nil\n\t\t}\n\n\t\tif rv.Elem().Kind() == reflect.Invalid {\n\t\t\tn := reflect.New(rv.Type().Elem())\n\t\t\trv.Set(n)\n\t\t}\n\n\t\to, err := d.decode(rv.Elem(), offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\toffset = o\n\n\tcase reflect.Interface:\n\t\tif rv.Elem().Kind() == reflect.Ptr {\n\t\t\to, err := d.decode(rv.Elem(), offset)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\toffset = o\n\t\t} else {\n\t\t\tv, o, err := d.asInterface(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tif v != nil {\n\t\t\t\trv.Set(reflect.ValueOf(v))\n\t\t\t}\n\t\t\toffset = o\n\t\t}\n\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"%v is %w type\", rv.Kind(), def.ErrUnsupportedType)\n\t}\n\treturn offset, nil\n}\n\nfunc (d *decoder) errorTemplate(code byte, k reflect.Kind) error {\n\treturn fmt.Errorf(\"%w %x decoding as %v\", def.ErrCanNotDecode, code, k)\n}\n"
  },
  {
    "path": "internal/decoding/decoding_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\ntype AsXXXTestCase[T any] struct {\n\tName           string\n\tData           []byte\n\tExpected       T\n\tError          error\n\tMethodAs       func(d *decoder) func(int, reflect.Kind) (T, int, error)\n\tMethodAsCustom func(d *decoder) (int, T, error)\n}\n\ntype AsXXXTestCases[T any] []AsXXXTestCase[T]\n\nfunc (tcs AsXXXTestCases[T]) Run(t *testing.T) {\n\tfor _, tc := range tcs {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc (tc *AsXXXTestCase[T]) Run(t *testing.T) {\n\tconst kind = reflect.String\n\tt.Helper()\n\n\tif tc.MethodAs == nil && tc.MethodAsCustom == nil {\n\t\tt.Fatal(\"must set either method or MethodAsCustom\")\n\t}\n\n\tmethodAs := func(d *decoder) (T, int, error) {\n\t\tif tc.MethodAs != nil {\n\t\t\treturn tc.MethodAs(d)(0, kind)\n\t\t}\n\t\tif tc.MethodAsCustom != nil {\n\t\t\tv, o, err := tc.MethodAsCustom(d)\n\t\t\treturn o, v, err\n\t\t}\n\t\tpanic(\"unreachable\")\n\t}\n\n\tt.Run(tc.Name, func(t *testing.T) {\n\t\td := decoder{\n\t\t\tdata: tc.Data,\n\t\t}\n\n\t\tv, offset, err := methodAs(&d)\n\t\tif tc.Error != nil {\n\t\t\ttu.IsError(t, err, tc.Error)\n\t\t\treturn\n\t\t}\n\t\ttu.NoError(t, err)\n\t\ttu.Equal(t, v, tc.Expected)\n\t\ttu.Equal(t, offset, len(tc.Data))\n\t})\n}\n\nfunc TestDecoding(t *testing.T) {\n\tt.Run(\"empty data\", func(t *testing.T) {\n\t\tv := new(int)\n\t\terr := Decode(nil, v, false)\n\t\ttu.IsError(t, err, def.ErrNoData)\n\t})\n\tt.Run(\"not pointer\", func(t *testing.T) {\n\t\tv := 0\n\t\terr := Decode([]byte{def.PositiveFixIntMax}, v, false)\n\t\ttu.IsError(t, err, def.ErrReceiverNotPointer)\n\t})\n\tt.Run(\"left data\", func(t *testing.T) {\n\t\tv := new(int)\n\t\terr := Decode([]byte{def.PositiveFixIntMin, 0}, v, false)\n\t\ttu.IsError(t, err, def.ErrHasLeftOver)\n\t})\n}\n\nfunc Test_decodeWithCode(t *testing.T) {\n\tvar target any\n\tmethod := func(d *decoder) func(offset int, _ reflect.Kind) (bool, int, error) {\n\t\treturn func(offset int, _ reflect.Kind) (bool, int, error) {\n\t\t\trv := reflect.ValueOf(target)\n\t\t\to, err := d.decode(rv.Elem(), offset)\n\t\t\treturn true, o, err\n\t\t}\n\t}\n\n\tt.Run(\"Int\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Int8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Int8, 5},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 5)\n\t})\n\tt.Run(\"Uint\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Uint8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Uint8, 5},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(uint)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 5)\n\t})\n\tt.Run(\"Float32\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Float32},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Float32, 63, 128, 0, 0},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(float32)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 1)\n\t})\n\tt.Run(\"Float64\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Float64},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(float64)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 1)\n\t})\n\tt.Run(\"BinString\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Bin8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Bin8, 1, 'a'},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(string)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, \"a\")\n\t})\n\tt.Run(\"String\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Str8},\n\t\t\t\tExpected: false,\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Str8, 1, 'b'},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(string)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, \"b\")\n\t})\n\tt.Run(\"Bool\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Int8},\n\t\t\t\tError:    def.ErrCanNotDecode,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.True},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(bool)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, true)\n\t})\n\tt.Run(\"Slice.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Nil},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, nil)\n\t})\n\tt.Run(\"Slice.bin\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Bin8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Bin8, 1, 2},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []byte{2})\n\t})\n\tt.Run(\"Slice.string\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Str8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.bytelen\",\n\t\t\t\tData:     []byte{def.Str8, 1},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Str8, 1, 'c'},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []byte{'c'})\n\t})\n\tt.Run(\"Slice.fixed\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Array16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.require\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.slice\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.Int8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []int{3})\n\t})\n\tt.Run(\"Slice.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Array16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.require\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.slice\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.Map16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.struct\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new([]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []st{{V: 3}})\n\t})\n\tt.Run(\"Slice.map\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Array16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.require\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.slice\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.Map16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.map\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []map[string]int{{\"v\": 3}})\n\t})\n\tt.Run(\"Complex64\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Fixext8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(complex64)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, complex(1, 1))\n\t})\n\tt.Run(\"Complex128\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Fixext8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Fixext8, byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(complex128)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, complex(1, 1))\n\t})\n\n\tt.Run(\"Array.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Nil},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]int{})\n\t})\n\tt.Run(\"Array.bin\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.bin\",\n\t\t\t\tData:     []byte{def.Bin8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.len\",\n\t\t\t\tData:     []byte{def.Bin8, 2, 1, 2},\n\t\t\t\tError:    def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Bin8, 1, 2},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]byte{2})\n\t})\n\tt.Run(\"Array.string\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Str8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.compare\",\n\t\t\t\tData:     []byte{def.Str8, 2},\n\t\t\t\tError:    def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.bytelen\",\n\t\t\t\tData:     []byte{def.Str8, 1},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Str8, 1, 'c'},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]byte{'c'})\n\t})\n\tt.Run(\"Array.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Array16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.len.match\",\n\t\t\t\tData:     []byte{def.Array16, 0, 2},\n\t\t\t\tError:    def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.slice\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.struct\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new([1]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]st{{V: 3}})\n\t})\n\tt.Run(\"Map.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Nil},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, nil)\n\t})\n\tt.Run(\"Map.fixed\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Map16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.require\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToMap,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.map\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.Str16, 0},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'a', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, map[string]int{\"a\": 3})\n\t})\n\tt.Run(\"Map.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error.strlen\",\n\t\t\t\tData:     []byte{def.Map16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.require\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToMap,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.key\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.Str16, 0},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.value\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'a', def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tExpected: true,\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'a', def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new(map[string]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, map[string]st{\"a\": {V: 3}})\n\t})\n\tt.Run(\"Struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Map16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new(st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, st{V: 3})\n\t})\n\tt.Run(\"Ptr.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Nil},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 0)\n\t})\n\tt.Run(\"Ptr\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Int8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Int8, 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 3)\n\t})\n\tt.Run(\"Interface.ptr\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Int8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Int8, 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\tv := (any)(new(int))\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\tvv := v.(*int)\n\t\ttu.Equal(t, *vv, 3)\n\t})\n\tt.Run(\"Interface\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:     \"error\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'v', def.Int8},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'v', def.Int8, 3},\n\t\t\t\tExpected: true,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV any `msgpack:\"v\"`\n\t\t}\n\t\tv := new(st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\tvar vv any = int8(3)\n\t\ttu.Equal(t, v.V, vv)\n\t})\n}\n"
  },
  {
    "path": "internal/decoding/ext.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nvar (\n\textCoderMap = map[int8]ext.Decoder{time.Decoder.Code(): time.Decoder}\n\textCoders   = []ext.Decoder{time.Decoder}\n)\n\n// AddExtDecoder adds decoders for extension types.\nfunc AddExtDecoder(f ext.Decoder) {\n\t// ignore time\n\tif f.Code() == time.Decoder.Code() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Code()]\n\tif !ok {\n\t\textCoderMap[f.Code()] = f\n\t\tupdateExtCoders()\n\t}\n}\n\n// RemoveExtDecoder removes decoders for extension types.\nfunc RemoveExtDecoder(f ext.Decoder) {\n\t// ignore time\n\tif f.Code() == time.Decoder.Code() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Code()]\n\tif ok {\n\t\tdelete(extCoderMap, f.Code())\n\t\tupdateExtCoders()\n\t}\n}\n\nfunc updateExtCoders() {\n\textCoders = make([]ext.Decoder, len(extCoderMap))\n\ti := 0\n\tfor k := range extCoderMap {\n\t\textCoders[i] = extCoderMap[k]\n\t\ti++\n\t}\n}\n\nfunc (d *decoder) extEndOffset(offset int) (bool, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn false, 0, err\n\t}\n\treturn d.extEndOffsetWithCode(code, offset)\n}\n\nfunc (d *decoder) extEndOffsetWithCode(code byte, offset int) (bool, int, error) {\n\tswitch code {\n\tcase def.Fixext1:\n\t\t_, offset, err := d.readSizeN(offset, def.Byte1+def.Byte1)\n\t\treturn true, offset, err\n\tcase def.Fixext2:\n\t\t_, offset, err := d.readSizeN(offset, def.Byte1+def.Byte2)\n\t\treturn true, offset, err\n\tcase def.Fixext4:\n\t\t_, offset, err := d.readSizeN(offset, def.Byte1+def.Byte4)\n\t\treturn true, offset, err\n\tcase def.Fixext8:\n\t\t_, offset, err := d.readSizeN(offset, def.Byte1+def.Byte8)\n\t\treturn true, offset, err\n\tcase def.Fixext16:\n\t\t_, offset, err := d.readSizeN(offset, def.Byte1+def.Byte16)\n\t\treturn true, offset, err\n\tcase def.Ext8:\n\t\tsize, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn true, 0, err\n\t\t}\n\t\t_, offset, err = d.readSizeN(offset, def.Byte1+int(size))\n\t\treturn true, offset, err\n\tcase def.Ext16:\n\t\tsizeBytes, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn true, 0, err\n\t\t}\n\t\t_, offset, err = d.readSizeN(offset, def.Byte1+int(binary.BigEndian.Uint16(sizeBytes)))\n\t\treturn true, offset, err\n\tcase def.Ext32:\n\t\tsizeBytes, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn true, 0, err\n\t\t}\n\t\t_, offset, err = d.readSizeN(offset, def.Byte1+int(binary.BigEndian.Uint32(sizeBytes)))\n\t\treturn true, offset, err\n\tdefault:\n\t\treturn false, 0, nil\n\t}\n}\n\n/*\nvar zero = time.Unix(0,0)\n\nfunc (d *decoder) isDateTime(offset int) bool {\n\tcode, offset := d.readSize1(offset)\n\n\tif code == def.Fixext4 {\n\t\tt, _ := d.readSize1(offset)\n\t\treturn int8(t) == def.TimeStamp\n\t} else if code == def.Fixext8 {\n\t\tt, _ := d.readSize1(offset)\n\t\treturn int8(t) == def.TimeStamp\n\t} else if code == def.Ext8 {\n\t\tl, offset := d.readSize1(offset)\n\t\tt, _ := d.readSize1(offset)\n\t\treturn l == 12 && int8(t) == def.TimeStamp\n\t}\n\treturn false\n}\n\nfunc (d *decoder) asDateTime(offset int, k reflect.Kind) (time.Time, int, error) {\n\tcode, offset := d.readSize1(offset)\n\n\tswitch code {\n\tcase def.Fixext4:\n\t\t_, offset = d.readSize1(offset)\n\t\tbs, offset := d.readSize4(offset)\n\t\treturn time.Unix(int64(binary.BigEndian.Uint32(bs)), 0), offset, nil\n\n\tcase def.Fixext8:\n\t\t_, offset = d.readSize1(offset)\n\t\tbs, offset := d.readSize8(offset)\n\t\tdata64 := binary.BigEndian.Uint64(bs)\n\t\tnano := int64(data64 >> 34)\n\t\tif nano > 999999999 {\n\t\t\treturn zero, 0, fmt.Errorf(\"In timestamp 64 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\treturn time.Unix(int64(data64&0x00000003ffffffff), nano), offset, nil\n\n\tcase def.Ext8:\n\t\t_, offset = d.readSize1(offset)\n\t\t_, offset = d.readSize1(offset)\n\t\tnanobs, offset := d.readSize4(offset)\n\t\tsecbs, offset := d.readSize8(offset)\n\t\tnano := binary.BigEndian.Uint32(nanobs)\n\t\tif nano > 999999999 {\n\t\t\treturn zero, 0, fmt.Errorf(\"In timestamp 96 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\tsec := binary.BigEndian.Uint64(secbs)\n\t\treturn time.Unix(int64(sec), int64(nano)), offset, nil\n\t}\n\n\treturn zero, 0, d.errorTemplate(code, k)\n}\n*/\n"
  },
  {
    "path": "internal/decoding/ext_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nfunc Test_AddExtDecoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tAddExtDecoder(time.Decoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\nfunc Test_RemoveExtDecoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tRemoveExtDecoder(time.Decoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\ntype trackingExtDecoder struct {\n\tisTypeCalls  int\n\tasValueCalls int\n}\n\nfunc (td *trackingExtDecoder) Code() int8 {\n\treturn 42\n}\n\nfunc (td *trackingExtDecoder) IsType(_ int, _ *[]byte) bool {\n\ttd.isTypeCalls++\n\treturn false\n}\n\nfunc (td *trackingExtDecoder) AsValue(_ int, _ reflect.Kind, _ *[]byte) (interface{}, int, error) {\n\ttd.asValueCalls++\n\treturn nil, 0, ErrTestExtDecoder\n}\n\nfunc TestExtValidationRejectsTruncatedBytesBeforeCustomDecoders(t *testing.T) {\n\tdec := &trackingExtDecoder{}\n\tAddExtDecoder(dec)\n\tdefer RemoveExtDecoder(dec)\n\n\ttestcases := []struct {\n\t\tname string\n\t\tdata []byte\n\t}{\n\t\t{name: \"fixext1\", data: []byte{def.Fixext1, 42}},\n\t\t{name: \"fixext2\", data: []byte{def.Fixext2, 42, 0}},\n\t\t{name: \"fixext4\", data: []byte{def.Fixext4, 42, 0, 0, 0}},\n\t\t{name: \"fixext8\", data: []byte{def.Fixext8, 42, 0, 0, 0, 0, 0, 0, 0}},\n\t\t{name: \"fixext16\", data: []byte{def.Fixext16, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},\n\t\t{name: \"ext8\", data: []byte{def.Ext8, 1, 42}},\n\t\t{name: \"ext16\", data: []byte{def.Ext16, 0, 1, 42}},\n\t\t{name: \"ext32\", data: []byte{def.Ext32, 0, 0, 0, 1, 42}},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(\"interface/\"+tc.name, func(t *testing.T) {\n\t\t\tdec.isTypeCalls = 0\n\t\t\tdec.asValueCalls = 0\n\n\t\t\td := decoder{data: tc.data}\n\t\t\t_, _, err := d.asInterface(0, reflect.Interface)\n\t\t\ttu.IsError(t, err, def.ErrTooShortBytes)\n\t\t\ttu.Equal(t, dec.isTypeCalls, 0)\n\t\t\ttu.Equal(t, dec.asValueCalls, 0)\n\t\t})\n\n\t\tt.Run(\"struct/\"+tc.name, func(t *testing.T) {\n\t\t\tdec.isTypeCalls = 0\n\t\t\tdec.asValueCalls = 0\n\n\t\t\td := decoder{data: tc.data}\n\t\t\tvar v struct{}\n\t\t\t_, err := d.setStruct(reflect.ValueOf(&v).Elem(), 0, reflect.Struct)\n\t\t\ttu.IsError(t, err, def.ErrTooShortBytes)\n\t\t\ttu.Equal(t, dec.isTypeCalls, 0)\n\t\t\ttu.Equal(t, dec.asValueCalls, 0)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/decoding/float.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asFloat32(offset int, k reflect.Kind) (float32, int, error) {\n\tcode, _, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase code == def.Float32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := math.Float32frombits(binary.BigEndian.Uint32(bs))\n\t\treturn v, offset, nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn float32(v), offset, nil\n\n\tcase d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn float32(v), offset, nil\n\n\tcase code == def.Nil:\n\t\toffset++\n\t\treturn 0, offset, nil\n\t}\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asFloat64(offset int, k reflect.Kind) (float64, int, error) {\n\tcode, _, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase code == def.Float64:\n\t\toffset++\n\t\tbs, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := math.Float64frombits(binary.BigEndian.Uint64(bs))\n\t\treturn v, offset, nil\n\n\tcase code == def.Float32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := math.Float32frombits(binary.BigEndian.Uint32(bs))\n\t\treturn float64(v), offset, nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn float64(v), offset, nil\n\n\tcase d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn float64(v), offset, nil\n\n\tcase code == def.Nil:\n\t\toffset++\n\t\treturn 0, offset, nil\n\t}\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/decoding/float_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asFloat32(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (float32, int, error) {\n\t\treturn d.asFloat32\n\t}\n\ttestcases := AsXXXTestCases[float32]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.error\",\n\t\t\tData:     []byte{def.Float32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.ok\",\n\t\t\tData:     []byte{def.Float32, 63, 128, 0, 0},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"PositiveFixNum.ok\",\n\t\t\tData:     []byte{def.PositiveFixIntMin + 1},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.error\",\n\t\t\tData:     []byte{def.Uint8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.ok\",\n\t\t\tData:     []byte{def.Uint8, 1},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.error\",\n\t\t\tData:     []byte{def.Uint16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.ok\",\n\t\t\tData:     []byte{def.Uint16, 0, 1},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.error\",\n\t\t\tData:     []byte{def.Uint32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.ok\",\n\t\t\tData:     []byte{def.Uint32, 0, 0, 0, 1},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.error\",\n\t\t\tData:     []byte{def.Uint64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.ok\",\n\t\t\tData:     []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected: float32(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"NegativeFixNum.ok\",\n\t\t\tData:     []byte{0xff},\n\t\t\tExpected: float32(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.error\",\n\t\t\tData:     []byte{def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.ok\",\n\t\t\tData:     []byte{def.Int8, 0xff},\n\t\t\tExpected: float32(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.error\",\n\t\t\tData:     []byte{def.Int16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.ok\",\n\t\t\tData:     []byte{def.Int16, 0xff, 0xff},\n\t\t\tExpected: float32(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.error\",\n\t\t\tData:     []byte{def.Int32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.ok\",\n\t\t\tData:     []byte{def.Int32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: float32(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.error\",\n\t\t\tData:     []byte{def.Int64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.ok\",\n\t\t\tData:     []byte{def.Int64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: float32(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Nil.ok\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tExpected: float32(0),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asFloat64(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (float64, int, error) {\n\t\treturn d.asFloat64\n\t}\n\ttestcases := AsXXXTestCases[float64]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.error\",\n\t\t\tData:     []byte{def.Float64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.ok\",\n\t\t\tData:     []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.error\",\n\t\t\tData:     []byte{def.Float32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.ok\",\n\t\t\tData:     []byte{def.Float32, 63, 128, 0, 0},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"PositiveFixNum.ok\",\n\t\t\tData:     []byte{def.PositiveFixIntMin + 1},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.error\",\n\t\t\tData:     []byte{def.Uint8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.ok\",\n\t\t\tData:     []byte{def.Uint8, 1},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.error\",\n\t\t\tData:     []byte{def.Uint16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.ok\",\n\t\t\tData:     []byte{def.Uint16, 0, 1},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.error\",\n\t\t\tData:     []byte{def.Uint32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.ok\",\n\t\t\tData:     []byte{def.Uint32, 0, 0, 0, 1},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.error\",\n\t\t\tData:     []byte{def.Uint64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.ok\",\n\t\t\tData:     []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected: float64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"NegativeFixNum.ok\",\n\t\t\tData:     []byte{0xff},\n\t\t\tExpected: float64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.error\",\n\t\t\tData:     []byte{def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.ok\",\n\t\t\tData:     []byte{def.Int8, 0xff},\n\t\t\tExpected: float64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.error\",\n\t\t\tData:     []byte{def.Int16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.ok\",\n\t\t\tData:     []byte{def.Int16, 0xff, 0xff},\n\t\t\tExpected: float64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.error\",\n\t\t\tData:     []byte{def.Int32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.ok\",\n\t\t\tData:     []byte{def.Int32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: float64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.error\",\n\t\t\tData:     []byte{def.Int64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.ok\",\n\t\t\tData:     []byte{def.Int64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: float64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Nil.ok\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tExpected: float64(0),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/int.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) isPositiveFixNum(v byte) bool {\n\treturn def.PositiveFixIntMin <= v && v <= def.PositiveFixIntMax\n}\n\nfunc (d *decoder) isNegativeFixNum(v byte) bool {\n\treturn def.NegativeFixintMin <= int8(v) && int8(v) <= def.NegativeFixintMax\n}\n\nfunc (d *decoder) asInt(offset int, k reflect.Kind) (int64, int, error) {\n\tcode, _, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase d.isPositiveFixNum(code):\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(b), offset, nil\n\n\tcase d.isNegativeFixNum(code):\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(int8(b)), offset, nil\n\n\tcase code == def.Uint8:\n\t\toffset++\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(uint8(b)), offset, nil\n\n\tcase code == def.Int8:\n\t\toffset++\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(int8(b)), offset, nil\n\n\tcase code == def.Uint16:\n\t\toffset++\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint16(bs)\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Int16:\n\t\toffset++\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := int16(binary.BigEndian.Uint16(bs))\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Uint32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint32(bs)\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Int32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := int32(binary.BigEndian.Uint32(bs))\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Uint64:\n\t\toffset++\n\t\tbs, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(binary.BigEndian.Uint64(bs)), offset, nil\n\n\tcase code == def.Int64:\n\t\toffset++\n\t\tbs, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(binary.BigEndian.Uint64(bs)), offset, nil\n\n\tcase code == def.Float32:\n\t\tv, offset, err := d.asFloat32(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Float64:\n\t\tv, offset, err := d.asFloat64(offset, k)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int64(v), offset, nil\n\n\tcase code == def.Nil:\n\t\toffset++\n\t\treturn 0, offset, nil\n\t}\n\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/decoding/int_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asInt(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (int64, int, error) {\n\t\treturn d.asInt\n\t}\n\ttestcases := AsXXXTestCases[int64]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"PositiveFixNum.ok\",\n\t\t\tData:     []byte{def.PositiveFixIntMin + 1},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.error\",\n\t\t\tData:     []byte{def.Uint8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.ok\",\n\t\t\tData:     []byte{def.Uint8, 1},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.error\",\n\t\t\tData:     []byte{def.Uint16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.ok\",\n\t\t\tData:     []byte{def.Uint16, 0, 1},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.error\",\n\t\t\tData:     []byte{def.Uint32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.ok\",\n\t\t\tData:     []byte{def.Uint32, 0, 0, 0, 1},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.error\",\n\t\t\tData:     []byte{def.Uint64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.ok\",\n\t\t\tData:     []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"NegativeFixNum.ok\",\n\t\t\tData:     []byte{0xff},\n\t\t\tExpected: int64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.error\",\n\t\t\tData:     []byte{def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.ok\",\n\t\t\tData:     []byte{def.Int8, 0xff},\n\t\t\tExpected: int64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.error\",\n\t\t\tData:     []byte{def.Int16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.ok\",\n\t\t\tData:     []byte{def.Int16, 0xff, 0xff},\n\t\t\tExpected: int64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.error\",\n\t\t\tData:     []byte{def.Int32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.ok\",\n\t\t\tData:     []byte{def.Int32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: int64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.error\",\n\t\t\tData:     []byte{def.Int64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.ok\",\n\t\t\tData:     []byte{def.Int64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: int64(-1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.error\",\n\t\t\tData:     []byte{def.Float32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.ok\",\n\t\t\tData:     []byte{def.Float32, 63, 128, 0, 0},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.error\",\n\t\t\tData:     []byte{def.Float64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.ok\",\n\t\t\tData:     []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\tExpected: int64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Nil.ok\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tExpected: int64(0),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/interface.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asInterface(offset int, k reflect.Kind) (interface{}, int, error) {\n\tcode, _, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase code == def.Nil:\n\t\toffset++\n\t\treturn nil, offset, nil\n\n\tcase code == def.True, code == def.False:\n\t\tv, offset, err := d.asBool(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn uint8(v), offset, err\n\tcase code == def.Uint16:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn uint16(v), offset, err\n\tcase code == def.Uint32:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn uint32(v), offset, err\n\tcase code == def.Uint64:\n\t\tv, offset, err := d.asUint(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\n\tcase d.isNegativeFixNum(code), code == def.Int8:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn int8(v), offset, err\n\tcase code == def.Int16:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn int16(v), offset, err\n\tcase code == def.Int32:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn int32(v), offset, err\n\tcase code == def.Int64:\n\t\tv, offset, err := d.asInt(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\n\tcase code == def.Float32:\n\t\tv, offset, err := d.asFloat32(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\tcase code == def.Float64:\n\t\tv, offset, err := d.asFloat64(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\n\tcase d.isFixString(code), code == def.Str8, code == def.Str16, code == def.Str32:\n\t\tv, offset, err := d.asString(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\n\tcase code == def.Bin8, code == def.Bin16, code == def.Bin32:\n\t\tv, offset, err := d.asBin(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, err\n\n\tcase d.isFixSlice(code), code == def.Array16, code == def.Array32:\n\t\tl, o, err := d.sliceLength(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tif err = d.hasRequiredLeastSliceSize(o, l); err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\n\t\tv := make([]interface{}, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tvv, o2, err := d.asInterface(o, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tv[i] = vv\n\t\t\to = o2\n\t\t}\n\t\toffset = o\n\t\treturn v, offset, nil\n\n\tcase d.isFixMap(code), code == def.Map16, code == def.Map32:\n\t\tl, o, err := d.mapLength(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tif err = d.hasRequiredLeastMapSize(o, l); err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\tv := make(map[interface{}]interface{}, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err := d.canSetAsMapKey(o); err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tkey, o2, err := d.asInterface(o, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tvalue, o2, err := d.asInterface(o2, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, 0, err\n\t\t\t}\n\t\t\tv[key] = value\n\t\t\to = o2\n\t\t}\n\t\toffset = o\n\t\treturn v, offset, nil\n\t}\n\n\t/* use ext\n\tif d.isDateTime(offset) {\n\t\tv, offset, err := d.asDateTime(offset, k)\n\t\tif err != nil {\n\t\t\treturn nil, 0, err\n\t\t}\n\t\treturn v, offset, nil\n\t}\n\t*/\n\n\t// ext\n\tisExt, _, err := d.extEndOffset(offset)\n\tif err != nil {\n\t\treturn nil, 0, err\n\t}\n\tif isExt {\n\t\tfor i := range extCoders {\n\t\t\tif extCoders[i].IsType(offset, &d.data) {\n\t\t\t\tv, offset, err := extCoders[i].AsValue(offset, k, &d.data)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, 0, err\n\t\t\t\t}\n\t\t\t\treturn v, offset, nil\n\t\t\t}\n\t\t}\n\t}\n\treturn nil, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) canSetAsMapKey(index int) error {\n\tcode, _, err := d.readSize1(index)\n\tif err != nil {\n\t\treturn err\n\t}\n\tswitch {\n\tcase d.isFixSlice(code), code == def.Array16, code == def.Array32:\n\t\treturn fmt.Errorf(\"%w. code: %x\", def.ErrCanNotSetSliceAsMapKey, code)\n\tcase d.isFixMap(code), code == def.Map16, code == def.Map32:\n\t\treturn fmt.Errorf(\"%w. code: %x\", def.ErrCanNotSetMapAsMapKey, code)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/decoding/interface_test.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nfunc Test_asInterfaceWithCode(t *testing.T) {\n\tdec := testExt2Decoder{}\n\tAddExtDecoder(&dec)\n\tdefer RemoveExtDecoder(&dec)\n\n\tmethod := func(d *decoder) func(int, reflect.Kind) (any, int, error) {\n\t\treturn d.asInterface\n\t}\n\ttestcases := AsXXXTestCases[any]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.error\",\n\t\t\tData:     []byte{def.Uint8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.error\",\n\t\t\tData:     []byte{def.Uint16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.error\",\n\t\t\tData:     []byte{def.Uint32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.error\",\n\t\t\tData:     []byte{def.Uint64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.error\",\n\t\t\tData:     []byte{def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.error\",\n\t\t\tData:     []byte{def.Int16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.error\",\n\t\t\tData:     []byte{def.Int32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.error\",\n\t\t\tData:     []byte{def.Int64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.error\",\n\t\t\tData:     []byte{def.Float32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.error\",\n\t\t\tData:     []byte{def.Float64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str.error\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin.error\",\n\t\t\tData:     []byte{def.Bin8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array.error.length\",\n\t\t\tData:     []byte{def.Array16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array.error.required\",\n\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array.error.set\",\n\t\t\tData:     []byte{def.Array16, 0, 1, def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.length\",\n\t\t\tData:     []byte{def.Map16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.required\",\n\t\t\tData:     []byte{def.Map16, 0, 1},\n\t\t\tError:    def.ErrLackDataLengthToMap,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.set.can.slice\",\n\t\t\tData:     []byte{def.Map16, 0, 1, def.Array16, 0},\n\t\t\tError:    def.ErrCanNotSetSliceAsMapKey,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.set.can.map\",\n\t\t\tData:     []byte{def.Map16, 0, 1, def.Map16, 0},\n\t\t\tError:    def.ErrCanNotSetMapAsMapKey,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.set.key\",\n\t\t\tData:     []byte{def.Map16, 0, 1, def.Str8, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map.error.set.value\",\n\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'a'},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"ExtCoder.error.truncated\",\n\t\t\tData:     []byte{def.Fixext1, 3},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"ExtCoder.error\",\n\t\t\tData:     []byte{def.Fixext1, 3, 0},\n\t\t\tError:    ErrTestExtDecoder,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\n// TODO: to testutil\ntype testExt2Decoder struct {\n\text.DecoderCommon\n}\n\nvar _ ext.Decoder = (*testExt2Decoder)(nil)\n\nfunc (td *testExt2Decoder) Code() int8 {\n\treturn 3\n}\n\nfunc (td *testExt2Decoder) IsType(o int, d *[]byte) bool {\n\t// todo : lack of error handling\n\tcode, _ := td.ReadSize1(o, d)\n\tif code == def.Fixext1 {\n\t\textCode, _ := td.ReadSize1(o+1, d)\n\t\treturn int8(extCode) == td.Code()\n\t}\n\treturn false\n}\n\nvar ErrTestExtDecoder = fmt.Errorf(\"testExtDecoder\")\n\nfunc (td *testExt2Decoder) AsValue(_ int, _ reflect.Kind, _ *[]byte) (any, int, error) {\n\treturn nil, 0, ErrTestExtDecoder\n}\n"
  },
  {
    "path": "internal/decoding/map.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\ttypeMapStringInt   = reflect.TypeOf(map[string]int{})\n\ttypeMapStringInt8  = reflect.TypeOf(map[string]int8{})\n\ttypeMapStringInt16 = reflect.TypeOf(map[string]int16{})\n\ttypeMapStringInt32 = reflect.TypeOf(map[string]int32{})\n\ttypeMapStringInt64 = reflect.TypeOf(map[string]int64{})\n\n\ttypeMapStringUint   = reflect.TypeOf(map[string]uint{})\n\ttypeMapStringUint8  = reflect.TypeOf(map[string]uint8{})\n\ttypeMapStringUint16 = reflect.TypeOf(map[string]uint16{})\n\ttypeMapStringUint32 = reflect.TypeOf(map[string]uint32{})\n\ttypeMapStringUint64 = reflect.TypeOf(map[string]uint64{})\n\n\ttypeMapStringFloat32 = reflect.TypeOf(map[string]float32{})\n\ttypeMapStringFloat64 = reflect.TypeOf(map[string]float64{})\n\n\ttypeMapStringBool   = reflect.TypeOf(map[string]bool{})\n\ttypeMapStringString = reflect.TypeOf(map[string]string{})\n\n\ttypeMapIntString   = reflect.TypeOf(map[int]string{})\n\ttypeMapInt8String  = reflect.TypeOf(map[int8]string{})\n\ttypeMapInt16String = reflect.TypeOf(map[int16]string{})\n\ttypeMapInt32String = reflect.TypeOf(map[int32]string{})\n\ttypeMapInt64String = reflect.TypeOf(map[int64]string{})\n\ttypeMapIntBool     = reflect.TypeOf(map[int]bool{})\n\ttypeMapInt8Bool    = reflect.TypeOf(map[int8]bool{})\n\ttypeMapInt16Bool   = reflect.TypeOf(map[int16]bool{})\n\ttypeMapInt32Bool   = reflect.TypeOf(map[int32]bool{})\n\ttypeMapInt64Bool   = reflect.TypeOf(map[int64]bool{})\n\n\ttypeMapUintString   = reflect.TypeOf(map[uint]string{})\n\ttypeMapUint8String  = reflect.TypeOf(map[uint8]string{})\n\ttypeMapUint16String = reflect.TypeOf(map[uint16]string{})\n\ttypeMapUint32String = reflect.TypeOf(map[uint32]string{})\n\ttypeMapUint64String = reflect.TypeOf(map[uint64]string{})\n\ttypeMapUintBool     = reflect.TypeOf(map[uint]bool{})\n\ttypeMapUint8Bool    = reflect.TypeOf(map[uint8]bool{})\n\ttypeMapUint16Bool   = reflect.TypeOf(map[uint16]bool{})\n\ttypeMapUint32Bool   = reflect.TypeOf(map[uint32]bool{})\n\ttypeMapUint64Bool   = reflect.TypeOf(map[uint64]bool{})\n\n\ttypeMapFloat32String = reflect.TypeOf(map[float32]string{})\n\ttypeMapFloat64String = reflect.TypeOf(map[float64]string{})\n\ttypeMapFloat32Bool   = reflect.TypeOf(map[float32]bool{})\n\ttypeMapFloat64Bool   = reflect.TypeOf(map[float64]bool{})\n)\n\nfunc (d *decoder) isFixMap(v byte) bool {\n\treturn def.FixMap <= v && v <= def.FixMap+0x0f\n}\n\nfunc (d *decoder) mapLength(offset int, k reflect.Kind) (int, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase d.isFixMap(code):\n\t\treturn int(code - def.FixMap), offset, nil\n\tcase code == def.Map16:\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(bs)), offset, nil\n\tcase code == def.Map32:\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(bs)), offset, nil\n\t}\n\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) hasRequiredLeastMapSize(offset, length int) error {\n\t// minimum check (byte length)\n\tif len(d.data[offset:]) < length*2 {\n\t\treturn def.ErrLackDataLengthToMap\n\t}\n\treturn nil\n}\n\nfunc (d *decoder) asFixedMap(rv reflect.Value, offset int, l int) (int, bool, error) {\n\tt := rv.Type()\n\n\tkeyKind := t.Key().Kind()\n\tvalueKind := t.Elem().Kind()\n\n\tswitch t {\n\tcase typeMapStringInt:\n\t\tm := make(map[string]int, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asInt(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = int(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringUint:\n\t\tm := make(map[string]uint, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asUint(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = uint(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringFloat32:\n\t\tm := make(map[string]float32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asFloat32(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringFloat64:\n\t\tm := make(map[string]float64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asFloat64(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringBool:\n\t\tm := make(map[string]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringString:\n\t\tm := make(map[string]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringInt8:\n\t\tm := make(map[string]int8, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asInt(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = int8(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringInt16:\n\t\tm := make(map[string]int16, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asInt(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = int16(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringInt32:\n\t\tm := make(map[string]int32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asInt(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = int32(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringInt64:\n\t\tm := make(map[string]int64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asInt(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringUint8:\n\t\tm := make(map[string]uint8, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asUint(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = uint8(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\tcase typeMapStringUint16:\n\t\tm := make(map[string]uint16, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asUint(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = uint16(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringUint32:\n\t\tm := make(map[string]uint32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asUint(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = uint32(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapStringUint64:\n\t\tm := make(map[string]uint64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asString(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asUint(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapIntString:\n\t\tm := make(map[int]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt8String:\n\t\tm := make(map[int8]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int8(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt16String:\n\t\tm := make(map[int16]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int16(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt32String:\n\t\tm := make(map[int32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int32(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt64String:\n\t\tm := make(map[int64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapIntBool:\n\t\tm := make(map[int]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt8Bool:\n\t\tm := make(map[int8]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int8(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt16Bool:\n\t\tm := make(map[int16]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int16(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt32Bool:\n\t\tm := make(map[int32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[int32(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapInt64Bool:\n\t\tm := make(map[int64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asInt(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUintString:\n\t\tm := make(map[uint]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint8String:\n\t\tm := make(map[uint8]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint8(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint16String:\n\t\tm := make(map[uint16]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint16(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint32String:\n\t\tm := make(map[uint32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint32(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint64String:\n\t\tm := make(map[uint64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUintBool:\n\t\tm := make(map[uint]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint8Bool:\n\t\tm := make(map[uint8]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint8(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint16Bool:\n\t\tm := make(map[uint16]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint16(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint32Bool:\n\t\tm := make(map[uint32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[uint32(k)] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapUint64Bool:\n\t\tm := make(map[uint64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asUint(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapFloat32String:\n\t\tm := make(map[float32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asFloat32(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapFloat64String:\n\t\tm := make(map[float64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asFloat64(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asString(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapFloat32Bool:\n\t\tm := make(map[float32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asFloat32(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\n\tcase typeMapFloat64Bool:\n\t\tm := make(map[float64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, o, err := d.asFloat64(offset, keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tv, o, err := d.asBool(o, valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn offset, true, nil\n\t}\n\n\treturn offset, false, nil\n}\n"
  },
  {
    "path": "internal/decoding/map_test.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_mapLength(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (int, int, error) {\n\t\treturn d.mapLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixMap\",\n\t\t\tData:     []byte{def.FixMap + 3},\n\t\t\tExpected: 3,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map16.error\",\n\t\t\tData:     []byte{def.Map16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map16.ok\",\n\t\t\tData:     []byte{def.Map16, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint16,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map32.error\",\n\t\t\tData:     []byte{def.Map32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map32.ok\",\n\t\t\tData:     []byte{def.Map32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint32,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asFixedMap_StringInt(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.PositiveFixIntMin + dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[string]int)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]int{\"a\": 1})\n\tv2 := new(map[string]int8)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]int8{\"a\": 2})\n\tv3 := new(map[string]int16)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[string]int16{\"a\": 3})\n\tv4 := new(map[string]int32)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[string]int32{\"a\": 4})\n\tv5 := new(map[string]int64)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[string]int64{\"a\": 5})\n}\n\nfunc Test_asFixedMap_StringUint(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Uint8, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[string]uint)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]uint{\"a\": 1})\n\tv2 := new(map[string]uint8)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]uint8{\"a\": 2})\n\tv3 := new(map[string]uint16)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[string]uint16{\"a\": 3})\n\tv4 := new(map[string]uint32)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[string]uint32{\"a\": 4})\n\tv5 := new(map[string]uint64)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[string]uint64{\"a\": 5})\n}\n\nfunc Test_asFixedMap_StringFloat(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Int16, 0, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[string]float32)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]float32{\"a\": 1})\n\tv2 := new(map[string]float64)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]float64{\"a\": 2})\n}\n\nfunc Test_asFixedMap_StringBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[string]bool)\n\trun(t, v1, def.True)\n\ttu.EqualMap(t, *v1, map[string]bool{\"a\": true})\n}\n\nfunc Test_asFixedMap_StringString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.FixStr + 1, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[string]string)\n\trun(t, v1, 'b')\n\ttu.EqualMap(t, *v1, map[string]string{\"a\": \"b\"})\n}\n\nfunc Test_asFixedMap_IntString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[int]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[int]string{1: \"b\"})\n\tv2 := new(map[int8]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[int8]string{int8(2): \"b\"})\n\tv3 := new(map[int16]string)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[int16]string{int16(3): \"b\"})\n\tv4 := new(map[int32]string)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[int32]string{int32(4): \"b\"})\n\tv5 := new(map[int64]string)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[int64]string{int64(5): \"b\"})\n}\n\nfunc Test_asFixedMap_IntBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[int]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[int]bool{1: true})\n\tv2 := new(map[int8]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[int8]bool{int8(2): true})\n\tv3 := new(map[int16]bool)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[int16]bool{int16(3): true})\n\tv4 := new(map[int32]bool)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[int32]bool{int32(4): true})\n\tv5 := new(map[int64]bool)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[int64]bool{int64(5): true})\n}\n\nfunc Test_asFixedMap_UintString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[uint]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[uint]string{1: \"b\"})\n\tv2 := new(map[uint8]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[uint8]string{uint8(2): \"b\"})\n\tv3 := new(map[uint16]string)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[uint16]string{uint16(3): \"b\"})\n\tv4 := new(map[uint32]string)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[uint32]string{uint32(4): \"b\"})\n\tv5 := new(map[uint64]string)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[uint64]string{uint64(5): \"b\"})\n}\n\nfunc Test_asFixedMap_UintBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[uint]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[uint]bool{1: true})\n\tv2 := new(map[uint8]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[uint8]bool{uint8(2): true})\n\tv3 := new(map[uint16]bool)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[uint16]bool{uint16(3): true})\n\tv4 := new(map[uint32]bool)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[uint32]bool{uint32(4): true})\n\tv5 := new(map[uint64]bool)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[uint64]bool{uint64(5): true})\n}\n\nfunc Test_asFixedMap_FloatString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[float32]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[float32]string{1: \"b\"})\n\tv2 := new(map[float64]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[float64]string{2: \"b\"})\n}\n\nfunc Test_asFixedMap_FloatBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 0, 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new(map[float32]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[float32]bool{1: true})\n\tv2 := new(map[float64]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[float64]bool{2: true})\n}\n"
  },
  {
    "path": "internal/decoding/nil.go",
    "content": "package decoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\nfunc (d *decoder) isCodeNil(v byte) bool {\n\treturn def.Nil == v\n}\n"
  },
  {
    "path": "internal/decoding/read.go",
    "content": "package decoding\n\nimport (\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) readSize1(index int) (byte, int, error) {\n\trb := def.Byte1\n\tif len(d.data) < index+rb {\n\t\treturn 0, 0, def.ErrTooShortBytes\n\t}\n\treturn d.data[index], index + rb, nil\n}\n\nfunc (d *decoder) readSize2(index int) ([]byte, int, error) {\n\treturn d.readSizeN(index, def.Byte2)\n}\n\nfunc (d *decoder) readSize4(index int) ([]byte, int, error) {\n\treturn d.readSizeN(index, def.Byte4)\n}\n\nfunc (d *decoder) readSize8(index int) ([]byte, int, error) {\n\treturn d.readSizeN(index, def.Byte8)\n}\n\nfunc (d *decoder) readSizeN(index, n int) ([]byte, int, error) {\n\tif len(d.data) < index+n {\n\t\treturn emptyBytes, 0, def.ErrTooShortBytes\n\t}\n\treturn d.data[index : index+n], index + n, nil\n}\n"
  },
  {
    "path": "internal/decoding/slice.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\ttypeIntSlice   = reflect.TypeOf([]int{})\n\ttypeInt8Slice  = reflect.TypeOf([]int8{})\n\ttypeInt16Slice = reflect.TypeOf([]int16{})\n\ttypeInt32Slice = reflect.TypeOf([]int32{})\n\ttypeInt64Slice = reflect.TypeOf([]int64{})\n\n\ttypeUintSlice   = reflect.TypeOf([]uint{})\n\ttypeUint8Slice  = reflect.TypeOf([]uint8{})\n\ttypeUint16Slice = reflect.TypeOf([]uint16{})\n\ttypeUint32Slice = reflect.TypeOf([]uint32{})\n\ttypeUint64Slice = reflect.TypeOf([]uint64{})\n\n\ttypeFloat32Slice = reflect.TypeOf([]float32{})\n\ttypeFloat64Slice = reflect.TypeOf([]float64{})\n\n\ttypeStringSlice = reflect.TypeOf([]string{})\n\n\ttypeBoolSlice = reflect.TypeOf([]bool{})\n)\n\nfunc (d *decoder) isFixSlice(v byte) bool {\n\treturn def.FixArray <= v && v <= def.FixArray+0x0f\n}\n\nfunc (d *decoder) sliceLength(offset int, k reflect.Kind) (int, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase d.isFixSlice(code):\n\t\treturn int(code - def.FixArray), offset, nil\n\tcase code == def.Array16:\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(bs)), offset, nil\n\tcase code == def.Array32:\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(bs)), offset, nil\n\t}\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) hasRequiredLeastSliceSize(offset, length int) error {\n\t// minimum check (byte length)\n\tif len(d.data[offset:]) < length {\n\t\treturn def.ErrLackDataLengthToSlice\n\t}\n\treturn nil\n}\n\nfunc (d *decoder) asFixedSlice(rv reflect.Value, offset int, l int) (int, bool, error) {\n\tt := rv.Type()\n\tk := t.Elem().Kind()\n\n\tswitch t {\n\tcase typeIntSlice:\n\t\tsli := make([]int, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asInt(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = int(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeUintSlice:\n\t\tsli := make([]uint, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asUint(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = uint(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeStringSlice:\n\t\tsli := make([]string, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asString(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeBoolSlice:\n\t\tsli := make([]bool, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asBool(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeFloat32Slice:\n\t\tsli := make([]float32, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asFloat32(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeFloat64Slice:\n\t\tsli := make([]float64, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asFloat64(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeInt8Slice:\n\t\tsli := make([]int8, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asInt(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = int8(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeInt16Slice:\n\t\tsli := make([]int16, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asInt(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = int16(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeInt32Slice:\n\t\tsli := make([]int32, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asInt(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = int32(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeInt64Slice:\n\t\tsli := make([]int64, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asInt(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeUint8Slice:\n\t\tsli := make([]uint8, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asUint(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = uint8(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeUint16Slice:\n\t\tsli := make([]uint16, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asUint(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = uint16(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeUint32Slice:\n\t\tsli := make([]uint32, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asUint(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = uint32(v)\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\n\tcase typeUint64Slice:\n\t\tsli := make([]uint64, l)\n\t\tfor i := range sli {\n\t\t\tv, o, err := d.asUint(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t\toffset = o\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn offset, true, nil\n\t}\n\n\treturn offset, false, nil\n}\n"
  },
  {
    "path": "internal/decoding/slice_test.go",
    "content": "package decoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_sliceLength(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (int, int, error) {\n\t\treturn d.sliceLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixArray\",\n\t\t\tData:     []byte{def.FixArray + 3},\n\t\t\tExpected: 3,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array16.error\",\n\t\t\tData:     []byte{def.Array16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array16.ok\",\n\t\t\tData:     []byte{def.Array16, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint16,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array32.error\",\n\t\t\tData:     []byte{def.Array32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array32.ok\",\n\t\t\tData:     []byte{def.Array32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint32,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asFixedSlice_Int(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]int)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int{3})\n}\n\nfunc Test_asFixedSlice_Int8(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 4},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int8)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int8{4})\n}\n\nfunc Test_asFixedSlice_Int16(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 5},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]int16)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int16{5})\n}\n\nfunc Test_asFixedSlice_Int32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 6},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]int32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int32{6})\n}\n\nfunc Test_asFixedSlice_Int64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 7},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]int64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int64{7})\n}\n\nfunc Test_asFixedSlice_Uint(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 5},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]uint)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint{5})\n}\n\nfunc Test_asFixedSlice_Uint8(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 6},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]uint8)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint8{6})\n}\n\nfunc Test_asFixedSlice_Uint16(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 7},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]uint16)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint16{7})\n}\n\nfunc Test_asFixedSlice_Uint32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 8},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]uint32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint32{8})\n}\n\nfunc Test_asFixedSlice_Uint64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 9},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]uint64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint64{9})\n}\n\nfunc Test_asFixedSlice_Float32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.Float32, 63, 128, 0, 0},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]float32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []float32{1})\n}\n\nfunc Test_asFixedSlice_Float64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]float64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []float64{1})\n}\n\nfunc Test_asFixedSlice_String(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 2)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]string)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []string{\"a\", \"b\"})\n}\n\nfunc Test_asFixedSlice_Bool(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (int, bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 0, 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          def.ErrTooShortBytes,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tv1 := new([]bool)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []bool{true})\n}\n"
  },
  {
    "path": "internal/decoding/string.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\temptyString = \"\"\n\temptyBytes  = []byte{}\n)\n\nfunc (d *decoder) isCodeString(code byte) bool {\n\treturn d.isFixString(code) || code == def.Str8 || code == def.Str16 || code == def.Str32\n}\n\nfunc (d *decoder) isFixString(v byte) bool {\n\treturn def.FixStr <= v && v <= def.FixStr+0x1f\n}\n\nfunc (d *decoder) stringByteLength(offset int, k reflect.Kind) (int, int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tif def.FixStr <= code && code <= def.FixStr+0x1f {\n\t\tl := int(code - def.FixStr)\n\t\treturn l, offset, nil\n\t} else if code == def.Str8 {\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(b), offset, nil\n\t} else if code == def.Str16 {\n\t\tb, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(b)), offset, nil\n\t} else if code == def.Str32 {\n\t\tb, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(b)), offset, nil\n\t} else if code == def.Nil {\n\t\treturn 0, offset, nil\n\t}\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asString(offset int, k reflect.Kind) (string, int, error) {\n\tbs, offset, err := d.asStringByte(offset, k)\n\tif err != nil {\n\t\treturn emptyString, 0, err\n\t}\n\treturn string(bs), offset, nil\n}\n\nfunc (d *decoder) asStringByte(offset int, k reflect.Kind) ([]byte, int, error) {\n\tl, offset, err := d.stringByteLength(offset, k)\n\tif err != nil {\n\t\treturn emptyBytes, 0, err\n\t}\n\n\treturn d.asStringByteByLength(offset, l, k)\n}\n\nfunc (d *decoder) asStringByteByLength(offset int, l int, k reflect.Kind) ([]byte, int, error) {\n\tif l < 1 {\n\t\treturn emptyBytes, offset, nil\n\t}\n\n\treturn d.readSizeN(offset, l)\n}\n"
  },
  {
    "path": "internal/decoding/string_test.go",
    "content": "package decoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_stringByteLength(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (int, int, error) {\n\t\treturn d.stringByteLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixStr.ok\",\n\t\t\tData:     []byte{def.FixStr + 1},\n\t\t\tExpected: 1,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str8.error\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str8.ok\",\n\t\t\tData:     []byte{def.Str8, 0xff},\n\t\t\tExpected: math.MaxUint8,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str16.error\",\n\t\t\tData:     []byte{def.Str16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str16.ok\",\n\t\t\tData:     []byte{def.Str16, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint16,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str32.error\",\n\t\t\tData:     []byte{def.Str32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str32.ok\",\n\t\t\tData:     []byte{def.Str32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: math.MaxUint32,\n\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Nil\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tExpected: 0,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Array16},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asString(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (string, int, error) {\n\t\treturn d.asString\n\t}\n\ttestcases := AsXXXTestCases[string]{\n\t\t{\n\t\t\tName:     \"error.string\",\n\t\t\tData:     []byte{def.FixStr + 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"ok\",\n\t\t\tData:     []byte{def.FixStr + 1, 'a'},\n\t\t\tExpected: \"a\",\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_asStringByte(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) ([]byte, int, error) {\n\t\treturn d.asStringByte\n\t}\n\ttestcases := AsXXXTestCases[[]byte]{\n\t\t{\n\t\t\tName:     \"error\",\n\t\t\tData:     []byte{def.FixStr + 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"ok\",\n\t\t\tData:     []byte{def.FixStr + 1, 'a'},\n\t\t\tExpected: []byte{'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/struct.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\ntype structCacheTypeMap struct {\n\tkeys [][]byte\n\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes [][]int // field path (support for embedded structs)\n}\n\ntype structCacheTypeArray struct {\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes [][]int // field path (support for embedded structs)\n}\n\n// struct cache map\nvar (\n\tmapSCTM = sync.Map{}\n\tmapSCTA = sync.Map{}\n)\n\n// getFieldByPath returns the field value by following the path of indices.\n// The bool indicates whether the path was reachable (no nil pointer in the path).\nfunc getFieldByPath(rv reflect.Value, path []int, allowAlloc bool) (reflect.Value, bool) {\n\tfor _, idx := range path {\n\t\t// Handle pointer indirection if needed\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\tif rv.IsNil() {\n\t\t\t\tif !allowAlloc {\n\t\t\t\t\treturn reflect.Value{}, false\n\t\t\t\t}\n\t\t\t\t// Allocate new value if pointer is nil\n\t\t\t\trv.Set(reflect.New(rv.Type().Elem()))\n\t\t\t}\n\t\t\trv = rv.Elem()\n\t\t}\n\t\trv = rv.Field(idx)\n\t}\n\treturn rv, true\n}\n\nfunc (d *decoder) setStruct(rv reflect.Value, offset int, k reflect.Kind) (int, error) {\n\t/*\n\t\tif d.isDateTime(offset) {\n\t\t\tdt, offset, err := d.asDateTime(offset, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\trv.Set(reflect.ValueOf(dt))\n\t\t\treturn offset, nil\n\t\t}\n\t*/\n\n\tisExt, _, err := d.extEndOffset(offset)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tif isExt {\n\t\tfor i := range extCoders {\n\t\t\tif extCoders[i].IsType(offset, &d.data) {\n\t\t\t\tv, offset, err := extCoders[i].AsValue(offset, k, &d.data)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\n\t\t\t\t// Validate that the receptacle is of the right value type.\n\t\t\t\tif rv.Type() == reflect.TypeOf(v) {\n\t\t\t\t\trv.Set(reflect.ValueOf(v))\n\t\t\t\t\treturn offset, nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif d.asArray {\n\t\treturn d.setStructFromArray(rv, offset, k)\n\t}\n\treturn d.setStructFromMap(rv, offset, k)\n}\n\nfunc (d *decoder) setStructFromArray(rv reflect.Value, offset int, k reflect.Kind) (int, error) {\n\t// get length\n\tl, o, err := d.sliceLength(offset, k)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tif err = d.hasRequiredLeastSliceSize(o, l); err != nil {\n\t\treturn 0, err\n\t}\n\n\t// find or create reference\n\tvar scta *structCacheTypeArray\n\tcache, findCache := mapSCTA.Load(rv.Type())\n\tif !findCache {\n\t\tscta = &structCacheTypeArray{}\n\t\tfields := d.CollectFields(rv.Type(), nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tscta.hasEmbedded = hasEmbedded\n\n\t\tfor _, field := range fields {\n\t\t\tif hasEmbedded {\n\t\t\t\tscta.indexes = append(scta.indexes, field.Path)\n\t\t\t} else {\n\t\t\t\tscta.simpleIndexes = append(scta.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t}\n\t\tmapSCTA.Store(rv.Type(), scta)\n\t} else {\n\t\tscta = cache.(*structCacheTypeArray)\n\t}\n\n\t// set value\n\tif scta.hasEmbedded {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif i < len(scta.indexes) {\n\t\t\t\tallowAlloc := !d.isCodeNil(d.data[o])\n\t\t\t\tfieldValue, ok := getFieldByPath(rv, scta.indexes[i], allowAlloc)\n\t\t\t\tif ok {\n\t\t\t\t\to, err = d.decode(fieldValue, o)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\to, err = d.jumpOffset(o)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\to, err = d.jumpOffset(o)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif i < len(scta.simpleIndexes) {\n\t\t\t\to, err = d.decode(rv.Field(scta.simpleIndexes[i]), o)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\to, err = d.jumpOffset(o)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn o, nil\n}\n\nfunc (d *decoder) setStructFromMap(rv reflect.Value, offset int, k reflect.Kind) (int, error) {\n\t// get length\n\tl, o, err := d.mapLength(offset, k)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tif err = d.hasRequiredLeastMapSize(o, l); err != nil {\n\t\treturn 0, err\n\t}\n\n\tvar sctm *structCacheTypeMap\n\tcache, cacheFind := mapSCTM.Load(rv.Type())\n\tif !cacheFind {\n\t\tsctm = &structCacheTypeMap{}\n\t\tfields := d.CollectFields(rv.Type(), nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tsctm.hasEmbedded = hasEmbedded\n\n\t\tfor _, field := range fields {\n\t\t\tsctm.keys = append(sctm.keys, []byte(field.Name))\n\t\t\tif hasEmbedded {\n\t\t\t\tsctm.indexes = append(sctm.indexes, field.Path)\n\t\t\t} else {\n\t\t\t\tsctm.simpleIndexes = append(sctm.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t}\n\t\tmapSCTM.Store(rv.Type(), sctm)\n\t} else {\n\t\tsctm = cache.(*structCacheTypeMap)\n\t}\n\n\tif sctm.hasEmbedded {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tdataKey, o2, err := d.asStringByte(o, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\tfieldPath := []int(nil)\n\t\t\tfor keyIndex, keyBytes := range sctm.keys {\n\t\t\t\tif len(keyBytes) != len(dataKey) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfound := true\n\t\t\t\tfor dataIndex := range dataKey {\n\t\t\t\t\tif dataKey[dataIndex] != keyBytes[dataIndex] {\n\t\t\t\t\t\tfound = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif found {\n\t\t\t\t\tfieldPath = sctm.indexes[keyIndex]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif fieldPath != nil {\n\t\t\t\tallowAlloc := !d.isCodeNil(d.data[o2])\n\t\t\t\tfieldValue, ok := getFieldByPath(rv, fieldPath, allowAlloc)\n\t\t\t\tif ok {\n\t\t\t\t\to2, err = d.decode(fieldValue, o2)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\to2, err = d.jumpOffset(o2)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn 0, err\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\to2, err = d.jumpOffset(o2)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t\to = o2\n\t\t}\n\t} else {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tdataKey, o2, err := d.asStringByte(o, k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\tfieldIndex := -1\n\t\t\tfor keyIndex, keyBytes := range sctm.keys {\n\t\t\t\tif len(keyBytes) != len(dataKey) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfound := true\n\t\t\t\tfor dataIndex := range dataKey {\n\t\t\t\t\tif dataKey[dataIndex] != keyBytes[dataIndex] {\n\t\t\t\t\t\tfound = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif found {\n\t\t\t\t\tfieldIndex = sctm.simpleIndexes[keyIndex]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif fieldIndex >= 0 {\n\t\t\t\to2, err = d.decode(rv.Field(fieldIndex), o2)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\to2, err = d.jumpOffset(o2)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn 0, err\n\t\t\t\t}\n\t\t\t}\n\t\t\to = o2\n\t\t}\n\t}\n\treturn o, nil\n}\n\nfunc (d *decoder) jumpOffset(offset int) (int, error) {\n\tcode, offset, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\tswitch {\n\tcase code == def.True, code == def.False, code == def.Nil:\n\t\t// do nothing\n\n\tcase d.isPositiveFixNum(code) || d.isNegativeFixNum(code):\n\t\t// do nothing\n\tcase code == def.Uint8, code == def.Int8:\n\t\toffset += def.Byte1\n\tcase code == def.Uint16, code == def.Int16:\n\t\toffset += def.Byte2\n\tcase code == def.Uint32, code == def.Int32, code == def.Float32:\n\t\toffset += def.Byte4\n\tcase code == def.Uint64, code == def.Int64, code == def.Float64:\n\t\toffset += def.Byte8\n\n\tcase d.isFixString(code):\n\t\toffset += int(code - def.FixStr)\n\tcase code == def.Str8, code == def.Bin8:\n\t\tb, o, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\to += int(b)\n\t\toffset = o\n\tcase code == def.Str16, code == def.Bin16:\n\t\tbs, o, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\to += int(binary.BigEndian.Uint16(bs))\n\t\toffset = o\n\tcase code == def.Str32, code == def.Bin32:\n\t\tbs, o, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\to += int(binary.BigEndian.Uint32(bs))\n\t\toffset = o\n\n\tcase d.isFixSlice(code):\n\t\tl := int(code - def.FixArray)\n\t\tfor i := 0; i < l; i++ {\n\t\t\toffset, err = d.jumpOffset(offset)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\tcase code == def.Array16:\n\t\tbs, o, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint16(bs))\n\t\tfor i := 0; i < l; i++ {\n\t\t\to, err = d.jumpOffset(o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\toffset = o\n\tcase code == def.Array32:\n\t\tbs, o, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint32(bs))\n\t\tfor i := 0; i < l; i++ {\n\t\t\to, err = d.jumpOffset(o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\toffset = o\n\n\tcase d.isFixMap(code):\n\t\tl := int(code - def.FixMap)\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\toffset, err = d.jumpOffset(offset)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\tcase code == def.Map16:\n\t\tbs, o, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint16(bs))\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\to, err = d.jumpOffset(o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\toffset = o\n\tcase code == def.Map32:\n\t\tbs, o, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint32(bs))\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\to, err = d.jumpOffset(o)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t}\n\t\toffset = o\n\n\tdefault:\n\t\tisExt, o, err := d.extEndOffsetWithCode(code, offset)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tif isExt {\n\t\t\toffset = o\n\t\t}\n\n\t}\n\treturn offset, nil\n}\n"
  },
  {
    "path": "internal/decoding/struct_test.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_setStruct_ext(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(int, reflect.Kind) (any, int, error) {\n\t\t\treturn func(offset int, k reflect.Kind) (any, int, error) {\n\t\t\t\to, err := d.setStruct(rv, offset, k)\n\t\t\t\treturn nil, o, err\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:     \"ExtCoder.error\",\n\t\t\t\tData:     []byte{def.Fixext1, 3, 0},\n\t\t\t\tError:    ErrTestExtDecoder,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ExtCoder.ok\",\n\t\t\t\tData:     []byte{def.Fixext4, 255, 0, 0, 0, 0},\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\tngDec := testExt2Decoder{}\n\tAddExtDecoder(&ngDec)\n\tdefer RemoveExtDecoder(&ngDec)\n\n\tv1 := new(time.Time)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.EqualEqualer(t, *v1, time.Unix(0, 0))\n}\n\nfunc Test_setStructFromMap(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(int, reflect.Kind) (any, int, error) {\n\t\t\treturn func(offset int, k reflect.Kind) (any, int, error) {\n\t\t\t\to, err := d.setStructFromMap(rv, offset, k)\n\t\t\t\treturn nil, o, err\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:     \"error.length\",\n\t\t\t\tData:     []byte{},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.required\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToMap,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.key\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.Str16, 0},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.decode\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'v', def.Array16},\n\t\t\t\tError:    def.ErrCanNotDecode,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.jump\",\n\t\t\t\tData:     []byte{def.Map16, 0, 2, def.FixStr + 1, 'v', 0, def.FixStr + 1, 'b'},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Map16, 0, 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 7},\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\ttype st struct {\n\t\tV int `msgpack:\"v\"`\n\t}\n\n\tv1 := new(st)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.Equal(t, v1.V, 7)\n}\n\nfunc Test_setStructFromArray(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(int, reflect.Kind) (any, int, error) {\n\t\t\treturn func(offset int, k reflect.Kind) (any, int, error) {\n\t\t\t\to, err := d.setStructFromArray(rv, offset, k)\n\t\t\t\treturn nil, o, err\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:     \"error.length\",\n\t\t\t\tData:     []byte{},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.required\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\t\tError:    def.ErrLackDataLengthToSlice,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.decode\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.Array16},\n\t\t\t\tError:    def.ErrCanNotDecode,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"error.jump\",\n\t\t\t\tData:     []byte{def.Array16, 0, 2, 0, def.Array16},\n\t\t\t\tError:    def.ErrTooShortBytes,\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:     \"ok\",\n\t\t\t\tData:     []byte{def.Array16, 0, 1, def.PositiveFixIntMin + 8},\n\t\t\t\tMethodAs: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t}\n\n\ttype st struct {\n\t\tV int `msgpack:\"v\"`\n\t}\n\n\tv1 := new(st)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.Equal(t, v1.V, 8)\n}\n\nfunc Test_jumpOffset(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (any, int, error) {\n\t\treturn func(offset int, _ reflect.Kind) (any, int, error) {\n\t\t\to, err := d.jumpOffset(offset)\n\t\t\treturn nil, o, err\n\t\t}\n\t}\n\n\ttestcases := AsXXXTestCases[any]{\n\t\t{\n\t\t\tName:     \"error.read.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"True.ok\",\n\t\t\tData:     []byte{def.True},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"False.ok\",\n\t\t\tData:     []byte{def.False},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"PositiveFixNum.ok\",\n\t\t\tData:     []byte{def.PositiveFixIntMin + 1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"NegativeFixNum.ok\",\n\t\t\tData:     []byte{0xf0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.ok\",\n\t\t\tData:     []byte{def.Uint8, 1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.ok\",\n\t\t\tData:     []byte{def.Int8, 1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.ok\",\n\t\t\tData:     []byte{def.Uint16, 0, 1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.ok\",\n\t\t\tData:     []byte{def.Int16, 0, 1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.ok\",\n\t\t\tData:     []byte{def.Uint32, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.ok\",\n\t\t\tData:     []byte{def.Int32, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float32.ok\",\n\t\t\tData:     []byte{def.Float32, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.ok\",\n\t\t\tData:     []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.ok\",\n\t\t\tData:     []byte{def.Int64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Float64.ok\",\n\t\t\tData:     []byte{def.Float64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixStr.ok\",\n\t\t\tData:     []byte{def.FixStr + 1, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str8.ng.length\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str8.ok\",\n\t\t\tData:     []byte{def.Str8, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin8.ng.length\",\n\t\t\tData:     []byte{def.Bin8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin8.ok\",\n\t\t\tData:     []byte{def.Bin8, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str16.ng.length\",\n\t\t\tData:     []byte{def.Str16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str16.ok\",\n\t\t\tData:     []byte{def.Str16, 0, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin16.ng.length\",\n\t\t\tData:     []byte{def.Bin16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin16.ok\",\n\t\t\tData:     []byte{def.Bin16, 0, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str32.ng.length\",\n\t\t\tData:     []byte{def.Str32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Str32.ok\",\n\t\t\tData:     []byte{def.Str32, 0, 0, 0, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin32.ng.length\",\n\t\t\tData:     []byte{def.Bin32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Bin32.ok\",\n\t\t\tData:     []byte{def.Bin32, 0, 0, 0, 1, 'a'},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixSlice.ng\",\n\t\t\tData:     []byte{def.FixArray + 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixSlice.ok\",\n\t\t\tData:     []byte{def.FixArray + 1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array16.ng.len\",\n\t\t\tData:     []byte{def.Array16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array16.ng.jump\",\n\t\t\tData:     []byte{def.Array16, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array16.ok\",\n\t\t\tData:     []byte{def.Array16, 0, 1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array32.ng.len\",\n\t\t\tData:     []byte{def.Array32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array32.ng.jump\",\n\t\t\tData:     []byte{def.Array32, 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Array32.ok\",\n\t\t\tData:     []byte{def.Array32, 0, 0, 0, 1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixMap.ng\",\n\t\t\tData:     []byte{def.FixMap + 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"FixMap.ok\",\n\t\t\tData:     []byte{def.FixMap + 1, 0xc1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map16.ng.len\",\n\t\t\tData:     []byte{def.Map16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map16.ng.jump\",\n\t\t\tData:     []byte{def.Map16, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map16.ok\",\n\t\t\tData:     []byte{def.Map16, 0, 1, 0xc1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map32.ng.len\",\n\t\t\tData:     []byte{def.Map32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map32.ng.jump\",\n\t\t\tData:     []byte{def.Map32, 0, 0, 0, 1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Map32.ok\",\n\t\t\tData:     []byte{def.Map32, 0, 0, 0, 1, 0xc1, 0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext1.ng\",\n\t\t\tData:     []byte{def.Fixext1},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext1.ok\",\n\t\t\tData:     []byte{def.Fixext1, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext2.ng\",\n\t\t\tData:     []byte{def.Fixext2},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext2.ok\",\n\t\t\tData:     []byte{def.Fixext2, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext4.ng\",\n\t\t\tData:     []byte{def.Fixext4},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext4.ok\",\n\t\t\tData:     []byte{def.Fixext4, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.ng\",\n\t\t\tData:     []byte{def.Fixext8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext8.ok\",\n\t\t\tData:     []byte{def.Fixext8, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.ng\",\n\t\t\tData:     []byte{def.Fixext16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Fixext16.ok\",\n\t\t\tData:     []byte{def.Fixext16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext8.ng.size\",\n\t\t\tData:     []byte{def.Ext8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext8.ok\",\n\t\t\tData:     []byte{def.Ext8, 1, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext16.ng.size\",\n\t\t\tData:     []byte{def.Ext16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext16.ok\",\n\t\t\tData:     []byte{def.Ext16, 0, 1, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext32.ng.size\",\n\t\t\tData:     []byte{def.Ext32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Ext32.ok\",\n\t\t\tData:     []byte{def.Ext32, 0, 0, 0, 1, 0, 0},\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{0xc1},\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/decoding/uint.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asUint(offset int, k reflect.Kind) (uint64, int, error) {\n\tcode, _, err := d.readSize1(offset)\n\tif err != nil {\n\t\treturn 0, 0, err\n\t}\n\n\tswitch {\n\tcase d.isPositiveFixNum(code):\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn uint64(b), offset, nil\n\n\tcase d.isNegativeFixNum(code):\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn uint64(int8(b)), offset, nil\n\n\tcase code == def.Uint8:\n\t\toffset++\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn uint64(uint8(b)), offset, nil\n\n\tcase code == def.Int8:\n\t\toffset++\n\t\tb, offset, err := d.readSize1(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn uint64(int8(b)), offset, nil\n\n\tcase code == def.Uint16:\n\t\toffset++\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint16(bs)\n\t\treturn uint64(v), offset, nil\n\n\tcase code == def.Int16:\n\t\toffset++\n\t\tbs, offset, err := d.readSize2(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := int16(binary.BigEndian.Uint16(bs))\n\t\treturn uint64(v), offset, nil\n\n\tcase code == def.Uint32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint32(bs)\n\t\treturn uint64(v), offset, nil\n\n\tcase code == def.Int32:\n\t\toffset++\n\t\tbs, offset, err := d.readSize4(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\tv := int32(binary.BigEndian.Uint32(bs))\n\t\treturn uint64(v), offset, nil\n\n\tcase code == def.Uint64:\n\t\toffset++\n\t\tbs, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn binary.BigEndian.Uint64(bs), offset, nil\n\n\tcase code == def.Int64:\n\t\toffset++\n\t\tbs, offset, err := d.readSize8(offset)\n\t\tif err != nil {\n\t\t\treturn 0, 0, err\n\t\t}\n\t\treturn binary.BigEndian.Uint64(bs), offset, nil\n\n\tcase code == def.Nil:\n\t\toffset++\n\t\treturn 0, offset, nil\n\t}\n\n\treturn 0, 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/decoding/uint_test.go",
    "content": "package decoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asUint(t *testing.T) {\n\tmethod := func(d *decoder) func(int, reflect.Kind) (uint64, int, error) {\n\t\treturn d.asUint\n\t}\n\ttestcases := AsXXXTestCases[uint64]{\n\t\t{\n\t\t\tName:     \"error.code\",\n\t\t\tData:     []byte{},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"PositiveFixNum.ok\",\n\t\t\tData:     []byte{def.PositiveFixIntMin + 1},\n\t\t\tExpected: uint64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.error\",\n\t\t\tData:     []byte{def.Uint8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint8.ok\",\n\t\t\tData:     []byte{def.Uint8, 1},\n\t\t\tExpected: uint64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.error\",\n\t\t\tData:     []byte{def.Uint16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint16.ok\",\n\t\t\tData:     []byte{def.Uint16, 0, 1},\n\t\t\tExpected: uint64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.error\",\n\t\t\tData:     []byte{def.Uint32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint32.ok\",\n\t\t\tData:     []byte{def.Uint32, 0, 0, 0, 1},\n\t\t\tExpected: uint64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.error\",\n\t\t\tData:     []byte{def.Uint64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Uint64.ok\",\n\t\t\tData:     []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected: uint64(1),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"NegativeFixNum.ok\",\n\t\t\tData:     []byte{0xff},\n\t\t\tExpected: uint64(math.MaxUint64),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.error\",\n\t\t\tData:     []byte{def.Int8},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int8.ok\",\n\t\t\tData:     []byte{def.Int8, 0xff},\n\t\t\tExpected: uint64(math.MaxUint64),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.error\",\n\t\t\tData:     []byte{def.Int16},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int16.ok\",\n\t\t\tData:     []byte{def.Int16, 0xff, 0xff},\n\t\t\tExpected: uint64(math.MaxUint64),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.error\",\n\t\t\tData:     []byte{def.Int32},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int32.ok\",\n\t\t\tData:     []byte{def.Int32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: uint64(math.MaxUint64),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.error\",\n\t\t\tData:     []byte{def.Int64},\n\t\t\tError:    def.ErrTooShortBytes,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Int64.ok\",\n\t\t\tData:     []byte{def.Int64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected: uint64(math.MaxUint64),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Nil.ok\",\n\t\t\tData:     []byte{def.Nil},\n\t\t\tExpected: uint64(0),\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:     \"Unexpected\",\n\t\t\tData:     []byte{def.Str8},\n\t\t\tError:    def.ErrCanNotDecode,\n\t\t\tMethodAs: method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/encoding/bool.go",
    "content": "package encoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\n//func (e *encoder) calcBool() int {\n//\treturn 0\n//}\n\nfunc (e *encoder) writeBool(v bool, offset int) int {\n\tif v {\n\t\toffset = e.setByte1Int(def.True, offset)\n\t} else {\n\t\toffset = e.setByte1Int(def.False, offset)\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/byte.go",
    "content": "package encoding\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar typeByte = reflect.TypeOf(byte(0))\n\nfunc (e *encoder) isByteSlice(rv reflect.Value) bool {\n\treturn rv.Type().Elem() == typeByte\n}\n\nfunc (e *encoder) calcByteSlice(l int) (int, error) {\n\tif l <= math.MaxUint8 {\n\t\treturn def.Byte1 + def.Byte1 + l, nil\n\t} else if l <= math.MaxUint16 {\n\t\treturn def.Byte1 + def.Byte2 + l, nil\n\t} else if uint(l) <= math.MaxUint32 {\n\t\treturn def.Byte1 + def.Byte4 + l, nil\n\t}\n\t// not supported error\n\treturn 0, fmt.Errorf(\"%w slice length : %d\", def.ErrUnsupportedType, l)\n}\n\nfunc (e *encoder) writeByteSliceLength(l int, offset int) int {\n\tif l <= math.MaxUint8 {\n\t\toffset = e.setByte1Int(def.Bin8, offset)\n\t\toffset = e.setByte1Int(l, offset)\n\t} else if l <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Bin16, offset)\n\t\toffset = e.setByte2Int(l, offset)\n\t} else if uint(l) <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Bin32, offset)\n\t\toffset = e.setByte4Int(l, offset)\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/byte_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_calcByteSlice(t *testing.T) {\n\ttestcases := []struct {\n\t\tname   string\n\t\tvalue  int\n\t\tresult int\n\t\terror  error\n\t}{\n\t\t{\n\t\t\tname:   \"u8\",\n\t\t\tvalue:  math.MaxUint8,\n\t\t\tresult: def.Byte1 + def.Byte1 + math.MaxUint8,\n\t\t},\n\t\t{\n\t\t\tname:   \"u16\",\n\t\t\tvalue:  math.MaxUint16,\n\t\t\tresult: def.Byte1 + def.Byte2 + math.MaxUint16,\n\t\t},\n\t\t{\n\t\t\tname:   \"u32\",\n\t\t\tvalue:  math.MaxUint32,\n\t\t\tresult: def.Byte1 + def.Byte4 + math.MaxUint32,\n\t\t},\n\t\t{\n\t\t\tname:  \"u32over\",\n\t\t\tvalue: math.MaxUint32 + 1,\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tresult, err := e.calcByteSlice(tc.value)\n\t\t\ttu.IsError(t, err, tc.error)\n\t\t\ttu.Equal(t, result, tc.result)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/encoding/complex.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcComplex64() int {\n\treturn def.Byte1 + def.Byte1 + def.Byte8\n}\n\nfunc (e *encoder) calcComplex128() int {\n\treturn def.Byte1 + def.Byte1 + def.Byte16\n}\n\nfunc (e *encoder) writeComplex64(v complex64, offset int) int {\n\toffset = e.setByte1Int(def.Fixext8, offset)\n\toffset = e.setByte1Int(int(def.ComplexTypeCode()), offset)\n\toffset = e.setByte4Uint64(uint64(math.Float32bits(real(v))), offset)\n\toffset = e.setByte4Uint64(uint64(math.Float32bits(imag(v))), offset)\n\treturn offset\n}\n\nfunc (e *encoder) writeComplex128(v complex128, offset int) int {\n\toffset = e.setByte1Int(def.Fixext16, offset)\n\toffset = e.setByte1Int(int(def.ComplexTypeCode()), offset)\n\toffset = e.setByte8Uint64(math.Float64bits(real(v)), offset)\n\toffset = e.setByte8Uint64(math.Float64bits(imag(v)), offset)\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/encoding.go",
    "content": "package encoding\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype encoder struct {\n\td       []byte\n\tasArray bool\n\tcommon.Common\n\tmk map[uintptr][]reflect.Value\n\tmv map[uintptr][]reflect.Value\n}\n\n// Encode returns the MessagePack-encoded byte array of v.\nfunc Encode(v interface{}, asArray bool) (b []byte, err error) {\n\te := encoder{asArray: asArray}\n\t/*\n\t\tdefer func() {\n\t\t\te := recover()\n\t\t\tif e != nil {\n\t\t\t\tb = nil\n\t\t\t\terr = fmt.Errorf(\"unexpected error!! \\n%s\", stackTrace())\n\t\t\t}\n\t\t}()\n\t*/\n\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() == reflect.Ptr {\n\t\trv = rv.Elem()\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\trv = rv.Elem()\n\t\t}\n\t}\n\tsize, err := e.calcSize(rv)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\te.d = make([]byte, size)\n\tlast := e.create(rv, 0)\n\tif size != last {\n\t\treturn nil, fmt.Errorf(\"%w size=%d, lastIdx=%d\", def.ErrNotMatchLastIndex, size, last)\n\t}\n\treturn e.d, err\n}\n\n//func stackTrace() string {\n//\tmsg := \"\"\n//\tfor depth := 0; ; depth++ {\n//\t\t_, file, line, ok := runtime.Caller(depth)\n//\t\tif !ok {\n//\t\t\tbreak\n//\t\t}\n//\t\tmsg += fmt.Sprintln(depth, \": \", file, \":\", line)\n//\t}\n//\treturn msg\n//}\n\nfunc (e *encoder) calcSize(rv reflect.Value) (int, error) {\n\tswitch rv.Kind() {\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tv := rv.Uint()\n\t\treturn e.calcUint(v), nil\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tv := rv.Int()\n\t\treturn e.calcInt(int64(v)), nil\n\n\tcase reflect.Float32:\n\t\treturn e.calcFloat32(0), nil\n\n\tcase reflect.Float64:\n\t\treturn e.calcFloat64(0), nil\n\n\tcase reflect.String:\n\t\treturn e.calcString(rv.String()), nil\n\n\tcase reflect.Bool:\n\t\treturn def.Byte1, nil\n\n\tcase reflect.Complex64:\n\t\treturn e.calcComplex64(), nil\n\n\tcase reflect.Complex128:\n\t\treturn e.calcComplex128(), nil\n\n\tcase reflect.Slice:\n\t\tif rv.IsNil() {\n\t\t\treturn def.Byte1, nil\n\t\t}\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\tsize, err := e.calcByteSlice(rv.Len())\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treturn size, nil\n\t\t}\n\n\t\tif size, find := e.calcFixedSlice(rv); find {\n\t\t\treturn size, nil\n\t\t}\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structCalcFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructCalc(elem)\n\t\t} else {\n\t\t\tf = e.calcSize\n\t\t}\n\n\t\tl := rv.Len()\n\t\tsize, err := e.calcLength(l)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// objects size\n\t\tfor i := 0; i < l; i++ {\n\t\t\ts, err := f(rv.Index(i))\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tsize += s\n\t\t}\n\t\treturn size, nil\n\n\tcase reflect.Array:\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\tsize, err := e.calcByteSlice(rv.Len())\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\treturn size, nil\n\t\t}\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structCalcFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructCalc(elem)\n\t\t} else {\n\t\t\tf = e.calcSize\n\t\t}\n\n\t\tl := rv.Len()\n\t\tsize, err := e.calcLength(l)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// objects size\n\t\tfor i := 0; i < l; i++ {\n\t\t\ts, err := f(rv.Index(i))\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tsize += s\n\t\t}\n\t\treturn size, nil\n\n\tcase reflect.Map:\n\t\tif rv.IsNil() {\n\t\t\treturn def.Byte1, nil\n\t\t}\n\n\t\tif size, find := e.calcFixedMap(rv); find {\n\t\t\treturn size, nil\n\t\t}\n\n\t\tif e.mk == nil {\n\t\t\te.mk = map[uintptr][]reflect.Value{}\n\t\t\te.mv = map[uintptr][]reflect.Value{}\n\t\t}\n\n\t\tkeys := rv.MapKeys()\n\t\tsize, err := e.calcLength(len(keys))\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\n\t\t// key-value\n\t\tmv := make([]reflect.Value, len(keys))\n\t\ti := 0\n\t\tfor _, k := range keys {\n\t\t\tkeySize, err := e.calcSize(k)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tvalue := rv.MapIndex(k)\n\t\t\tvalueSize, err := e.calcSize(value)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tsize += keySize + valueSize\n\t\t\tmv[i] = value\n\t\t\ti++\n\t\t}\n\t\te.mk[rv.Pointer()], e.mv[rv.Pointer()] = keys, mv\n\t\treturn size, nil\n\n\tcase reflect.Struct:\n\t\tsize, err := e.calcStruct(rv)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn size, nil\n\n\tcase reflect.Ptr:\n\t\tif rv.IsNil() {\n\t\t\treturn def.Byte1, nil\n\t\t}\n\t\tsize, err := e.calcSize(rv.Elem())\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn size, nil\n\n\tcase reflect.Interface:\n\t\tsize, err := e.calcSize(rv.Elem())\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn size, nil\n\n\tcase reflect.Invalid:\n\t\t// do nothing (return nil)\n\t\treturn def.Byte1, nil\n\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"%v is %w type\", rv.Kind(), def.ErrUnsupportedType)\n\t}\n}\n\nfunc (e *encoder) calcLength(l int) (int, error) {\n\tif l <= 0x0f {\n\t\treturn def.Byte1, nil\n\t} else if l <= math.MaxUint16 {\n\t\treturn def.Byte1 + def.Byte2, nil\n\t} else if uint(l) <= math.MaxUint32 {\n\t\treturn def.Byte1 + def.Byte4, nil\n\t}\n\t// not supported error\n\treturn 0, fmt.Errorf(\"array length %d is %w\", l, def.ErrUnsupportedLength)\n}\n\nfunc (e *encoder) create(rv reflect.Value, offset int) int {\n\tswitch rv.Kind() {\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tv := rv.Uint()\n\t\toffset = e.writeUint(v, offset)\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tv := rv.Int()\n\t\toffset = e.writeInt(v, offset)\n\n\tcase reflect.Float32:\n\t\toffset = e.writeFloat32(rv.Float(), offset)\n\n\tcase reflect.Float64:\n\t\toffset = e.writeFloat64(rv.Float(), offset)\n\n\tcase reflect.Bool:\n\t\toffset = e.writeBool(rv.Bool(), offset)\n\n\tcase reflect.String:\n\t\toffset = e.writeString(rv.String(), offset)\n\n\tcase reflect.Complex64:\n\t\toffset = e.writeComplex64(complex64(rv.Complex()), offset)\n\n\tcase reflect.Complex128:\n\t\toffset = e.writeComplex128(rv.Complex(), offset)\n\n\tcase reflect.Slice:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil(offset)\n\t\t}\n\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\toffset = e.writeByteSliceLength(rv.Len(), offset)\n\t\t\toffset = e.setBytes(rv.Bytes(), offset)\n\t\t\treturn offset\n\t\t}\n\n\t\tif offset, find := e.writeFixedSlice(rv, offset); find {\n\t\t\treturn offset\n\t\t}\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structWriteFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructWriter(elem)\n\t\t} else {\n\t\t\tf = e.create\n\t\t}\n\n\t\t// objects\n\t\tl := rv.Len()\n\t\toffset = e.writeSliceLength(l, offset)\n\t\tfor i := 0; i < l; i++ {\n\t\t\toffset = f(rv.Index(i), offset)\n\t\t}\n\n\tcase reflect.Array:\n\t\tl := rv.Len()\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\toffset = e.writeByteSliceLength(l, offset)\n\t\t\t// objects\n\t\t\tfor i := 0; i < l; i++ {\n\t\t\t\toffset = e.setByte1Uint64(rv.Index(i).Uint(), offset)\n\t\t\t}\n\t\t\treturn offset\n\t\t}\n\n\t\t// format\n\t\toffset = e.writeSliceLength(l, offset)\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structWriteFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructWriter(elem)\n\t\t} else {\n\t\t\tf = e.create\n\t\t}\n\n\t\t// objects\n\t\tfor i := 0; i < l; i++ {\n\t\t\toffset = f(rv.Index(i), offset)\n\t\t}\n\n\tcase reflect.Map:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil(offset)\n\t\t}\n\n\t\tl := rv.Len()\n\t\toffset = e.writeMapLength(l, offset)\n\n\t\tif offset, find := e.writeFixedMap(rv, offset); find {\n\t\t\treturn offset\n\t\t}\n\n\t\t// key-value\n\t\tp := rv.Pointer()\n\t\tfor i := range e.mk[p] {\n\t\t\toffset = e.create(e.mk[p][i], offset)\n\t\t\toffset = e.create(e.mv[p][i], offset)\n\t\t}\n\n\tcase reflect.Struct:\n\t\toffset = e.writeStruct(rv, offset)\n\n\tcase reflect.Ptr:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil(offset)\n\t\t}\n\n\t\toffset = e.create(rv.Elem(), offset)\n\n\tcase reflect.Interface:\n\t\toffset = e.create(rv.Elem(), offset)\n\n\tcase reflect.Invalid:\n\t\treturn e.writeNil(offset)\n\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/encoding_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestEncode(t *testing.T) {\n\tv := 1\n\tvv := &v\n\n\tb, err := Encode(&vv, false)\n\ttu.NoError(t, err)\n\n\ttu.EqualSlice(t, b, []byte{def.PositiveFixIntMin + 1})\n}\n\nfunc Test_encode(t *testing.T) {\n\ttype st struct {\n\t\tV int\n\t}\n\n\ttype testcase struct {\n\t\tvalue any\n\t\tcode  byte\n\t\terror error\n\t}\n\n\tf := func(tcs []testcase, t *testing.T) {\n\t\tfor _, tc := range tcs {\n\t\t\trv := reflect.ValueOf(tc.value)\n\t\t\tt.Run(rv.Type().String(), func(t *testing.T) {\n\t\t\t\te := encoder{}\n\t\t\t\tsize, err := e.calcSize(rv)\n\t\t\t\ttu.IsError(t, err, tc.error)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\te.d = make([]byte, size)\n\t\t\t\tresult := e.create(rv, 0)\n\t\t\t\ttu.Equal(t, result, size)\n\t\t\t\ttu.Equal(t, e.d[0], tc.code)\n\t\t\t})\n\t\t}\n\t}\n\n\tvar testcases []testcase\n\n\t// slice tests\n\ttestcases = []testcase{\n\t\t{\n\t\t\tvalue: ([]byte)(nil),\n\t\t\tcode:  def.Nil,\n\t\t},\n\t\t{\n\t\t\tvalue: make([]byte, math.MaxUint32+1),\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t\t{\n\t\t\tvalue: make([]int, 1),\n\t\t\tcode:  def.FixArray + 1,\n\t\t},\n\t\t{\n\t\t\tvalue: make([]int, math.MaxUint16),\n\t\t\tcode:  def.Array16,\n\t\t},\n\t\t// too heavy\n\t\t//{\n\t\t//\tvalue: make([]int, math.MaxUint32),\n\t\t//\tcode:  def.Array32,\n\t\t//},\n\t\t//{\n\t\t//\tvalue: make([]int, math.MaxUint32+1),\n\t\t//\terror: def.ErrUnsupportedType,\n\t\t//},\n\t\t{\n\t\t\tvalue: []st{{1}},\n\t\t\tcode:  def.FixArray + 1,\n\t\t},\n\t\t{\n\t\t\tvalue: []chan int{make(chan int)},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t}\n\tt.Run(\"slice\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n\n\t// array tests\n\ttestcases = []testcase{\n\t\t// stack frame too large (compile error)\n\t\t//{\n\t\t//\tvalue: [math.MaxUint32 + 1]byte{},\n\t\t//\terror: def.ErrUnsupportedType,\n\t\t//},\n\t\t{\n\t\t\tvalue: [1]int{},\n\t\t\tcode:  def.FixArray + 1,\n\t\t},\n\t\t{\n\t\t\tvalue: [math.MaxUint16]int{},\n\t\t\tcode:  def.Array16,\n\t\t},\n\t\t// stack frame too large (compile error)\n\t\t//{\n\t\t//\tvalue: [math.MaxUint32]int{},\n\t\t//\tcode:  def.Array32,\n\t\t//},\n\t\t//{\n\t\t//\tvalue: [math.MaxUint32 + 1]int{},\n\t\t//\terror: def.ErrUnsupportedType,\n\t\t//},\n\t\t{\n\t\t\tvalue: [1]st{{1}},\n\t\t\tcode:  def.FixArray + 1,\n\t\t},\n\t\t{\n\t\t\tvalue: [1]chan int{make(chan int)},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t}\n\tt.Run(\"array\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n\n\t// map tests\n\tcreateMap := func(l int) map[string]int {\n\t\tm := map[string]int{}\n\t\tfor i := 0; i < l; i++ {\n\t\t\tm[strconv.Itoa(i)] = i\n\t\t}\n\t\treturn m\n\t}\n\ttestcases = []testcase{\n\t\t{\n\t\t\tvalue: (map[string]int)(nil),\n\t\t\tcode:  def.Nil,\n\t\t},\n\t\t{\n\t\t\tvalue: createMap(1),\n\t\t\tcode:  def.FixMap + 1,\n\t\t},\n\t\t{\n\t\t\tvalue: createMap(math.MaxUint16),\n\t\t\tcode:  def.Map16,\n\t\t},\n\t\t// too heavy\n\t\t//{\n\t\t//\tvalue: createMap(math.MaxUint32),\n\t\t//\tcode:  def.Map32,\n\t\t//},\n\t\t//{\n\t\t//\tvalue: createMap(math.MaxUint32 + 1),\n\t\t//\terror: def.ErrUnsupportedType,\n\t\t//},\n\t\t{\n\t\t\tvalue: map[chan int]int{make(chan int): 1},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t\t{\n\t\t\tvalue: map[string]chan int{\"a\": make(chan int)},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t}\n\tt.Run(\"map\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n\n\ttype unsupport struct {\n\t\tChan chan int\n\t}\n\n\ttestcases = []testcase{\n\t\t{\n\t\t\tvalue: unsupport{make(chan int)},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t}\n\tt.Run(\"struct\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n\n\tch := make(chan int)\n\ttestcases = []testcase{\n\t\t{\n\t\t\tvalue: (*int)(nil),\n\t\t\tcode:  def.Nil,\n\t\t},\n\t\t{\n\t\t\tvalue: &ch,\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t\t{\n\t\t\tvalue: new(int),\n\t\t\tcode:  0,\n\t\t},\n\t}\n\tt.Run(\"ptr\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n\n\ttype inter struct {\n\t\tV any\n\t}\n\ttestcases = []testcase{\n\t\t{\n\t\t\tvalue: inter{V: make(chan int)},\n\t\t\terror: def.ErrUnsupportedType,\n\t\t},\n\t\t{\n\t\t\tvalue: inter{V: 1},\n\t\t\tcode:  def.FixMap + 1,\n\t\t},\n\t}\n\tt.Run(\"interface\", func(t *testing.T) {\n\t\tf(testcases, t)\n\t})\n}\n\nfunc Test_calcLength(t *testing.T) {\n\te := encoder{}\n\n\ttestcases := []struct {\n\t\tname   string\n\t\tlength int\n\t\tsize   int\n\t\terr    error\n\t}{\n\t\t{\n\t\t\tname:   \"0x0f\",\n\t\t\tlength: 0x0f,\n\t\t\tsize:   def.Byte1,\n\t\t\terr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:   \"MaxUint16\",\n\t\t\tlength: math.MaxUint16,\n\t\t\tsize:   def.Byte1 + def.Byte2,\n\t\t\terr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:   \"MaxUint32\",\n\t\t\tlength: math.MaxUint32,\n\t\t\tsize:   def.Byte1 + def.Byte4,\n\t\t\terr:    nil,\n\t\t},\n\t\t{\n\t\t\tname:   \"error\",\n\t\t\tlength: math.MaxUint32 + 1,\n\t\t\tsize:   0,\n\t\t\terr:    def.ErrUnsupportedLength,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tsize, err := e.calcLength(tc.length)\n\t\t\ttu.IsError(t, err, tc.err)\n\t\t\ttu.Equal(t, size, tc.size)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/encoding/ext.go",
    "content": "package encoding\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nvar (\n\textCoderMap = map[reflect.Type]ext.Encoder{time.Encoder.Type(): time.Encoder}\n\textCoders   = []ext.Encoder{time.Encoder}\n)\n\n// AddExtEncoder adds encoders for extension types.\nfunc AddExtEncoder(f ext.Encoder) {\n\t// ignore time\n\tif f.Type() == time.Encoder.Type() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Type()]\n\tif !ok {\n\t\textCoderMap[f.Type()] = f\n\t\tupdateExtCoders()\n\t}\n}\n\n// RemoveExtEncoder removes encoders for extension types.\nfunc RemoveExtEncoder(f ext.Encoder) {\n\t// ignore time\n\tif f.Type() == time.Encoder.Type() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Type()]\n\tif ok {\n\t\tdelete(extCoderMap, f.Type())\n\t\tupdateExtCoders()\n\t}\n}\n\nfunc updateExtCoders() {\n\textCoders = make([]ext.Encoder, len(extCoderMap))\n\ti := 0\n\tfor k := range extCoderMap {\n\t\textCoders[i] = extCoderMap[k]\n\t\ti++\n\t}\n}\n\n/*\nfunc (e *encoder) isDateTime(value reflect.Value) (bool, time.Time) {\n\ti := value.Interface()\n\tswitch t := i.(type) {\n\tcase time.Time:\n\t\treturn true, t\n\t}\n\treturn false, now\n}\n\nfunc (e *encoder) calcTime(t time.Time) int {\n\tsecs := uint64(t.Unix())\n\tif secs>>34 == 0 {\n\t\tdata := uint64(t.Nanosecond())<<34 | secs\n\t\tif data&0xffffffff00000000 == 0 {\n\t\t\treturn def.Byte1 + def.Byte4\n\t\t}\n\t\treturn def.Byte1 + def.Byte8\n\t}\n\n\treturn def.Byte1 + def.Byte1 + def.Byte4 + def.Byte8\n}\n\nfunc (e *encoder) writeTime(t time.Time, offset int) int {\n\tsecs := uint64(t.Unix())\n\tif secs>>34 == 0 {\n\t\tdata := uint64(t.Nanosecond())<<34 | secs\n\t\tif data&0xffffffff00000000 == 0 {\n\t\t\toffset = e.setByte1Int(def.Fixext4, offset)\n\t\t\toffset = e.setByte1Int(def.TimeStamp, offset)\n\t\t\toffset = e.setByte4Uint64(data, offset)\n\t\t\treturn offset\n\t\t}\n\n\t\toffset = e.setByte1Int(def.Fixext8, offset)\n\t\toffset = e.setByte1Int(def.TimeStamp, offset)\n\t\toffset = e.setByte8Uint64(data, offset)\n\t\treturn offset\n\t}\n\n\toffset = e.setByte1Int(def.Ext8, offset)\n\toffset = e.setByte1Int(12, offset)\n\toffset = e.setByte1Int(def.TimeStamp, offset)\n\toffset = e.setByte4Int(t.Nanosecond(), offset)\n\toffset = e.setByte8Uint64(secs, offset)\n\treturn offset\n}\n*/\n"
  },
  {
    "path": "internal/encoding/ext_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nfunc Test_AddExtEncoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tAddExtEncoder(time.Encoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\nfunc Test_RemoveExtEncoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tRemoveExtEncoder(time.Encoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n"
  },
  {
    "path": "internal/encoding/float.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcFloat32(_ float64) int {\n\treturn def.Byte1 + def.Byte4\n}\n\nfunc (e *encoder) calcFloat64(_ float64) int {\n\treturn def.Byte1 + def.Byte8\n}\n\nfunc (e *encoder) writeFloat32(v float64, offset int) int {\n\toffset = e.setByte1Int(def.Float32, offset)\n\toffset = e.setByte4Uint64(uint64(math.Float32bits(float32(v))), offset)\n\treturn offset\n}\n\nfunc (e *encoder) writeFloat64(v float64, offset int) int {\n\toffset = e.setByte1Int(def.Float64, offset)\n\toffset = e.setByte8Uint64(math.Float64bits(v), offset)\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/int.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) isNegativeFixInt64(v int64) bool {\n\treturn def.NegativeFixintMin <= v && v <= def.NegativeFixintMax\n}\n\nfunc (e *encoder) calcInt(v int64) int {\n\tif v >= 0 {\n\t\treturn e.calcUint(uint64(v))\n\t} else if e.isNegativeFixInt64(v) {\n\t\t// format code only\n\t\treturn def.Byte1\n\t} else if v >= math.MinInt8 {\n\t\treturn def.Byte1 + def.Byte1\n\t} else if v >= math.MinInt16 {\n\t\treturn def.Byte1 + def.Byte2\n\t} else if v >= math.MinInt32 {\n\t\treturn def.Byte1 + def.Byte4\n\t}\n\treturn def.Byte1 + def.Byte8\n}\n\nfunc (e *encoder) writeInt(v int64, offset int) int {\n\tif v >= 0 {\n\t\toffset = e.writeUint(uint64(v), offset)\n\t} else if e.isNegativeFixInt64(v) {\n\t\toffset = e.setByte1Int64(v, offset)\n\t} else if v >= math.MinInt8 {\n\t\toffset = e.setByte1Int(def.Int8, offset)\n\t\toffset = e.setByte1Int64(v, offset)\n\t} else if v >= math.MinInt16 {\n\t\toffset = e.setByte1Int(def.Int16, offset)\n\t\toffset = e.setByte2Int64(v, offset)\n\t} else if v >= math.MinInt32 {\n\t\toffset = e.setByte1Int(def.Int32, offset)\n\t\toffset = e.setByte4Int64(v, offset)\n\t} else {\n\t\toffset = e.setByte1Int(def.Int64, offset)\n\t\toffset = e.setByte8Int64(v, offset)\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/map.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcFixedMap(rv reflect.Value) (int, bool) {\n\t// calcLength formally returns (int, error), but for map lengths in Go\n\t// the error case is unreachable. The error value is always nil and is\n\t// intentionally ignored with `_`.\n\tswitch m := rv.Interface().(type) {\n\tcase map[string]int:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]uint:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]float32:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcFloat32(0)\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]float64:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcFloat64(0)\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += def.Byte1 /*+ e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[string]int8:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]int16:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]int32:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]int64:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcInt(v)\n\t\t}\n\t\treturn size, true\n\tcase map[string]uint8:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]uint16:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]uint32:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\tcase map[string]uint64:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcString(k)\n\t\t\tsize += e.calcUint(v)\n\t\t}\n\t\treturn size, true\n\n\tcase map[int]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[int]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[uint]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[uint]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[float32]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcFloat32(float64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[float32]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcFloat32(float64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[float64]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcFloat64(k)\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[float64]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcFloat64(k)\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[int8]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[int8]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[int16]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[int16]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[int32]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[int32]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcInt(int64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[int64]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcInt(k)\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[int64]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcInt(k)\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\tcase map[uint8]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[uint8]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[uint16]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[uint16]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[uint32]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[uint32]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcUint(uint64(k))\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\tcase map[uint64]string:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k, v := range m {\n\t\t\tsize += e.calcUint(k)\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\tcase map[uint64]bool:\n\t\tsize, _ := e.calcLength(len(m))\n\t\tfor k := range m {\n\t\t\tsize += e.calcUint(k)\n\t\t\tsize += def.Byte1 /* + e.calcBool()*/\n\t\t}\n\t\treturn size, true\n\n\t}\n\treturn 0, false\n}\n\nfunc (e *encoder) writeMapLength(l int, offset int) int {\n\t// format\n\tif l <= 0x0f {\n\t\toffset = e.setByte1Int(def.FixMap+l, offset)\n\t} else if l <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Map16, offset)\n\t\toffset = e.setByte2Int(l, offset)\n\t} else if uint(l) <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Map32, offset)\n\t\toffset = e.setByte4Int(l, offset)\n\t}\n\treturn offset\n}\n\nfunc (e *encoder) writeFixedMap(rv reflect.Value, offset int) (int, bool) {\n\tswitch m := rv.Interface().(type) {\n\tcase map[string]int:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]uint:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]float32:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeFloat32(float64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]float64:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeFloat64(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]int8:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]int16:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]int32:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]int64:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[string]uint8:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]uint16:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]uint32:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[string]uint64:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeString(k, offset)\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[int]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[uint]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[float32]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeFloat32(float64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[float32]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeFloat32(float64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[float64]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeFloat64(k, offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[float64]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeFloat64(k, offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[int8]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int8]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int16]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int16]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int32]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int32]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(int64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int64]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(k, offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[int64]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeInt(k, offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase map[uint8]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint8]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint16]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint16]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint32]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint32]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(uint64(k), offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint64]string:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(k, offset)\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\tcase map[uint64]bool:\n\t\tfor k, v := range m {\n\t\t\toffset = e.writeUint(k, offset)\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\t}\n\treturn offset, false\n}\n"
  },
  {
    "path": "internal/encoding/nil.go",
    "content": "package encoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\nfunc (e *encoder) writeNil(offset int) int {\n\toffset = e.setByte1Int(def.Nil, offset)\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/set.go",
    "content": "package encoding\n\nfunc (e *encoder) setByte1Int64(value int64, offset int) int {\n\te.d[offset] = byte(value)\n\treturn offset + 1\n}\n\nfunc (e *encoder) setByte2Int64(value int64, offset int) int {\n\te.d[offset+0] = byte(value >> 8)\n\te.d[offset+1] = byte(value)\n\treturn offset + 2\n}\n\nfunc (e *encoder) setByte4Int64(value int64, offset int) int {\n\te.d[offset+0] = byte(value >> 24)\n\te.d[offset+1] = byte(value >> 16)\n\te.d[offset+2] = byte(value >> 8)\n\te.d[offset+3] = byte(value)\n\treturn offset + 4\n}\n\nfunc (e *encoder) setByte8Int64(value int64, offset int) int {\n\te.d[offset] = byte(value >> 56)\n\te.d[offset+1] = byte(value >> 48)\n\te.d[offset+2] = byte(value >> 40)\n\te.d[offset+3] = byte(value >> 32)\n\te.d[offset+4] = byte(value >> 24)\n\te.d[offset+5] = byte(value >> 16)\n\te.d[offset+6] = byte(value >> 8)\n\te.d[offset+7] = byte(value)\n\treturn offset + 8\n}\n\nfunc (e *encoder) setByte1Uint64(value uint64, offset int) int {\n\te.d[offset] = byte(value)\n\treturn offset + 1\n}\n\nfunc (e *encoder) setByte2Uint64(value uint64, offset int) int {\n\te.d[offset] = byte(value >> 8)\n\te.d[offset+1] = byte(value)\n\treturn offset + 2\n}\n\nfunc (e *encoder) setByte4Uint64(value uint64, offset int) int {\n\te.d[offset] = byte(value >> 24)\n\te.d[offset+1] = byte(value >> 16)\n\te.d[offset+2] = byte(value >> 8)\n\te.d[offset+3] = byte(value)\n\treturn offset + 4\n}\n\nfunc (e *encoder) setByte8Uint64(value uint64, offset int) int {\n\te.d[offset] = byte(value >> 56)\n\te.d[offset+1] = byte(value >> 48)\n\te.d[offset+2] = byte(value >> 40)\n\te.d[offset+3] = byte(value >> 32)\n\te.d[offset+4] = byte(value >> 24)\n\te.d[offset+5] = byte(value >> 16)\n\te.d[offset+6] = byte(value >> 8)\n\te.d[offset+7] = byte(value)\n\treturn offset + 8\n}\n\nfunc (e *encoder) setByte1Int(code, offset int) int {\n\te.d[offset] = byte(code)\n\treturn offset + 1\n}\n\nfunc (e *encoder) setByte2Int(value int, offset int) int {\n\te.d[offset] = byte(value >> 8)\n\te.d[offset+1] = byte(value)\n\treturn offset + 2\n}\n\nfunc (e *encoder) setByte4Int(value int, offset int) int {\n\te.d[offset] = byte(value >> 24)\n\te.d[offset+1] = byte(value >> 16)\n\te.d[offset+2] = byte(value >> 8)\n\te.d[offset+3] = byte(value)\n\treturn offset + 4\n}\n\nfunc (e *encoder) setBytes(bs []byte, offset int) int {\n\tfor i := range bs {\n\t\te.d[offset+i] = bs[i]\n\t}\n\treturn offset + len(bs)\n}\n"
  },
  {
    "path": "internal/encoding/slice.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcFixedSlice(rv reflect.Value) (int, bool) {\n\t// calcLength formally returns (int, error), but for map lengths in Go\n\t// the error case is unreachable. The error value is always nil and is\n\t// intentionally ignored with `_`.\n\tswitch sli := rv.Interface().(type) {\n\tcase []int:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []uint:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []string:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcString(v)\n\t\t}\n\t\treturn size, true\n\n\tcase []float32:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcFloat32(float64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []float64:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcFloat64(v)\n\t\t}\n\t\treturn size, true\n\n\tcase []bool:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tsize += def.Byte1 * len(sli)\n\t\treturn size, true\n\n\tcase []int8:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []int16:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []int32:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcInt(int64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []int64:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcInt(v)\n\t\t}\n\t\treturn size, true\n\n\tcase []uint8:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []uint16:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []uint32:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcUint(uint64(v))\n\t\t}\n\t\treturn size, true\n\n\tcase []uint64:\n\t\tsize, _ := e.calcLength(len(sli))\n\t\tfor _, v := range sli {\n\t\t\tsize += e.calcUint(v)\n\t\t}\n\t\treturn size, true\n\t}\n\n\treturn 0, false\n}\n\nfunc (e *encoder) writeSliceLength(l int, offset int) int {\n\t// format size\n\tif l <= 0x0f {\n\t\toffset = e.setByte1Int(def.FixArray+l, offset)\n\t} else if l <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Array16, offset)\n\t\toffset = e.setByte2Int(l, offset)\n\t} else if uint(l) <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Array32, offset)\n\t\toffset = e.setByte4Int(l, offset)\n\t}\n\treturn offset\n}\n\nfunc (e *encoder) writeFixedSlice(rv reflect.Value, offset int) (int, bool) {\n\tswitch sli := rv.Interface().(type) {\n\tcase []int:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []uint:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []string:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeString(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []float32:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeFloat32(float64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []float64:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeFloat64(float64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []bool:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeBool(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []int8:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []int16:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []int32:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeInt(int64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []int64:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeInt(v, offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []uint8:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []uint16:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []uint32:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeUint(uint64(v), offset)\n\t\t}\n\t\treturn offset, true\n\n\tcase []uint64:\n\t\toffset = e.writeSliceLength(len(sli), offset)\n\t\tfor _, v := range sli {\n\t\t\toffset = e.writeUint(v, offset)\n\t\t}\n\t\treturn offset, true\n\t}\n\n\treturn offset, false\n}\n"
  },
  {
    "path": "internal/encoding/slice_test.go",
    "content": "package encoding\n\nimport (\n\t\"reflect\"\n\t\"testing\"\n\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_FixedSlice(t *testing.T) {\n\ttestcases := []struct {\n\t\tvalue any\n\t\tsize  int\n\t}{\n\t\t{\n\t\t\tvalue: []int{-1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []uint{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []string{\"a\"},\n\t\t\tsize:  3,\n\t\t},\n\t\t{\n\t\t\tvalue: []float32{1.23},\n\t\t\tsize:  6,\n\t\t},\n\t\t{\n\t\t\tvalue: []float64{1.23},\n\t\t\tsize:  10,\n\t\t},\n\t\t{\n\t\t\tvalue: []bool{true},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []int8{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []int16{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []int32{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []int64{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []uint8{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []uint16{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []uint32{1},\n\t\t\tsize:  2,\n\t\t},\n\t\t{\n\t\t\tvalue: []uint64{1},\n\t\t\tsize:  2,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\trv := reflect.ValueOf(tc.value)\n\t\tt.Run(rv.Type().String(), func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tsize, b := e.calcFixedSlice(rv)\n\t\t\ttu.Equal(t, b, true)\n\t\t\ttu.Equal(t, size, tc.size)\n\n\t\t\te.d = make([]byte, size)\n\t\t\tresult, b := e.writeFixedSlice(rv, 0)\n\t\t\ttu.Equal(t, b, true)\n\t\t\ttu.Equal(t, result, size)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/encoding/string.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"unsafe\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcString(v string) int {\n\t// NOTE : unsafe\n\tstrBytes := *(*[]byte)(unsafe.Pointer(&v))\n\tl := len(strBytes)\n\tif l < 32 {\n\t\treturn def.Byte1 + l\n\t} else if l <= math.MaxUint8 {\n\t\treturn def.Byte1 + def.Byte1 + l\n\t} else if l <= math.MaxUint16 {\n\t\treturn def.Byte1 + def.Byte2 + l\n\t}\n\treturn def.Byte1 + def.Byte4 + l\n\t// NOTE : length over uint32\n}\n\nfunc (e *encoder) writeString(str string, offset int) int {\n\t// NOTE : unsafe\n\tstrBytes := *(*[]byte)(unsafe.Pointer(&str))\n\tl := len(strBytes)\n\tif l < 32 {\n\t\toffset = e.setByte1Int(def.FixStr+l, offset)\n\t} else if l <= math.MaxUint8 {\n\t\toffset = e.setByte1Int(def.Str8, offset)\n\t\toffset = e.setByte1Int(l, offset)\n\t} else if l <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Str16, offset)\n\t\toffset = e.setByte2Int(l, offset)\n\t} else {\n\t\toffset = e.setByte1Int(def.Str32, offset)\n\t\toffset = e.setByte4Int(l, offset)\n\t}\n\toffset += copy(e.d[offset:], str)\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/struct.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype structCache struct {\n\t// common fields\n\tnames  []string\n\tomits  []bool\n\tnoOmit bool\n\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes   [][]int   // field path (support for embedded structs)\n\tomitPaths [][][]int // embedded omitempty parent paths\n\n\tcommon.Common\n}\n\nvar cachemap = sync.Map{}\n\ntype (\n\tstructCalcFunc  func(rv reflect.Value) (int, error)\n\tstructWriteFunc func(rv reflect.Value, offset int) int\n)\n\n// getFieldByPath returns the field value by following the path of indices.\n// The bool indicates whether the path was reachable (no nil pointer in the path).\nfunc getFieldByPath(rv reflect.Value, path []int) (reflect.Value, bool) {\n\tfor _, idx := range path {\n\t\t// Handle pointer indirection if needed\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\tif rv.IsNil() {\n\t\t\t\t// Return invalid value if pointer is nil\n\t\t\t\treturn reflect.Value{}, false\n\t\t\t}\n\t\t\trv = rv.Elem()\n\t\t}\n\t\trv = rv.Field(idx)\n\t}\n\treturn rv, true\n}\n\nfunc shouldOmitByParent(rv reflect.Value, omitPaths [][]int) bool {\n\tfor _, path := range omitPaths {\n\t\tparentValue, ok := getFieldByPath(rv, path)\n\t\tif !ok || parentValue.IsZero() {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (e *encoder) getStructCalc(typ reflect.Type) structCalcFunc {\n\tfor j := range extCoders {\n\t\tif extCoders[j].Type() == typ {\n\t\t\treturn extCoders[j].CalcByteSize\n\t\t}\n\t}\n\tif e.asArray {\n\t\treturn e.calcStructArray\n\t}\n\treturn e.calcStructMap\n}\n\nfunc (e *encoder) calcStruct(rv reflect.Value) (int, error) {\n\t//if isTime, tm := e.isDateTime(rv); isTime {\n\t//\tsize := e.calcTime(tm)\n\t//\treturn size, nil\n\t//}\n\n\tfor i := range extCoders {\n\t\tif extCoders[i].Type() == rv.Type() {\n\t\t\treturn extCoders[i].CalcByteSize(rv)\n\t\t}\n\t}\n\n\tif e.asArray {\n\t\treturn e.calcStructArray(rv)\n\t}\n\treturn e.calcStructMap(rv)\n}\n\nfunc (e *encoder) calcStructArray(rv reflect.Value) (int, error) {\n\tret := 0\n\tt := rv.Type()\n\tcache, find := cachemap.Load(t)\n\tvar c *structCache\n\tif !find {\n\t\tc = &structCache{}\n\t\tfields := e.CollectFields(t, nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tc.hasEmbedded = hasEmbedded\n\n\t\tomitCount := 0\n\t\tfor _, field := range fields {\n\t\t\tc.names = append(c.names, field.Name)\n\t\t\tc.omits = append(c.omits, field.Omit)\n\t\t\tif hasEmbedded {\n\t\t\t\tc.indexes = append(c.indexes, field.Path)\n\t\t\t\tc.omitPaths = append(c.omitPaths, field.OmitPaths)\n\t\t\t} else {\n\t\t\t\tc.simpleIndexes = append(c.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t\tif field.Omit {\n\t\t\t\tomitCount++\n\t\t\t}\n\t\t}\n\t\tc.noOmit = omitCount == 0\n\t\tcachemap.Store(t, c)\n\t} else {\n\t\tc = cache.(*structCache)\n\t}\n\n\t// calculate size based on path type\n\tvar numFields int\n\tif c.hasEmbedded {\n\t\tnumFields = len(c.indexes)\n\t\tfor i := 0; i < numFields; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tfieldValue = reflect.Value{}\n\t\t\t}\n\t\t\tsize, err := e.calcSize(fieldValue)\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret += size\n\t\t}\n\t} else {\n\t\tnumFields = len(c.simpleIndexes)\n\t\tfor i := 0; i < numFields; i++ {\n\t\t\tsize, err := e.calcSize(rv.Field(c.simpleIndexes[i]))\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret += size\n\t\t}\n\t}\n\n\t// format size\n\tsize, err := e.calcLength(numFields)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tret += size\n\treturn ret, nil\n}\n\nfunc (e *encoder) calcStructMap(rv reflect.Value) (int, error) {\n\tret := 0\n\tt := rv.Type()\n\tcache, find := cachemap.Load(t)\n\tvar c *structCache\n\tif !find {\n\t\tc = &structCache{}\n\t\tfields := e.CollectFields(t, nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tc.hasEmbedded = hasEmbedded\n\n\t\tomitCount := 0\n\t\tfor _, field := range fields {\n\t\t\tc.names = append(c.names, field.Name)\n\t\t\tc.omits = append(c.omits, field.Omit)\n\t\t\tif hasEmbedded {\n\t\t\t\tc.indexes = append(c.indexes, field.Path)\n\t\t\t\tc.omitPaths = append(c.omitPaths, field.OmitPaths)\n\t\t\t} else {\n\t\t\t\tc.simpleIndexes = append(c.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t\tif field.Omit {\n\t\t\t\tomitCount++\n\t\t\t}\n\t\t}\n\t\tc.noOmit = omitCount == 0\n\t\tcachemap.Store(t, c)\n\t} else {\n\t\tc = cache.(*structCache)\n\t}\n\n\tl := 0\n\tif c.hasEmbedded {\n\t\tfor i := 0; i < len(c.indexes); i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tsize, err := e.calcSizeWithOmitEmpty(fieldValue, c.names[i], c.omits[i])\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret += size\n\t\t\tif size > 0 {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < len(c.simpleIndexes); i++ {\n\t\t\tsize, err := e.calcSizeWithOmitEmpty(rv.Field(c.simpleIndexes[i]), c.names[i], c.omits[i])\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\t\t\tret += size\n\t\t\tif size > 0 {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t}\n\n\t// format size\n\tsize, err := e.calcLength(l)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\tret += size\n\treturn ret, nil\n}\n\nfunc (e *encoder) calcSizeWithOmitEmpty(rv reflect.Value, name string, omit bool) (int, error) {\n\tkeySize := 0\n\tvalueSize := 0\n\tif !omit || !rv.IsZero() {\n\t\tkeySize = e.calcString(name)\n\t\tvSize, err := e.calcSize(rv)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tvalueSize = vSize\n\t}\n\treturn keySize + valueSize, nil\n}\n\nfunc (e *encoder) getStructWriter(typ reflect.Type) structWriteFunc {\n\tfor i := range extCoders {\n\t\tif extCoders[i].Type() == typ {\n\t\t\treturn func(rv reflect.Value, offset int) int {\n\t\t\t\treturn extCoders[i].WriteToBytes(rv, offset, &e.d)\n\t\t\t}\n\t\t}\n\t}\n\n\tif e.asArray {\n\t\treturn e.writeStructArray\n\t}\n\treturn e.writeStructMap\n}\n\nfunc (e *encoder) writeStruct(rv reflect.Value, offset int) int {\n\t/*\n\t\tif isTime, tm := e.isDateTime(rv); isTime {\n\t\t\treturn e.writeTime(tm, offset)\n\t\t}\n\t*/\n\n\tfor i := range extCoders {\n\t\tif extCoders[i].Type() == rv.Type() {\n\t\t\treturn extCoders[i].WriteToBytes(rv, offset, &e.d)\n\t\t}\n\t}\n\n\tif e.asArray {\n\t\treturn e.writeStructArray(rv, offset)\n\t}\n\treturn e.writeStructMap(rv, offset)\n}\n\nfunc (e *encoder) writeStructArray(rv reflect.Value, offset int) int {\n\tcache, _ := cachemap.Load(rv.Type())\n\tc := cache.(*structCache)\n\n\t// write format\n\tvar num int\n\tif c.hasEmbedded {\n\t\tnum = len(c.indexes)\n\t} else {\n\t\tnum = len(c.simpleIndexes)\n\t}\n\n\tif num <= 0x0f {\n\t\toffset = e.setByte1Int(def.FixArray+num, offset)\n\t} else if num <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Array16, offset)\n\t\toffset = e.setByte2Int(num, offset)\n\t} else if uint(num) <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Array32, offset)\n\t\toffset = e.setByte4Int(num, offset)\n\t}\n\n\tif c.hasEmbedded {\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tfieldValue = reflect.Value{}\n\t\t\t}\n\t\t\toffset = e.create(fieldValue, offset)\n\t\t}\n\t} else {\n\t\tfor i := 0; i < num; i++ {\n\t\t\toffset = e.create(rv.Field(c.simpleIndexes[i]), offset)\n\t\t}\n\t}\n\treturn offset\n}\n\nfunc (e *encoder) writeStructMap(rv reflect.Value, offset int) int {\n\tcache, _ := cachemap.Load(rv.Type())\n\tc := cache.(*structCache)\n\n\t// format size\n\tl := 0\n\tif c.hasEmbedded {\n\t\tnum := len(c.indexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnum := len(c.simpleIndexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tif c.noOmit || !c.omits[i] || !rv.Field(c.simpleIndexes[i]).IsZero() {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t}\n\n\tif l <= 0x0f {\n\t\toffset = e.setByte1Int(def.FixMap+l, offset)\n\t} else if l <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Map16, offset)\n\t\toffset = e.setByte2Int(l, offset)\n\t} else if uint(l) <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Map32, offset)\n\t\toffset = e.setByte4Int(l, offset)\n\t}\n\n\tif c.hasEmbedded {\n\t\tnum := len(c.indexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\toffset = e.writeString(c.names[i], offset)\n\t\t\t\toffset = e.create(fieldValue, offset)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnum := len(c.simpleIndexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue := rv.Field(c.simpleIndexes[i])\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\toffset = e.writeString(c.names[i], offset)\n\t\t\t\toffset = e.create(fieldValue, offset)\n\t\t\t}\n\t\t}\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/encoding/struct_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_calcStructArray(t *testing.T) {\n\ttype b struct {\n\t\tB []byte\n\t}\n\n\tt.Run(\"non-cache\", func(t *testing.T) {\n\t\tvalue := b{B: make([]byte, math.MaxUint32+1)}\n\t\te := encoder{}\n\t\trv := reflect.ValueOf(value)\n\t\t_, err := e.calcStructArray(rv)\n\t\ttu.IsError(t, err, def.ErrUnsupportedType)\n\t})\n\tt.Run(\"cache\", func(t *testing.T) {\n\t\tvalue := b{B: make([]byte, 1)}\n\t\te := encoder{}\n\t\trv := reflect.ValueOf(value)\n\t\t_, err := e.calcStructArray(rv)\n\t\ttu.NoError(t, err)\n\n\t\tvalue = b{B: make([]byte, math.MaxUint32+1)}\n\t\trv = reflect.ValueOf(value)\n\t\t_, err = e.calcStructArray(rv)\n\t\ttu.IsError(t, err, def.ErrUnsupportedType)\n\t})\n\n\ttestcases := []struct {\n\t\tname   string\n\t\tvalue  int\n\t\tresult int\n\t\terror  error\n\t}{\n\t\t{\n\t\t\tname:   \"0x0f\",\n\t\t\tvalue:  0x0f,\n\t\t\tresult: def.Byte1,\n\t\t},\n\t\t{\n\t\t\tname:   \"u16\",\n\t\t\tvalue:  math.MaxUint16,\n\t\t\tresult: def.Byte1 + def.Byte2,\n\t\t},\n\t\t{\n\t\t\tname:   \"u32\",\n\t\t\tvalue:  math.MaxUint16 + 1,\n\t\t\tresult: def.Byte1 + def.Byte4,\n\t\t},\n\t\t// can not run by out of memory\n\t\t//{\n\t\t//\tname:   \"u32over\",\n\t\t//\tvalue:  math.MaxUint32 + 1,\n\t\t//\tresult: 0,\n\t\t//},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tv, _, bs := tu.CreateStruct(tc.value)\n\t\t\trv := reflect.ValueOf(v).Elem()\n\t\t\tresult, err := e.calcStructArray(rv)\n\t\t\ttu.IsError(t, err, tc.error)\n\t\t\ttu.Equal(t, result, tc.result+len(bs))\n\t\t})\n\t}\n}\n\nfunc Test_calcStructMap(t *testing.T) {\n\ttype b struct {\n\t\tB []byte\n\t}\n\n\tt.Run(\"non-cache\", func(t *testing.T) {\n\t\tvalue := b{B: make([]byte, math.MaxUint32+1)}\n\t\te := encoder{}\n\t\trv := reflect.ValueOf(value)\n\t\t_, err := e.calcStructMap(rv)\n\t\ttu.IsError(t, err, def.ErrUnsupportedType)\n\t})\n\tt.Run(\"cache\", func(t *testing.T) {\n\t\tvalue := b{B: make([]byte, 1)}\n\t\te := encoder{}\n\t\trv := reflect.ValueOf(value)\n\t\t_, err := e.calcStructMap(rv)\n\t\ttu.NoError(t, err)\n\n\t\tvalue = b{B: make([]byte, math.MaxUint32+1)}\n\t\trv = reflect.ValueOf(value)\n\t\t_, err = e.calcStructMap(rv)\n\t\ttu.IsError(t, err, def.ErrUnsupportedType)\n\t})\n\n\ttestcases := []struct {\n\t\tname   string\n\t\tvalue  int\n\t\tresult int\n\t\terror  error\n\t}{\n\t\t{\n\t\t\tname:   \"0x0f\",\n\t\t\tvalue:  0x0f,\n\t\t\tresult: def.Byte1,\n\t\t},\n\t\t{\n\t\t\tname:   \"u16\",\n\t\t\tvalue:  math.MaxUint16,\n\t\t\tresult: def.Byte1 + def.Byte2,\n\t\t},\n\t\t{\n\t\t\tname:   \"u32\",\n\t\t\tvalue:  math.MaxUint16 + 1,\n\t\t\tresult: def.Byte1 + def.Byte4,\n\t\t},\n\t\t// can not run by out of memory\n\t\t//{\n\t\t//\tname:   \"u32over\",\n\t\t//\tvalue:  math.MaxUint32 + 1,\n\t\t//\tresult: 0,\n\t\t//},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tv, bs, _ := tu.CreateStruct(tc.value)\n\t\t\trv := reflect.ValueOf(v).Elem()\n\t\t\tresult, err := e.calcStructMap(rv)\n\t\t\ttu.IsError(t, err, tc.error)\n\t\t\ttu.Equal(t, result, tc.result+len(bs))\n\t\t})\n\t}\n}\n\nfunc Test_writeStructArray(t *testing.T) {\n\ttestcases := []struct {\n\t\tname  string\n\t\tvalue int\n\t\tcode  byte\n\t}{\n\t\t{\n\t\t\tname:  \"0x0f\",\n\t\t\tvalue: 0x0f,\n\t\t\tcode:  def.FixArray + 0x0f,\n\t\t},\n\t\t{\n\t\t\tname:  \"u16\",\n\t\t\tvalue: math.MaxUint16,\n\t\t\tcode:  def.Array16,\n\t\t},\n\t\t{\n\t\t\tname:  \"u32\",\n\t\t\tvalue: math.MaxUint16 + 1,\n\t\t\tcode:  def.Array32,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tv, _, _ := tu.CreateStruct(tc.value)\n\t\t\trv := reflect.ValueOf(v).Elem()\n\t\t\tsize, err := e.calcStructArray(rv)\n\t\t\ttu.NoError(t, err)\n\n\t\t\te.d = make([]byte, size)\n\t\t\tresult := e.writeStructArray(rv, 0)\n\t\t\ttu.Equal(t, len(e.d), result)\n\t\t\ttu.Equal(t, e.d[0], tc.code)\n\t\t})\n\t}\n}\n\nfunc Test_writeStructMap(t *testing.T) {\n\ttestcases := []struct {\n\t\tname  string\n\t\tvalue int\n\t\tcode  byte\n\t}{\n\t\t{\n\t\t\tname:  \"0x0f\",\n\t\t\tvalue: 0x0f,\n\t\t\tcode:  def.FixMap + 0x0f,\n\t\t},\n\t\t{\n\t\t\tname:  \"u16\",\n\t\t\tvalue: math.MaxUint16,\n\t\t\tcode:  def.Map16,\n\t\t},\n\t\t{\n\t\t\tname:  \"u32\",\n\t\t\tvalue: math.MaxUint16 + 1,\n\t\t\tcode:  def.Map32,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\te := encoder{}\n\t\t\tv, _, _ := tu.CreateStruct(tc.value)\n\t\t\trv := reflect.ValueOf(v).Elem()\n\t\t\tsize, err := e.calcStructMap(rv)\n\t\t\ttu.NoError(t, err)\n\n\t\t\te.d = make([]byte, size)\n\t\t\tresult := e.writeStructMap(rv, 0)\n\t\t\ttu.Equal(t, len(e.d), result)\n\t\t\ttu.Equal(t, e.d[0], tc.code)\n\t\t})\n\t}\n}\n\nfunc Test_calcSizeWithOmitEmpty(t *testing.T) {\n\te := encoder{}\n\tvar v any\n\tv = func() {}\n\t_, err := e.calcSizeWithOmitEmpty(reflect.ValueOf(v), \"a\", false)\n\ttu.Error(t, err)\n\n\tv = 1\n\t_, err = e.calcSizeWithOmitEmpty(reflect.ValueOf(v), \"a\", false)\n\ttu.NoError(t, err)\n}\n\nfunc Test_structCache(t *testing.T) {\n\ttype forMap struct {\n\t\tInt  int\n\t\tUint uint `msgpack:\",omitempty\"`\n\t\tStr  string\n\t}\n\ttype forMapNoOmit struct {\n\t\tInt  int\n\t\tUint uint\n\t\tStr  string\n\t}\n\ttype forArray struct {\n\t\tInt  int `msgpack:\",omitempty\"`\n\t\tUint uint\n\t\tStr  string `msgpack:\",omitempty\"`\n\t}\n\ttype forArrayNoOmit struct {\n\t\tInt  int\n\t\tUint uint\n\t\tStr  string\n\t}\n\n\te := encoder{}\n\ttestcases := []struct {\n\t\tv         any\n\t\tomitCount int\n\t\tf         func(rv reflect.Value) (int, error)\n\t}{\n\t\t{\n\t\t\tv:         forMap{},\n\t\t\tomitCount: 1,\n\t\t\tf:         e.calcStructMap,\n\t\t},\n\n\t\t{\n\t\t\tv:         forMapNoOmit{},\n\t\t\tomitCount: 0,\n\t\t\tf:         e.calcStructMap,\n\t\t},\n\t\t{\n\t\t\tv:         forArray{},\n\t\t\tomitCount: 2,\n\t\t\tf:         e.calcStructArray,\n\t\t},\n\n\t\t{\n\t\t\tv:         forArrayNoOmit{},\n\t\t\tomitCount: 0,\n\t\t\tf:         e.calcStructArray,\n\t\t},\n\t}\n\n\tfor _, c := range testcases {\n\t\trv := reflect.ValueOf(c.v)\n\t\tt.Run(rv.String(), func(t *testing.T) {\n\t\t\t_, found := cachemap.Load(rv.Type())\n\t\t\ttu.Equal(t, found, false)\n\n\t\t\t_, err := c.f(rv)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tcache, _ := cachemap.Load(rv.Type())\n\t\t\tca, ok := cache.(*structCache)\n\t\t\ttu.Equal(t, ok, true)\n\t\t\ttu.Equal(t, len(ca.omits), rv.NumField())\n\t\t\tcount := 0\n\t\t\tfor _, b := range ca.omits {\n\t\t\t\tif b {\n\t\t\t\t\tcount++\n\t\t\t\t}\n\t\t\t}\n\t\t\ttu.Equal(t, count, c.omitCount)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/encoding/uint.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) calcUint(v uint64) int {\n\tif v <= math.MaxInt8 {\n\t\t// format code only\n\t\treturn def.Byte1\n\t} else if v <= math.MaxUint8 {\n\t\treturn def.Byte1 + def.Byte1\n\t} else if v <= math.MaxUint16 {\n\t\treturn def.Byte1 + def.Byte2\n\t} else if v <= math.MaxUint32 {\n\t\treturn def.Byte1 + def.Byte4\n\t}\n\treturn def.Byte1 + def.Byte8\n}\n\nfunc (e *encoder) writeUint(v uint64, offset int) int {\n\tif v <= math.MaxInt8 {\n\t\toffset = e.setByte1Uint64(v, offset)\n\t} else if v <= math.MaxUint8 {\n\t\toffset = e.setByte1Int(def.Uint8, offset)\n\t\toffset = e.setByte1Uint64(v, offset)\n\t} else if v <= math.MaxUint16 {\n\t\toffset = e.setByte1Int(def.Uint16, offset)\n\t\toffset = e.setByte2Uint64(v, offset)\n\t} else if v <= math.MaxUint32 {\n\t\toffset = e.setByte1Int(def.Uint32, offset)\n\t\toffset = e.setByte4Uint64(v, offset)\n\t} else {\n\t\toffset = e.setByte1Int(def.Uint64, offset)\n\t\toffset = e.setByte8Uint64(v, offset)\n\t}\n\treturn offset\n}\n"
  },
  {
    "path": "internal/stream/decoding/bin.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"unsafe\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) isCodeBin(v byte) bool {\n\tswitch v {\n\tcase def.Bin8, def.Bin16, def.Bin32:\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (d *decoder) asBinWithCode(code byte, k reflect.Kind) ([]byte, error) {\n\tswitch code {\n\tcase def.Bin8:\n\t\tl, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn emptyBytes, err\n\t\t}\n\t\t// avoid common buffer reference\n\t\treturn d.copySizeN(int(l))\n\n\tcase def.Bin16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn emptyBytes, err\n\t\t}\n\t\t// avoid common buffer reference\n\t\treturn d.copySizeN(int(binary.BigEndian.Uint16(bs)))\n\n\tcase def.Bin32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn emptyBytes, err\n\t\t}\n\t\t// avoid common buffer reference\n\t\treturn d.copySizeN(int(binary.BigEndian.Uint32(bs)))\n\t}\n\n\treturn emptyBytes, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asBinStringWithCode(code byte, k reflect.Kind) (string, error) {\n\tbs, err := d.asBinWithCode(code, k)\n\treturn *(*string)(unsafe.Pointer(&bs)), err\n}\n\nfunc (d *decoder) copySizeN(n int) ([]byte, error) {\n\tbs, err := d.readSizeN(n)\n\tif err != nil {\n\t\treturn emptyBytes, err\n\t}\n\tv := make([]byte, n)\n\tcopy(v, bs)\n\treturn v, nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/bin_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_isCodeBin(t *testing.T) {\n\td := decoder{}\n\tfor i := 0x00; i <= 0xff; i++ {\n\t\tv := byte(i)\n\t\tisBin := v == def.Bin8 || v == def.Bin16 || v == def.Bin32\n\t\ttu.Equal(t, d.isCodeBin(v), isBin)\n\t}\n}\n\nfunc Test_asBinWithCode(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) ([]byte, error) {\n\t\treturn d.asBinWithCode\n\t}\n\ttestcases := AsXXXTestCases[[]byte]{\n\t\t{\n\t\t\tName:             \"Bin8.error.size\",\n\t\t\tCode:             def.Bin8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin8.error.data\",\n\t\t\tCode:             def.Bin8,\n\t\t\tData:             []byte{1},\n\t\t\tReadCount:        1,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin8.ok\",\n\t\t\tCode:             def.Bin8,\n\t\t\tData:             []byte{1, 'a'},\n\t\t\tExpected:         []byte{'a'},\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin16.error\",\n\t\t\tCode:             def.Bin16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin16.error.data\",\n\t\t\tCode:             def.Bin16,\n\t\t\tData:             []byte{0, 1},\n\t\t\tReadCount:        1,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin16.ok\",\n\t\t\tCode:             def.Bin16,\n\t\t\tData:             []byte{0, 1, 'b'},\n\t\t\tExpected:         []byte{'b'},\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin32.error\",\n\t\t\tCode:             def.Bin32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin32.error.data\",\n\t\t\tCode:             def.Bin32,\n\t\t\tData:             []byte{0, 0, 0, 1},\n\t\t\tReadCount:        1,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin32.ok\",\n\t\t\tCode:             def.Bin32,\n\t\t\tData:             []byte{0, 0, 0, 1, 'c'},\n\t\t\tExpected:         []byte{'c'},\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/bool.go",
    "content": "package decoding\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asBool(k reflect.Kind) (bool, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn false, err\n\t}\n\treturn d.asBoolWithCode(code, k)\n}\n\nfunc (d *decoder) asBoolWithCode(code byte, k reflect.Kind) (bool, error) {\n\tswitch code {\n\tcase def.True:\n\t\treturn true, nil\n\tcase def.False:\n\t\treturn false, nil\n\t}\n\treturn false, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/bool_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asBool(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (bool, error) {\n\t\treturn d.asBool\n\t}\n\ttestcases := AsXXXTestCases[bool]{\n\t\t{\n\t\t\tName:      \"error\",\n\t\t\tReadCount: 0,\n\t\t\tError:     io.EOF,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.True},\n\t\t\tExpected:  true,\n\t\t\tReadCount: 1,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asBoolWithCode(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (bool, error) {\n\t\treturn d.asBoolWithCode\n\t}\n\ttestcases := AsXXXTestCases[bool]{\n\t\t{\n\t\t\tName:             \"True\",\n\t\t\tCode:             def.True,\n\t\t\tExpected:         true,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"False\",\n\t\t\tCode:             def.False,\n\t\t\tExpected:         false,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/complex.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asComplex64(code byte, k reflect.Kind) (complex64, error) {\n\tswitch code {\n\tcase def.Fixext8:\n\t\tt, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), fmt.Errorf(\"fixext8. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tr := math.Float32frombits(binary.BigEndian.Uint32(rb))\n\n\t\tib, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\ti := math.Float32frombits(binary.BigEndian.Uint32(ib))\n\t\treturn complex(r, i), nil\n\n\tcase def.Fixext16:\n\t\tt, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), fmt.Errorf(\"fixext16. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tr := math.Float64frombits(binary.BigEndian.Uint64(rb))\n\n\t\tib, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\ti := math.Float64frombits(binary.BigEndian.Uint64(ib))\n\t\treturn complex64(complex(r, i)), nil\n\n\t}\n\n\treturn complex(0, 0), d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asComplex128(code byte, k reflect.Kind) (complex128, error) {\n\tswitch code {\n\tcase def.Fixext8:\n\t\tt, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), fmt.Errorf(\"fixext8. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tr := math.Float32frombits(binary.BigEndian.Uint32(rb))\n\n\t\tib, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\ti := math.Float32frombits(binary.BigEndian.Uint32(ib))\n\t\treturn complex128(complex(r, i)), nil\n\n\tcase def.Fixext16:\n\t\tt, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tif int8(t) != def.ComplexTypeCode() {\n\t\t\treturn complex(0, 0), fmt.Errorf(\"fixext16. complex type is diffrent %d, %d\", t, def.ComplexTypeCode())\n\t\t}\n\t\trb, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\tr := math.Float64frombits(binary.BigEndian.Uint64(rb))\n\n\t\tib, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn complex(0, 0), err\n\t\t}\n\t\ti := math.Float64frombits(binary.BigEndian.Uint64(ib))\n\t\treturn complex(r, i), nil\n\n\t}\n\n\treturn complex(0, 0), d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/complex_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asComplex64(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (complex64, error) {\n\t\treturn d.asComplex64\n\t}\n\ttestcases := AsXXXTestCases[complex64]{\n\t\t{\n\t\t\tName:             \"Fixext8.error.type\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.error.r\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode())},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.error.i\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.ok\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\tExpected:         complex(1, 1),\n\t\t\tReadCount:        3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.type\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.r\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode())},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.i\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName: \"Fixext16.ok\",\n\t\t\tCode: def.Fixext16,\n\t\t\tData: []byte{\n\t\t\t\tbyte(def.ComplexTypeCode()),\n\t\t\t\t63, 240, 0, 0, 0, 0, 0, 0, 63, 240, 0, 0, 0, 0, 0, 0,\n\t\t\t},\n\t\t\tExpected:         complex(1, 1),\n\t\t\tReadCount:        3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asComplex128(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (complex128, error) {\n\t\treturn d.asComplex128\n\t}\n\ttestcases := AsXXXTestCases[complex128]{\n\t\t{\n\t\t\tName:             \"Fixext8.error.type\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.error.r\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode())},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.error.i\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext8.ok\",\n\t\t\tCode:             def.Fixext8,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\tExpected:         complex(1, 1),\n\t\t\tReadCount:        3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.type\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.r\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode())},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Fixext16.error.i\",\n\t\t\tCode:             def.Fixext16,\n\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 0, 0, 0, 1},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        2,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName: \"Fixext16.ok\",\n\t\t\tCode: def.Fixext16,\n\t\t\tData: []byte{\n\t\t\t\tbyte(def.ComplexTypeCode()),\n\t\t\t\t63, 240, 0, 0, 0, 0, 0, 0, 63, 240, 0, 0, 0, 0, 0, 0,\n\t\t\t},\n\t\t\tExpected:         complex(1, 1),\n\t\t\tReadCount:        3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/decoding.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype decoder struct {\n\tr       io.Reader\n\tasArray bool\n\tbuf     *common.Buffer\n\tcommon.Common\n}\n\n// Decode analyzes the MessagePack-encoded data and stores\n// the result into the pointer of v.\nfunc Decode(r io.Reader, v interface{}, asArray bool) error {\n\tif r == nil {\n\t\treturn def.ErrNoData\n\t}\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() != reflect.Ptr {\n\t\treturn fmt.Errorf(\"%w. v.(type): %T\", def.ErrReceiverNotPointer, v)\n\t}\n\n\trv = rv.Elem()\n\n\td := decoder{\n\t\tr:       r,\n\t\tbuf:     common.GetBuffer(),\n\t\tasArray: asArray,\n\t}\n\terr := d.decode(rv)\n\tcommon.PutBuffer(d.buf)\n\treturn err\n}\n\nfunc (d *decoder) decode(rv reflect.Value) error {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn d.decodeWithCode(code, rv)\n}\n\nfunc (d *decoder) decodeWithCode(code byte, rv reflect.Value) error {\n\tk := rv.Kind()\n\tswitch k {\n\tcase reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetInt(v)\n\n\tcase reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetUint(v)\n\n\tcase reflect.Float32:\n\t\tv, err := d.asFloat32WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetFloat(float64(v))\n\n\tcase reflect.Float64:\n\t\tv, err := d.asFloat64WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetFloat(v)\n\n\tcase reflect.String:\n\t\t// byte slice\n\t\tif d.isCodeBin(code) {\n\t\t\tv, err := d.asBinStringWithCode(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trv.SetString(v)\n\t\t\treturn nil\n\t\t}\n\t\tv, err := d.asStringWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetString(v)\n\n\tcase reflect.Bool:\n\t\tv, err := d.asBoolWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetBool(v)\n\n\tcase reflect.Slice:\n\t\t// nil\n\t\tif d.isCodeNil(code) {\n\t\t\treturn nil\n\t\t}\n\t\t// byte slice\n\t\tif d.isCodeBin(code) {\n\t\t\tbs, err := d.asBinWithCode(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trv.SetBytes(bs)\n\t\t\treturn nil\n\t\t}\n\t\t// string to bytes\n\t\tif d.isCodeString(code) {\n\t\t\tl, err := d.stringByteLength(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tbs, err := d.asStringByteByLength(l, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\trv.SetBytes(bs)\n\t\t\treturn nil\n\t\t}\n\n\t\t// get slice length\n\t\tl, err := d.sliceLength(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// check fixed type\n\t\tfound, err := d.asFixedSlice(rv, l)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif found {\n\t\t\treturn nil\n\t\t}\n\n\t\t// create slice dynamically\n\t\ttmpSlice := reflect.MakeSlice(rv.Type(), l, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tv := tmpSlice.Index(i)\n\t\t\tif v.Kind() == reflect.Struct {\n\t\t\t\tstructCode, err := d.readSize1()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err = d.setStruct(structCode, v, k); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif err = d.decode(v); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\trv.Set(tmpSlice)\n\n\tcase reflect.Complex64:\n\t\tv, err := d.asComplex64(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetComplex(complex128(v))\n\n\tcase reflect.Complex128:\n\t\tv, err := d.asComplex128(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\trv.SetComplex(v)\n\n\tcase reflect.Array:\n\t\t// nil\n\t\tif d.isCodeNil(code) {\n\t\t\treturn nil\n\t\t}\n\t\t// byte slice\n\t\tif d.isCodeBin(code) {\n\t\t\tbs, err := d.asBinWithCode(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif len(bs) > rv.Len() {\n\t\t\t\treturn fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), len(bs), def.ErrNotMatchArrayElement)\n\t\t\t}\n\t\t\tfor i, b := range bs {\n\t\t\t\trv.Index(i).SetUint(uint64(b))\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\t// string to bytes\n\t\tif d.isCodeString(code) {\n\t\t\tl, err := d.stringByteLength(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif l > rv.Len() {\n\t\t\t\treturn fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), l, def.ErrNotMatchArrayElement)\n\t\t\t}\n\t\t\tbs, err := d.asStringByteByLength(l, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tfor i, b := range bs {\n\t\t\t\trv.Index(i).SetUint(uint64(b))\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\t// get slice length\n\t\tl, err := d.sliceLength(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif l > rv.Len() {\n\t\t\treturn fmt.Errorf(\"%v len is %d, but msgpack has %d elements, %w\", rv.Type(), rv.Len(), l, def.ErrNotMatchArrayElement)\n\t\t}\n\n\t\t// create array dynamically\n\t\tfor i := 0; i < l; i++ {\n\t\t\terr = d.decode(rv.Index(i))\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase reflect.Map:\n\t\t// nil\n\t\tif d.isCodeNil(code) {\n\t\t\treturn nil\n\t\t}\n\n\t\t// get map length\n\t\tl, err := d.mapLength(code, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// check fixed type\n\t\tfound, err := d.asFixedMap(rv, l)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif found {\n\t\t\treturn nil\n\t\t}\n\n\t\t// create dynamically\n\t\tkey := rv.Type().Key()\n\t\tvalue := rv.Type().Elem()\n\t\tif rv.IsNil() {\n\t\t\trv.Set(reflect.MakeMapWithSize(rv.Type(), l))\n\t\t}\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk := reflect.New(key).Elem()\n\t\t\tv := reflect.New(value).Elem()\n\t\t\terr = d.decode(k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\terr = d.decode(v)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\trv.SetMapIndex(k, v)\n\t\t}\n\n\tcase reflect.Struct:\n\t\terr := d.setStruct(code, rv, k)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase reflect.Ptr:\n\t\t// nil\n\t\tif d.isCodeNil(code) {\n\t\t\treturn nil\n\t\t}\n\n\t\tif rv.Elem().Kind() == reflect.Invalid {\n\t\t\tn := reflect.New(rv.Type().Elem())\n\t\t\trv.Set(n)\n\t\t}\n\n\t\terr := d.decodeWithCode(code, rv.Elem())\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\tcase reflect.Interface:\n\t\tif rv.Elem().Kind() == reflect.Ptr {\n\t\t\terr := d.decode(rv.Elem())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tv, err := d.asInterfaceWithCode(code, k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif v != nil {\n\t\t\t\trv.Set(reflect.ValueOf(v))\n\t\t\t}\n\t\t}\n\n\tdefault:\n\t\treturn fmt.Errorf(\"%v is %w type\", rv.Kind(), def.ErrUnsupportedType)\n\t}\n\treturn nil\n}\n\nfunc (d *decoder) errorTemplate(code byte, k reflect.Kind) error {\n\treturn fmt.Errorf(\"%w %x decoding as %v\", def.ErrCanNotDecode, code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/decoding_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\ntype AsXXXTestCase[T any] struct {\n\tName             string\n\tCode             byte\n\tData             []byte\n\tReadCount        int\n\tExpected         T\n\tError            error\n\tMethodAs         func(d *decoder) func(reflect.Kind) (T, error)\n\tMethodAsWithCode func(d *decoder) func(byte, reflect.Kind) (T, error)\n\tMethodAsCustom   func(d *decoder) (T, error)\n}\n\ntype AsXXXTestCases[T any] []AsXXXTestCase[T]\n\nfunc (tcs AsXXXTestCases[T]) Run(t *testing.T) {\n\tfor _, tc := range tcs {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc (tc *AsXXXTestCase[T]) Run(t *testing.T) {\n\tconst kind = reflect.String\n\tt.Helper()\n\n\tif tc.MethodAs == nil && tc.MethodAsWithCode == nil && tc.MethodAsCustom == nil {\n\t\tt.Fatal(\"must set either method or methodAsWithCode or MethodAsCustom\")\n\t}\n\n\tmethodAs := func(d *decoder) (T, error) {\n\t\tif tc.MethodAs != nil {\n\t\t\treturn tc.MethodAs(d)(kind)\n\t\t}\n\t\tif tc.MethodAsWithCode != nil {\n\t\t\treturn tc.MethodAsWithCode(d)(tc.Code, kind)\n\t\t}\n\t\tif tc.MethodAsCustom != nil {\n\t\t\treturn tc.MethodAsCustom(d)\n\t\t}\n\t\tpanic(\"unreachable\")\n\t}\n\n\tt.Run(tc.Name, func(t *testing.T) {\n\t\tr := tu.NewTestReader(tc.Data)\n\t\td := decoder{\n\t\t\tr:   r,\n\t\t\tbuf: common.GetBuffer(),\n\t\t}\n\t\tdefer common.PutBuffer(d.buf)\n\n\t\tv, err := methodAs(&d)\n\t\ttu.Equal(t, r.Count(), tc.ReadCount)\n\n\t\tif tc.Error != nil {\n\t\t\ttu.IsError(t, err, tc.Error)\n\t\t\treturn\n\t\t}\n\t\ttu.NoError(t, err)\n\t\ttu.Equal(t, v, tc.Expected)\n\n\t\tp := make([]byte, 1)\n\t\tn, err := d.r.Read(p)\n\t\ttu.IsError(t, err, io.EOF)\n\t\ttu.Equal(t, n, 0)\n\t})\n}\n\nfunc TestDecoding(t *testing.T) {\n\tt.Run(\"nil reader\", func(t *testing.T) {\n\t\tv := new(int)\n\t\terr := Decode(nil, v, false)\n\t\ttu.IsError(t, err, def.ErrNoData)\n\t})\n\tt.Run(\"not pointer\", func(t *testing.T) {\n\t\tv := 0\n\t\tr := tu.NewTestReader([]byte{def.PositiveFixIntMax})\n\t\terr := Decode(r, v, false)\n\t\ttu.IsError(t, err, def.ErrReceiverNotPointer)\n\t})\n}\n\nfunc Test_decodeWithCode(t *testing.T) {\n\tvar target any\n\tmethod := func(d *decoder) func(code byte, _ reflect.Kind) (bool, error) {\n\t\treturn func(code byte, _ reflect.Kind) (bool, error) {\n\t\t\trv := reflect.ValueOf(target)\n\t\t\treturn true, d.decodeWithCode(code, rv.Elem())\n\t\t}\n\t}\n\n\tt.Run(\"Int\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{5},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 5)\n\t})\n\tt.Run(\"Uint\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Uint8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Uint8,\n\t\t\t\tData:             []byte{5},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(uint)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 5)\n\t})\n\tt.Run(\"Float32\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Float32,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Float32,\n\t\t\t\tData:             []byte{63, 128, 0, 0},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(float32)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 1)\n\t})\n\tt.Run(\"Float64\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Float64,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Float64,\n\t\t\t\tData:             []byte{63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(float64)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 1)\n\t})\n\tt.Run(\"BinString\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{1, 'a'},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(string)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, \"a\")\n\t})\n\tt.Run(\"String\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         false,\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{1, 'b'},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(string)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, \"b\")\n\t})\n\tt.Run(\"Bool\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            def.ErrCanNotDecode,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.True,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        0,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(bool)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, true)\n\t})\n\tt.Run(\"Slice.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Nil,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        0,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, nil)\n\t})\n\tt.Run(\"Slice.bin\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{1, 2},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []byte{2})\n\t})\n\tt.Run(\"Slice.string\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.bytelen\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{1, 'c'},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []byte{'c'})\n\t})\n\tt.Run(\"Slice.fixed\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.slice\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []int{3})\n\t})\n\tt.Run(\"Slice.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.slice\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.struct\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tReadCount:        4,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        5,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new([]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []st{{V: 3}})\n\t})\n\tt.Run(\"Slice.map\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.slice\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.map\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tReadCount:        4,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        5,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([]map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, []map[string]int{{\"v\": 3}})\n\t})\n\tt.Run(\"Complex64\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Fixext8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Fixext8,\n\t\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        3,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(complex64)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, complex(1, 1))\n\t})\n\tt.Run(\"Complex128\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Fixext8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Fixext8,\n\t\t\t\tData:             []byte{byte(def.ComplexTypeCode()), 63, 128, 0, 0, 63, 128, 0, 0},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        3,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(complex128)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, complex(1, 1))\n\t})\n\n\tt.Run(\"Array.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Nil,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        0,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]int{})\n\t})\n\tt.Run(\"Array.bin\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.bin\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.len\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{2, 1, 2},\n\t\t\t\tReadCount:        2,\n\t\t\t\tError:            def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Bin8,\n\t\t\t\tData:             []byte{1, 2},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]byte{2})\n\t})\n\tt.Run(\"Array.string\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.compare\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{2},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.bytelen\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Str8,\n\t\t\t\tData:             []byte{1, 'c'},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new([1]byte)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]byte{'c'})\n\t})\n\tt.Run(\"Array.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 2},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            def.ErrNotMatchArrayElement,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.slice\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.struct\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tReadCount:        4,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        5,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new([1]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, [1]st{{V: 3}})\n\t})\n\tt.Run(\"Map.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Nil,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        0,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, nil)\n\t})\n\tt.Run(\"Map.fixed\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.map\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'a', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        4,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(map[string]int)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, map[string]int{\"a\": 3})\n\t})\n\tt.Run(\"Map.struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error.strlen\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.key\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.value\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'a', def.FixMap + 1, def.FixStr + 1, 'v'},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        6,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'a', def.FixMap + 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        7,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new(map[string]st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, map[string]st{\"a\": {V: 3}})\n\t})\n\tt.Run(\"Struct\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        4,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV int `msgpack:\"v\"`\n\t\t}\n\t\tv := new(st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, st{V: 3})\n\t})\n\tt.Run(\"Ptr.nil\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Nil,\n\t\t\t\tData:             []byte{},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        0,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 0)\n\t})\n\tt.Run(\"Ptr\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := new(int)\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\ttu.Equal(t, *v, 3)\n\t})\n\tt.Run(\"Interface.ptr\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Int8,\n\t\t\t\tData:             []byte{3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        1,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tv := (any)(new(int))\n\t\ttarget = &v\n\t\ttestcases.Run(t)\n\t\tvv := v.(*int)\n\t\ttu.Equal(t, *vv, 3)\n\t})\n\tt.Run(\"Interface\", func(t *testing.T) {\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:             \"error\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'v', def.Int8},\n\t\t\t\tReadCount:        4,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'v', def.Int8, 3},\n\t\t\t\tExpected:         true,\n\t\t\t\tReadCount:        5,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\ttype st struct {\n\t\t\tV any `msgpack:\"v\"`\n\t\t}\n\t\tv := new(st)\n\t\ttarget = v\n\t\ttestcases.Run(t)\n\t\tvar vv any = int8(3)\n\t\ttu.Equal(t, v.V, vv)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/decoding/ext.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nvar (\n\textCoderMap = map[int8]ext.StreamDecoder{time.StreamDecoder.Code(): time.StreamDecoder}\n\textCoders   = []ext.StreamDecoder{time.StreamDecoder}\n)\n\n// AddExtDecoder adds decoders for extension types.\nfunc AddExtDecoder(f ext.StreamDecoder) {\n\t// ignore time\n\tif f.Code() == time.Decoder.Code() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Code()]\n\tif !ok {\n\t\textCoderMap[f.Code()] = f\n\t\tupdateExtCoders()\n\t}\n}\n\n// RemoveExtDecoder removes decoders for extension types.\nfunc RemoveExtDecoder(f ext.StreamDecoder) {\n\t// ignore time\n\tif f.Code() == time.Decoder.Code() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Code()]\n\tif ok {\n\t\tdelete(extCoderMap, f.Code())\n\t\tupdateExtCoders()\n\t}\n}\n\nfunc updateExtCoders() {\n\textCoders = make([]ext.StreamDecoder, len(extCoderMap))\n\ti := 0\n\tfor k := range extCoderMap {\n\t\textCoders[i] = extCoderMap[k]\n\t\ti++\n\t}\n}\n\nfunc (d *decoder) readIfExtType(code byte) (innerType int8, data []byte, err error) {\n\tswitch code {\n\tcase def.Fixext1:\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tv, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), []byte{v}, nil\n\n\tcase def.Fixext2:\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Fixext4:\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Fixext8:\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Fixext16:\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSize16()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Ext8:\n\t\tbs, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tsize := int(bs)\n\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSizeN(size)\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Ext16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tsize := int(binary.BigEndian.Uint16(bs))\n\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSizeN(size)\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\n\tcase def.Ext32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tsize := int(binary.BigEndian.Uint32(bs))\n\n\t\ttyp, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\tdata, err = d.readSizeN(size)\n\t\tif err != nil {\n\t\t\treturn 0, nil, err\n\t\t}\n\t\treturn int8(typ), data, nil\n\t}\n\n\treturn 0, nil, nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/ext_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nfunc Test_AddExtDecoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tAddExtDecoder(time.StreamDecoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\nfunc Test_RemoveExtDecoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tRemoveExtDecoder(time.StreamDecoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\nfunc Test_readIfExtType(t *testing.T) {\n\ttestcases := []struct {\n\t\tname  string\n\t\tcode  byte\n\t\tr     []byte\n\t\ttyp   int8\n\t\tdata  []byte\n\t\terr   error\n\t\tcount int\n\t}{\n\t\t{\n\t\t\tname:  \"Fixext1.error.type\",\n\t\t\tcode:  def.Fixext1,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext1.error.data\",\n\t\t\tcode:  def.Fixext1,\n\t\t\tr:     []byte{1},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext1.ok\",\n\t\t\tcode:  def.Fixext1,\n\t\t\tr:     []byte{1, 2},\n\t\t\ttyp:   1,\n\t\t\tdata:  []byte{2},\n\t\t\tcount: 2,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Fixext2.error.type\",\n\t\t\tcode:  def.Fixext2,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext2.error.data\",\n\t\t\tcode:  def.Fixext2,\n\t\t\tr:     []byte{2},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext2.ok\",\n\t\t\tcode:  def.Fixext2,\n\t\t\tr:     []byte{2, 3, 4},\n\t\t\ttyp:   2,\n\t\t\tdata:  []byte{3, 4},\n\t\t\tcount: 2,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Fixext4.error.type\",\n\t\t\tcode:  def.Fixext4,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext4.error.data\",\n\t\t\tcode:  def.Fixext4,\n\t\t\tr:     []byte{4},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext4.ok\",\n\t\t\tcode:  def.Fixext4,\n\t\t\tr:     []byte{4, 5, 6, 7, 8},\n\t\t\ttyp:   4,\n\t\t\tdata:  []byte{5, 6, 7, 8},\n\t\t\tcount: 2,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Fixext8.error.type\",\n\t\t\tcode:  def.Fixext8,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext8.error.data\",\n\t\t\tcode:  def.Fixext8,\n\t\t\tr:     []byte{8},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext8.ok\",\n\t\t\tcode:  def.Fixext8,\n\t\t\tr:     []byte{8, 1, 2, 3, 4, 5, 6, 7, 8},\n\t\t\ttyp:   8,\n\t\t\tdata:  []byte{1, 2, 3, 4, 5, 6, 7, 8},\n\t\t\tcount: 2,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Fixext16.error.type\",\n\t\t\tcode:  def.Fixext16,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext16.error.data\",\n\t\t\tcode:  def.Fixext16,\n\t\t\tr:     []byte{16},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Fixext16.ok\",\n\t\t\tcode:  def.Fixext16,\n\t\t\tr:     []byte{16, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},\n\t\t\ttyp:   16,\n\t\t\tdata:  []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16},\n\t\t\tcount: 2,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Ext8.error.size\",\n\t\t\tcode:  def.Ext8,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext8.error.type\",\n\t\t\tcode:  def.Ext8,\n\t\t\tr:     []byte{1},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext8.error.data\",\n\t\t\tcode:  def.Ext8,\n\t\t\tr:     []byte{1, 18},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 2,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext8.ok\",\n\t\t\tcode:  def.Ext8,\n\t\t\tr:     []byte{1, 18, 2},\n\t\t\ttyp:   18,\n\t\t\tdata:  []byte{2},\n\t\t\tcount: 3,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Ext16.error.size\",\n\t\t\tcode:  def.Ext16,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext16.error.type\",\n\t\t\tcode:  def.Ext16,\n\t\t\tr:     []byte{0, 1},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext16.error.data\",\n\t\t\tcode:  def.Ext16,\n\t\t\tr:     []byte{0, 1, 24},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 2,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext16.ok\",\n\t\t\tcode:  def.Ext16,\n\t\t\tr:     []byte{0, 1, 24, 3},\n\t\t\ttyp:   24,\n\t\t\tdata:  []byte{3},\n\t\t\tcount: 3,\n\t\t},\n\n\t\t{\n\t\t\tname:  \"Ext32.error.size\",\n\t\t\tcode:  def.Ext32,\n\t\t\tr:     []byte{},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 0,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext32.error.type\",\n\t\t\tcode:  def.Ext32,\n\t\t\tr:     []byte{0, 0, 0, 1},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 1,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext32.error.data\",\n\t\t\tcode:  def.Ext32,\n\t\t\tr:     []byte{0, 0, 0, 1, 32},\n\t\t\terr:   io.EOF,\n\t\t\tcount: 2,\n\t\t},\n\t\t{\n\t\t\tname:  \"Ext32.ok\",\n\t\t\tcode:  def.Ext32,\n\t\t\tr:     []byte{0, 0, 0, 1, 32, 4},\n\t\t\ttyp:   32,\n\t\t\tdata:  []byte{4},\n\t\t\tcount: 3,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tr := tu.NewTestReader(tc.r)\n\t\t\td := decoder{\n\t\t\t\tr:   r,\n\t\t\t\tbuf: common.GetBuffer(),\n\t\t\t}\n\t\t\tdefer common.PutBuffer(d.buf)\n\t\t\ttyp, data, err := d.readIfExtType(tc.code)\n\t\t\ttu.IsError(t, err, tc.err)\n\t\t\ttu.Equal(t, tc.typ, typ)\n\t\t\ttu.EqualSlice(t, data, tc.data)\n\t\t\ttu.Equal(t, r.Count(), tc.count)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/float.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asFloat32(k reflect.Kind) (float32, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn d.asFloat32WithCode(code, k)\n}\n\nfunc (d *decoder) asFloat32WithCode(code byte, k reflect.Kind) (float32, error) {\n\tswitch {\n\tcase code == def.Float32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := math.Float32frombits(binary.BigEndian.Uint32(bs))\n\t\treturn v, nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn float32(v), nil\n\n\tcase d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn float32(v), nil\n\n\tcase code == def.Nil:\n\t\treturn 0, nil\n\t}\n\treturn 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asFloat64(k reflect.Kind) (float64, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn d.asFloat64WithCode(code, k)\n}\n\nfunc (d *decoder) asFloat64WithCode(code byte, k reflect.Kind) (float64, error) {\n\tswitch {\n\tcase code == def.Float64:\n\t\tbs, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := math.Float64frombits(binary.BigEndian.Uint64(bs))\n\t\treturn v, nil\n\n\tcase code == def.Float32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := math.Float32frombits(binary.BigEndian.Uint32(bs))\n\t\treturn float64(v), nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8, code == def.Uint16, code == def.Uint32, code == def.Uint64:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn float64(v), nil\n\n\tcase d.isNegativeFixNum(code), code == def.Int8, code == def.Int16, code == def.Int32, code == def.Int64:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn float64(v), nil\n\n\tcase code == def.Nil:\n\t\treturn 0, nil\n\t}\n\treturn 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/float_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asFloat32(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (float32, error) {\n\t\treturn d.asFloat32\n\t}\n\ttestcases := AsXXXTestCases[float32]{\n\t\t{\n\t\t\tName:     \"error\",\n\t\t\tError:    io.EOF,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.Float32, 63, 128, 0, 0},\n\t\t\tExpected:  float32(1),\n\t\t\tReadCount: 2,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asFloat32WithCode(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (float32, error) {\n\t\treturn d.asFloat32WithCode\n\t}\n\ttestcases := AsXXXTestCases[float32]{\n\t\t{\n\t\t\tName:             \"Float32.error\",\n\t\t\tCode:             def.Float32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.ok\",\n\t\t\tCode:             def.Float32,\n\t\t\tData:             []byte{63, 128, 0, 0},\n\t\t\tExpected:         float32(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint8.error\",\n\t\t\tCode:             def.Uint8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint8.ok\",\n\t\t\tCode:             def.Uint8,\n\t\t\tData:             []byte{1},\n\t\t\tExpected:         float32(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.error\",\n\t\t\tCode:             def.Int8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.ok\",\n\t\t\tCode:             def.Int8,\n\t\t\tData:             []byte{0xff},\n\t\t\tExpected:         float32(-1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Nil.ok\",\n\t\t\tCode:             def.Nil,\n\t\t\tExpected:         float32(0),\n\t\t\tReadCount:        0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Str8,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asFloat64(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (float64, error) {\n\t\treturn d.asFloat64\n\t}\n\ttestcases := AsXXXTestCases[float64]{\n\t\t{\n\t\t\tName:     \"error\",\n\t\t\tError:    io.EOF,\n\t\t\tMethodAs: method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\tExpected:  float64(1),\n\t\t\tReadCount: 2,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asFloat64WithCode(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (float64, error) {\n\t\treturn d.asFloat64WithCode\n\t}\n\ttestcases := AsXXXTestCases[float64]{\n\t\t{\n\t\t\tName:             \"Float64.error\",\n\t\t\tCode:             def.Float64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float64.ok\",\n\t\t\tCode:             def.Float64,\n\t\t\tData:             []byte{63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\tExpected:         float64(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.error\",\n\t\t\tCode:             def.Float32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.ok\",\n\t\t\tCode:             def.Float32,\n\t\t\tData:             []byte{63, 128, 0, 0},\n\t\t\tExpected:         float64(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint8.error\",\n\t\t\tCode:             def.Uint8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint8.ok\",\n\t\t\tCode:             def.Uint8,\n\t\t\tData:             []byte{1},\n\t\t\tExpected:         float64(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.error\",\n\t\t\tCode:             def.Int8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.ok\",\n\t\t\tCode:             def.Int8,\n\t\t\tData:             []byte{0xff},\n\t\t\tExpected:         float64(-1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Nil.ok\",\n\t\t\tCode:             def.Nil,\n\t\t\tExpected:         float64(0),\n\t\t\tReadCount:        0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Str8,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/int.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) isPositiveFixNum(v byte) bool {\n\treturn def.PositiveFixIntMin <= v && v <= def.PositiveFixIntMax\n}\n\nfunc (d *decoder) isNegativeFixNum(v byte) bool {\n\treturn def.NegativeFixintMin <= int8(v) && int8(v) <= def.NegativeFixintMax\n}\n\nfunc (d *decoder) asInt(k reflect.Kind) (int64, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn d.asIntWithCode(code, k)\n}\n\nfunc (d *decoder) asIntWithCode(code byte, k reflect.Kind) (int64, error) {\n\tswitch {\n\tcase d.isPositiveFixNum(code):\n\t\treturn int64(code), nil\n\n\tcase d.isNegativeFixNum(code):\n\t\treturn int64(int8(code)), nil\n\n\tcase code == def.Uint8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(b), nil\n\n\tcase code == def.Int8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(int8(b)), nil\n\n\tcase code == def.Uint16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint16(bs)\n\t\treturn int64(v), nil\n\n\tcase code == def.Int16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := int16(binary.BigEndian.Uint16(bs))\n\t\treturn int64(v), nil\n\n\tcase code == def.Uint32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint32(bs)\n\t\treturn int64(v), nil\n\n\tcase code == def.Int32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := int32(binary.BigEndian.Uint32(bs))\n\t\treturn int64(v), nil\n\n\tcase code == def.Uint64:\n\t\tbs, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(binary.BigEndian.Uint64(bs)), nil\n\n\tcase code == def.Int64:\n\t\tbs, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(binary.BigEndian.Uint64(bs)), nil\n\n\tcase code == def.Float32:\n\t\tv, err := d.asFloat32WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(v), nil\n\n\tcase code == def.Float64:\n\t\tv, err := d.asFloat64WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int64(v), nil\n\n\tcase code == def.Nil:\n\t\treturn 0, nil\n\t}\n\n\treturn 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/int_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asInt(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (int64, error) {\n\t\treturn d.asInt\n\t}\n\ttestcases := AsXXXTestCases[int64]{\n\t\t{\n\t\t\tName:      \"error\",\n\t\t\tData:      []byte{},\n\t\t\tError:     io.EOF,\n\t\t\tReadCount: 0,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.Int8, 1},\n\t\t\tExpected:  1,\n\t\t\tReadCount: 2,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asIntWithCode(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (int64, error) {\n\t\treturn d.asIntWithCode\n\t}\n\ttestcases := AsXXXTestCases[int64]{\n\t\t{\n\t\t\tName:             \"Uint8.error\",\n\t\t\tCode:             def.Uint8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint8.ok\",\n\t\t\tCode:             def.Uint8,\n\t\t\tData:             []byte{1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.error\",\n\t\t\tCode:             def.Int8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.ok\",\n\t\t\tCode:             def.Int8,\n\t\t\tData:             []byte{1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint16.error\",\n\t\t\tCode:             def.Uint16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint16.ok\",\n\t\t\tCode:             def.Uint16,\n\t\t\tData:             []byte{0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int16.error\",\n\t\t\tCode:             def.Int16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int16.ok\",\n\t\t\tCode:             def.Int16,\n\t\t\tData:             []byte{0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint32.error\",\n\t\t\tCode:             def.Uint32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint32.ok\",\n\t\t\tCode:             def.Uint32,\n\t\t\tData:             []byte{0, 0, 0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int32.error\",\n\t\t\tCode:             def.Int32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int32.ok\",\n\t\t\tCode:             def.Int32,\n\t\t\tData:             []byte{0, 0, 0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint64.error\",\n\t\t\tCode:             def.Uint64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint64.ok\",\n\t\t\tCode:             def.Uint64,\n\t\t\tData:             []byte{0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int64.error\",\n\t\t\tCode:             def.Int64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int64.ok\",\n\t\t\tCode:             def.Int64,\n\t\t\tData:             []byte{0, 0, 0, 0, 0, 0, 0, 1},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.error\",\n\t\t\tCode:             def.Float32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.ok\",\n\t\t\tCode:             def.Float32,\n\t\t\tData:             []byte{63, 128, 0, 0},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float64.error\",\n\t\t\tCode:             def.Float64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float64.ok\",\n\t\t\tCode:             def.Float64,\n\t\t\tData:             []byte{63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\tExpected:         1,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Nil\",\n\t\t\tCode:             def.Nil,\n\t\t\tExpected:         0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Array16,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/interface.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asInterface(k reflect.Kind) (interface{}, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn d.asInterfaceWithCode(code, k)\n}\n\nfunc (d *decoder) asInterfaceWithCode(code byte, k reflect.Kind) (interface{}, error) {\n\tswitch {\n\tcase code == def.Nil:\n\t\treturn nil, nil\n\n\tcase code == def.True, code == def.False:\n\t\tv, err := d.asBoolWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, nil\n\n\tcase d.isPositiveFixNum(code), code == def.Uint8:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn uint8(v), err\n\tcase code == def.Uint16:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn uint16(v), err\n\tcase code == def.Uint32:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn uint32(v), err\n\tcase code == def.Uint64:\n\t\tv, err := d.asUintWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\n\tcase d.isNegativeFixNum(code), code == def.Int8:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn int8(v), err\n\tcase code == def.Int16:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn int16(v), err\n\tcase code == def.Int32:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn int32(v), err\n\tcase code == def.Int64:\n\t\tv, err := d.asIntWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\n\tcase code == def.Float32:\n\t\tv, err := d.asFloat32WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\tcase code == def.Float64:\n\t\tv, err := d.asFloat64WithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\n\tcase d.isFixString(code), code == def.Str8, code == def.Str16, code == def.Str32:\n\t\tv, err := d.asStringWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\n\tcase code == def.Bin8, code == def.Bin16, code == def.Bin32:\n\t\tv, err := d.asBinWithCode(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn v, err\n\n\tcase d.isFixSlice(code), code == def.Array16, code == def.Array32:\n\t\tl, err := d.sliceLength(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tv := make([]interface{}, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tvv, err := d.asInterface(k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tv[i] = vv\n\t\t}\n\t\treturn v, nil\n\n\tcase d.isFixMap(code), code == def.Map16, code == def.Map32:\n\t\tl, err := d.mapLength(code, k)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tv := make(map[interface{}]interface{}, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tkeyCode, err := d.readSize1()\n\t\t\tif err != nil {\n\t\t\t\treturn 0, err\n\t\t\t}\n\n\t\t\tif err := d.canSetAsMapKey(keyCode); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tkey, err := d.asInterfaceWithCode(keyCode, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tvalue, err := d.asInterface(k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tv[key] = value\n\t\t}\n\t\treturn v, nil\n\t}\n\n\t// ext\n\textInnerType, extData, err := d.readIfExtType(code)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor i := range extCoders {\n\t\tif extCoders[i].IsType(code, extInnerType, len(extData)) {\n\t\t\tv, err := extCoders[i].ToValue(code, extData, k)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn v, nil\n\t\t}\n\t}\n\treturn nil, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) canSetAsMapKey(code byte) error {\n\tswitch {\n\tcase d.isFixSlice(code), code == def.Array16, code == def.Array32:\n\t\treturn fmt.Errorf(\"%w. code: %x\", def.ErrCanNotSetSliceAsMapKey, code)\n\tcase d.isFixMap(code), code == def.Map16, code == def.Map32:\n\t\treturn fmt.Errorf(\"%w. code: %x\", def.ErrCanNotSetMapAsMapKey, code)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/interface_test.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nfunc Test_asInterface(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (any, error) {\n\t\treturn d.asInterface\n\t}\n\ttestcases := AsXXXTestCases[any]{\n\t\t{\n\t\t\tName:      \"error\",\n\t\t\tData:      []byte{},\n\t\t\tError:     io.EOF,\n\t\t\tReadCount: 0,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.Nil},\n\t\t\tExpected:  nil,\n\t\t\tReadCount: 1,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asInterfaceWithCode(t *testing.T) {\n\tdec := testExt2StreamDecoder{}\n\tAddExtDecoder(&dec)\n\tdefer RemoveExtDecoder(&dec)\n\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (any, error) {\n\t\treturn d.asInterfaceWithCode\n\t}\n\ttestcases := AsXXXTestCases[any]{\n\t\t{\n\t\t\tName:             \"Uint8.error\",\n\t\t\tCode:             def.Uint8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint16.error\",\n\t\t\tCode:             def.Uint16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint32.error\",\n\t\t\tCode:             def.Uint32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Uint64.error\",\n\t\t\tCode:             def.Uint64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int8.error\",\n\t\t\tCode:             def.Int8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int16.error\",\n\t\t\tCode:             def.Int16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int32.error\",\n\t\t\tCode:             def.Int32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Int64.error\",\n\t\t\tCode:             def.Int64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.error\",\n\t\t\tCode:             def.Float32,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float32.ok\",\n\t\t\tCode:             def.Float32,\n\t\t\tData:             []byte{63, 128, 0, 0},\n\t\t\tExpected:         float32(1),\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Float64.error\",\n\t\t\tCode:             def.Float64,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str.error\",\n\t\t\tCode:             def.Str8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Bin.error\",\n\t\t\tCode:             def.Bin8,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array.error.length\",\n\t\t\tCode:             def.Array16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array.error.set\",\n\t\t\tCode:             def.Array16,\n\t\t\tData:             []byte{0, 1},\n\t\t\tReadCount:        1,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.length\",\n\t\t\tCode:             def.Map16,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.set.key_code\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0, 1},\n\t\t\tReadCount:        1,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.set.can.slice\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0, 1, def.Array16},\n\t\t\tReadCount:        2,\n\t\t\tError:            def.ErrCanNotSetSliceAsMapKey,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.set.can.map\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0, 1, def.Map16},\n\t\t\tReadCount:        2,\n\t\t\tError:            def.ErrCanNotSetMapAsMapKey,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.set.key\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0, 1, def.FixStr + 1},\n\t\t\tReadCount:        2,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map.error.set.value\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'a'},\n\t\t\tReadCount:        3,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Ext.error\",\n\t\t\tCode:             def.Fixext1,\n\t\t\tData:             []byte{},\n\t\t\tReadCount:        0,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"ExtCoder.error\",\n\t\t\tCode:             def.Fixext1,\n\t\t\tData:             []byte{3, 0},\n\t\t\tReadCount:        2,\n\t\t\tError:            ErrTestExtStreamDecoder,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Fixext1,\n\t\t\tData:             []byte{4, 0},\n\t\t\tReadCount:        2,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\n// TODO: to testutil\ntype testExt2StreamDecoder struct{}\n\nvar _ ext.StreamDecoder = (*testExt2StreamDecoder)(nil)\n\nfunc (td *testExt2StreamDecoder) Code() int8 {\n\treturn 3\n}\n\nfunc (td *testExt2StreamDecoder) IsType(_ byte, code int8, _ int) bool {\n\treturn code == td.Code()\n}\n\nvar ErrTestExtStreamDecoder = fmt.Errorf(\"testExtStreamDecoder\")\n\nfunc (td *testExt2StreamDecoder) ToValue(_ byte, _ []byte, k reflect.Kind) (any, error) {\n\treturn nil, ErrTestExtStreamDecoder\n}\n"
  },
  {
    "path": "internal/stream/decoding/map.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\ttypeMapStringInt   = reflect.TypeOf(map[string]int{})\n\ttypeMapStringInt8  = reflect.TypeOf(map[string]int8{})\n\ttypeMapStringInt16 = reflect.TypeOf(map[string]int16{})\n\ttypeMapStringInt32 = reflect.TypeOf(map[string]int32{})\n\ttypeMapStringInt64 = reflect.TypeOf(map[string]int64{})\n\n\ttypeMapStringUint   = reflect.TypeOf(map[string]uint{})\n\ttypeMapStringUint8  = reflect.TypeOf(map[string]uint8{})\n\ttypeMapStringUint16 = reflect.TypeOf(map[string]uint16{})\n\ttypeMapStringUint32 = reflect.TypeOf(map[string]uint32{})\n\ttypeMapStringUint64 = reflect.TypeOf(map[string]uint64{})\n\n\ttypeMapStringFloat32 = reflect.TypeOf(map[string]float32{})\n\ttypeMapStringFloat64 = reflect.TypeOf(map[string]float64{})\n\n\ttypeMapStringBool   = reflect.TypeOf(map[string]bool{})\n\ttypeMapStringString = reflect.TypeOf(map[string]string{})\n\n\ttypeMapIntString   = reflect.TypeOf(map[int]string{})\n\ttypeMapInt8String  = reflect.TypeOf(map[int8]string{})\n\ttypeMapInt16String = reflect.TypeOf(map[int16]string{})\n\ttypeMapInt32String = reflect.TypeOf(map[int32]string{})\n\ttypeMapInt64String = reflect.TypeOf(map[int64]string{})\n\ttypeMapIntBool     = reflect.TypeOf(map[int]bool{})\n\ttypeMapInt8Bool    = reflect.TypeOf(map[int8]bool{})\n\ttypeMapInt16Bool   = reflect.TypeOf(map[int16]bool{})\n\ttypeMapInt32Bool   = reflect.TypeOf(map[int32]bool{})\n\ttypeMapInt64Bool   = reflect.TypeOf(map[int64]bool{})\n\n\ttypeMapUintString   = reflect.TypeOf(map[uint]string{})\n\ttypeMapUint8String  = reflect.TypeOf(map[uint8]string{})\n\ttypeMapUint16String = reflect.TypeOf(map[uint16]string{})\n\ttypeMapUint32String = reflect.TypeOf(map[uint32]string{})\n\ttypeMapUint64String = reflect.TypeOf(map[uint64]string{})\n\ttypeMapUintBool     = reflect.TypeOf(map[uint]bool{})\n\ttypeMapUint8Bool    = reflect.TypeOf(map[uint8]bool{})\n\ttypeMapUint16Bool   = reflect.TypeOf(map[uint16]bool{})\n\ttypeMapUint32Bool   = reflect.TypeOf(map[uint32]bool{})\n\ttypeMapUint64Bool   = reflect.TypeOf(map[uint64]bool{})\n\n\ttypeMapFloat32String = reflect.TypeOf(map[float32]string{})\n\ttypeMapFloat64String = reflect.TypeOf(map[float64]string{})\n\ttypeMapFloat32Bool   = reflect.TypeOf(map[float32]bool{})\n\ttypeMapFloat64Bool   = reflect.TypeOf(map[float64]bool{})\n)\n\nfunc (d *decoder) isFixMap(v byte) bool {\n\treturn def.FixMap <= v && v <= def.FixMap+0x0f\n}\n\nfunc (d *decoder) mapLength(code byte, k reflect.Kind) (int, error) {\n\tswitch {\n\tcase d.isFixMap(code):\n\t\treturn int(code - def.FixMap), nil\n\tcase code == def.Map16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(bs)), nil\n\tcase code == def.Map32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(bs)), nil\n\t}\n\n\treturn 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asFixedMap(rv reflect.Value, l int) (bool, error) {\n\tt := rv.Type()\n\n\tkeyKind := t.Key().Kind()\n\tvalueKind := t.Elem().Kind()\n\n\tswitch t {\n\tcase typeMapStringInt:\n\t\tm := make(map[string]int, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asInt(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = int(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringUint:\n\t\tm := make(map[string]uint, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asUint(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = uint(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringFloat32:\n\t\tm := make(map[string]float32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asFloat32(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringFloat64:\n\t\tm := make(map[string]float64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asFloat64(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringBool:\n\t\tm := make(map[string]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringString:\n\t\tm := make(map[string]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringInt8:\n\t\tm := make(map[string]int8, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asInt(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = int8(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringInt16:\n\t\tm := make(map[string]int16, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asInt(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = int16(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringInt32:\n\t\tm := make(map[string]int32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asInt(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = int32(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringInt64:\n\t\tm := make(map[string]int64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asInt(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringUint8:\n\t\tm := make(map[string]uint8, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asUint(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = uint8(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\tcase typeMapStringUint16:\n\t\tm := make(map[string]uint16, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asUint(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = uint16(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringUint32:\n\t\tm := make(map[string]uint32, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asUint(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = uint32(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapStringUint64:\n\t\tm := make(map[string]uint64, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asString(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asUint(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapIntString:\n\t\tm := make(map[int]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt8String:\n\t\tm := make(map[int8]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int8(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt16String:\n\t\tm := make(map[int16]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int16(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt32String:\n\t\tm := make(map[int32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int32(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt64String:\n\t\tm := make(map[int64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapIntBool:\n\t\tm := make(map[int]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt8Bool:\n\t\tm := make(map[int8]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int8(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt16Bool:\n\t\tm := make(map[int16]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int16(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt32Bool:\n\t\tm := make(map[int32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[int32(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapInt64Bool:\n\t\tm := make(map[int64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asInt(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUintString:\n\t\tm := make(map[uint]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint8String:\n\t\tm := make(map[uint8]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint8(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint16String:\n\t\tm := make(map[uint16]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint16(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint32String:\n\t\tm := make(map[uint32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint32(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint64String:\n\t\tm := make(map[uint64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUintBool:\n\t\tm := make(map[uint]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint8Bool:\n\t\tm := make(map[uint8]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint8(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint16Bool:\n\t\tm := make(map[uint16]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint16(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint32Bool:\n\t\tm := make(map[uint32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[uint32(k)] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapUint64Bool:\n\t\tm := make(map[uint64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asUint(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapFloat32String:\n\t\tm := make(map[float32]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asFloat32(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapFloat64String:\n\t\tm := make(map[float64]string, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asFloat64(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asString(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapFloat32Bool:\n\t\tm := make(map[float32]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asFloat32(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\n\tcase typeMapFloat64Bool:\n\t\tm := make(map[float64]bool, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tk, err := d.asFloat64(keyKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tv, err := d.asBool(valueKind)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tm[k] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(m))\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/map_test.go",
    "content": "package decoding\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_mapLength(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (int, error) {\n\t\treturn d.mapLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:             \"FixMap\",\n\t\t\tCode:             def.FixMap + 3,\n\t\t\tExpected:         3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map16.error\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{},\n\t\t\tReadCount:        0,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map16.ok\",\n\t\t\tCode:             def.Map16,\n\t\t\tData:             []byte{0xff, 0xff},\n\t\t\tExpected:         math.MaxUint16,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map32.error\",\n\t\t\tCode:             def.Map32,\n\t\t\tData:             []byte{},\n\t\t\tReadCount:        0,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Map32.ok\",\n\t\t\tCode:             def.Map32,\n\t\t\tData:             []byte{0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected:         math.MaxUint32,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asFixedMap_StringInt(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.PositiveFixIntMin + dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[string]int)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]int{\"a\": 1})\n\tv2 := new(map[string]int8)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]int8{\"a\": 2})\n\tv3 := new(map[string]int16)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[string]int16{\"a\": 3})\n\tv4 := new(map[string]int32)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[string]int32{\"a\": 4})\n\tv5 := new(map[string]int64)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[string]int64{\"a\": 5})\n}\n\nfunc Test_asFixedMap_StringUint(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Uint8, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[string]uint)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]uint{\"a\": 1})\n\tv2 := new(map[string]uint8)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]uint8{\"a\": 2})\n\tv3 := new(map[string]uint16)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[string]uint16{\"a\": 3})\n\tv4 := new(map[string]uint32)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[string]uint32{\"a\": 4})\n\tv5 := new(map[string]uint64)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[string]uint64{\"a\": 5})\n}\n\nfunc Test_asFixedMap_StringFloat(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Int16, 0, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[string]float32)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[string]float32{\"a\": 1})\n\tv2 := new(map[string]float64)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[string]float64{\"a\": 2})\n}\n\nfunc Test_asFixedMap_StringBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[string]bool)\n\trun(t, v1, def.True)\n\ttu.EqualMap(t, *v1, map[string]bool{\"a\": true})\n}\n\nfunc Test_asFixedMap_StringString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.FixStr + 1, dv},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[string]string)\n\trun(t, v1, 'b')\n\ttu.EqualMap(t, *v1, map[string]string{\"a\": \"b\"})\n}\n\nfunc Test_asFixedMap_IntString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[int]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[int]string{1: \"b\"})\n\tv2 := new(map[int8]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[int8]string{int8(2): \"b\"})\n\tv3 := new(map[int16]string)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[int16]string{int16(3): \"b\"})\n\tv4 := new(map[int32]string)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[int32]string{int32(4): \"b\"})\n\tv5 := new(map[int64]string)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[int64]string{int64(5): \"b\"})\n}\n\nfunc Test_asFixedMap_IntBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asInt\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Int8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Int8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[int]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[int]bool{1: true})\n\tv2 := new(map[int8]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[int8]bool{int8(2): true})\n\tv3 := new(map[int16]bool)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[int16]bool{int16(3): true})\n\tv4 := new(map[int32]bool)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[int32]bool{int32(4): true})\n\tv5 := new(map[int64]bool)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[int64]bool{int64(5): true})\n}\n\nfunc Test_asFixedMap_UintString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[uint]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[uint]string{1: \"b\"})\n\tv2 := new(map[uint8]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[uint8]string{uint8(2): \"b\"})\n\tv3 := new(map[uint16]string)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[uint16]string{uint16(3): \"b\"})\n\tv4 := new(map[uint32]string)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[uint32]string{uint32(4): \"b\"})\n\tv5 := new(map[uint64]string)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[uint64]string{uint64(5): \"b\"})\n}\n\nfunc Test_asFixedMap_UintBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asUint\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[uint]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[uint]bool{1: true})\n\tv2 := new(map[uint8]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[uint8]bool{uint8(2): true})\n\tv3 := new(map[uint16]bool)\n\trun(t, v3, 3)\n\ttu.EqualMap(t, *v3, map[uint16]bool{uint16(3): true})\n\tv4 := new(map[uint32]bool)\n\trun(t, v4, 4)\n\ttu.EqualMap(t, *v4, map[uint32]bool{uint32(4): true})\n\tv5 := new(map[uint64]bool)\n\trun(t, v5, 5)\n\ttu.EqualMap(t, *v5, map[uint64]bool{uint64(5): true})\n}\n\nfunc Test_asFixedMap_FloatString(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asString\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[float32]string)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[float32]string{1: \"b\"})\n\tv2 := new(map[float64]string)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[float64]string{2: \"b\"})\n}\n\nfunc Test_asFixedMap_FloatBool(t *testing.T) {\n\trun := func(t *testing.T, v any, dv byte) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedMap(rv.Elem(), 1)\n\t\t}\n\n\t\tname := fmt.Sprintf(\"%T\", v)\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           name + \".error.asFloat\",\n\t\t\t\tCode:           def.Str8,\n\t\t\t\tData:           []byte{def.Str8},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      1,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".error.asBool\",\n\t\t\t\tCode:           def.Int32,\n\t\t\t\tData:           []byte{def.Uint8, dv, def.Int32},\n\t\t\t\tExpected:       false,\n\t\t\t\tReadCount:      3,\n\t\t\t\tError:          def.ErrCanNotDecode,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           name + \".ok\",\n\t\t\t\tData:           []byte{def.Uint8, dv, def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      3,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new(map[float32]bool)\n\trun(t, v1, 1)\n\ttu.EqualMap(t, *v1, map[float32]bool{1: true})\n\tv2 := new(map[float64]bool)\n\trun(t, v2, 2)\n\ttu.EqualMap(t, *v2, map[float64]bool{2: true})\n}\n"
  },
  {
    "path": "internal/stream/decoding/nil.go",
    "content": "package decoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\nfunc (d *decoder) isCodeNil(v byte) bool {\n\treturn def.Nil == v\n}\n"
  },
  {
    "path": "internal/stream/decoding/read.go",
    "content": "package decoding\n\nfunc (d *decoder) readSize1() (byte, error) {\n\tif _, err := d.r.Read(d.buf.B1); err != nil {\n\t\treturn 0, err\n\t}\n\treturn d.buf.B1[0], nil\n}\n\nfunc (d *decoder) readSize2() ([]byte, error) {\n\tif _, err := d.r.Read(d.buf.B2); err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn d.buf.B2, nil\n}\n\nfunc (d *decoder) readSize4() ([]byte, error) {\n\tif _, err := d.r.Read(d.buf.B4); err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn d.buf.B4, nil\n}\n\nfunc (d *decoder) readSize8() ([]byte, error) {\n\tif _, err := d.r.Read(d.buf.B8); err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn d.buf.B8, nil\n}\n\nfunc (d *decoder) readSize16() ([]byte, error) {\n\tif _, err := d.r.Read(d.buf.B16); err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn d.buf.B16, nil\n}\n\nfunc (d *decoder) readSizeN(n int) ([]byte, error) {\n\tvar b []byte\n\tif n <= len(d.buf.Data) {\n\t\tb = d.buf.Data[:n]\n\t} else {\n\t\td.buf.Data = append(d.buf.Data, make([]byte, n-len(d.buf.Data))...)\n\t\tb = d.buf.Data\n\t}\n\tif _, err := d.r.Read(b); err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn b, nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/slice.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\ttypeIntSlice   = reflect.TypeOf([]int{})\n\ttypeInt8Slice  = reflect.TypeOf([]int8{})\n\ttypeInt16Slice = reflect.TypeOf([]int16{})\n\ttypeInt32Slice = reflect.TypeOf([]int32{})\n\ttypeInt64Slice = reflect.TypeOf([]int64{})\n\n\ttypeUintSlice   = reflect.TypeOf([]uint{})\n\ttypeUint8Slice  = reflect.TypeOf([]uint8{})\n\ttypeUint16Slice = reflect.TypeOf([]uint16{})\n\ttypeUint32Slice = reflect.TypeOf([]uint32{})\n\ttypeUint64Slice = reflect.TypeOf([]uint64{})\n\n\ttypeFloat32Slice = reflect.TypeOf([]float32{})\n\ttypeFloat64Slice = reflect.TypeOf([]float64{})\n\n\ttypeStringSlice = reflect.TypeOf([]string{})\n\n\ttypeBoolSlice = reflect.TypeOf([]bool{})\n)\n\nfunc (d *decoder) isFixSlice(v byte) bool {\n\treturn def.FixArray <= v && v <= def.FixArray+0x0f\n}\n\nfunc (d *decoder) sliceLength(code byte, k reflect.Kind) (int, error) {\n\tswitch {\n\tcase d.isFixSlice(code):\n\t\treturn int(code - def.FixArray), nil\n\tcase code == def.Array16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(bs)), nil\n\tcase code == def.Array32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(bs)), nil\n\t}\n\treturn 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asFixedSlice(rv reflect.Value, l int) (bool, error) {\n\tt := rv.Type()\n\tk := t.Elem().Kind()\n\n\tswitch t {\n\tcase typeIntSlice:\n\t\tsli := make([]int, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asInt(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = int(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeUintSlice:\n\t\tsli := make([]uint, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asUint(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = uint(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeStringSlice:\n\t\tsli := make([]string, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asString(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeBoolSlice:\n\t\tsli := make([]bool, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asBool(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeFloat32Slice:\n\t\tsli := make([]float32, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asFloat32(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeFloat64Slice:\n\t\tsli := make([]float64, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asFloat64(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeInt8Slice:\n\t\tsli := make([]int8, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asInt(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = int8(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeInt16Slice:\n\t\tsli := make([]int16, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asInt(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = int16(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeInt32Slice:\n\t\tsli := make([]int32, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asInt(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = int32(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeInt64Slice:\n\t\tsli := make([]int64, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asInt(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeUint8Slice:\n\t\tsli := make([]uint8, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asUint(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = uint8(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeUint16Slice:\n\t\tsli := make([]uint16, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asUint(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = uint16(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeUint32Slice:\n\t\tsli := make([]uint32, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asUint(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = uint32(v)\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\n\tcase typeUint64Slice:\n\t\tsli := make([]uint64, l)\n\t\tfor i := range sli {\n\t\t\tv, err := d.asUint(k)\n\t\t\tif err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tsli[i] = v\n\t\t}\n\t\trv.Set(reflect.ValueOf(sli))\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/slice_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_sliceLength(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (int, error) {\n\t\treturn d.sliceLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:             \"FixArray\",\n\t\t\tCode:             def.FixArray + 3,\n\t\t\tExpected:         3,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array16.error\",\n\t\t\tCode:             def.Array16,\n\t\t\tData:             []byte{},\n\t\t\tReadCount:        0,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array16.ok\",\n\t\t\tCode:             def.Array16,\n\t\t\tData:             []byte{0xff, 0xff},\n\t\t\tExpected:         math.MaxUint16,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array32.error\",\n\t\t\tCode:             def.Array32,\n\t\t\tData:             []byte{},\n\t\t\tReadCount:        0,\n\t\t\tError:            io.EOF,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Array32.ok\",\n\t\t\tCode:             def.Array32,\n\t\t\tData:             []byte{0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected:         math.MaxUint32,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Nil,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asFixedSlice_Int(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 3},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int{3})\n}\n\nfunc Test_asFixedSlice_Int8(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 4},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int8)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int8{4})\n}\n\nfunc Test_asFixedSlice_Int16(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 5},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int16)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int16{5})\n}\n\nfunc Test_asFixedSlice_Int32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 6},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int32{6})\n}\n\nfunc Test_asFixedSlice_Int64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 7},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]int64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []int64{7})\n}\n\nfunc Test_asFixedSlice_Uint(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 5},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]uint)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint{5})\n}\n\nfunc Test_asFixedSlice_Uint8(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 6},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]uint8)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint8{6})\n}\n\nfunc Test_asFixedSlice_Uint16(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 7},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]uint16)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint16{7})\n}\n\nfunc Test_asFixedSlice_Uint32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 8},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]uint32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint32{8})\n}\n\nfunc Test_asFixedSlice_Uint64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.PositiveFixIntMin + 9},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]uint64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []uint64{9})\n}\n\nfunc Test_asFixedSlice_Float32(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.Float32, 63, 128, 0, 0},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      2,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]float32)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []float32{1})\n}\n\nfunc Test_asFixedSlice_Float64(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.Float64, 63, 240, 0, 0, 0, 0, 0, 0},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      2,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]float64)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []float64{1})\n}\n\nfunc Test_asFixedSlice_String(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 2)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.FixStr + 1, 'a', def.FixStr + 1, 'b'},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      4,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]string)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []string{\"a\", \"b\"})\n}\n\nfunc Test_asFixedSlice_Bool(t *testing.T) {\n\trun := func(t *testing.T, v any) {\n\t\tmethod := func(d *decoder) (bool, error) {\n\t\t\trv := reflect.ValueOf(v)\n\t\t\treturn d.asFixedSlice(rv.Elem(), 1)\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tData:           []byte{},\n\t\t\t\tError:          io.EOF,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tData:           []byte{def.True},\n\t\t\t\tExpected:       true,\n\t\t\t\tReadCount:      1,\n\t\t\t\tMethodAsCustom: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tv1 := new([]bool)\n\trun(t, v1)\n\ttu.EqualSlice(t, *v1, []bool{true})\n}\n"
  },
  {
    "path": "internal/stream/decoding/string.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar (\n\temptyString = \"\"\n\temptyBytes  = []byte{}\n)\n\nfunc (d *decoder) isCodeString(code byte) bool {\n\treturn d.isFixString(code) || code == def.Str8 || code == def.Str16 || code == def.Str32\n}\n\nfunc (d *decoder) isFixString(v byte) bool {\n\treturn def.FixStr <= v && v <= def.FixStr+0x1f\n}\n\nfunc (d *decoder) stringByteLength(code byte, k reflect.Kind) (int, error) {\n\tif def.FixStr <= code && code <= def.FixStr+0x1f {\n\t\tl := int(code - def.FixStr)\n\t\treturn l, nil\n\t} else if code == def.Str8 {\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(b), nil\n\t} else if code == def.Str16 {\n\t\tb, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint16(b)), nil\n\t} else if code == def.Str32 {\n\t\tb, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn int(binary.BigEndian.Uint32(b)), nil\n\t} else if code == def.Nil {\n\t\treturn 0, nil\n\t}\n\treturn 0, d.errorTemplate(code, k)\n}\n\nfunc (d *decoder) asString(k reflect.Kind) (string, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn emptyString, err\n\t}\n\treturn d.asStringWithCode(code, k)\n}\n\nfunc (d *decoder) asStringWithCode(code byte, k reflect.Kind) (string, error) {\n\tbs, err := d.asStringByteWithCode(code, k)\n\tif err != nil {\n\t\treturn emptyString, err\n\t}\n\treturn string(bs), nil\n}\n\nfunc (d *decoder) asStringByte(k reflect.Kind) ([]byte, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn emptyBytes, err\n\t}\n\treturn d.asStringByteWithCode(code, k)\n}\n\nfunc (d *decoder) asStringByteWithCode(code byte, k reflect.Kind) ([]byte, error) {\n\tl, err := d.stringByteLength(code, k)\n\tif err != nil {\n\t\treturn emptyBytes, err\n\t}\n\n\treturn d.asStringByteByLength(l, k)\n}\n\nfunc (d *decoder) asStringByteByLength(l int, _ reflect.Kind) ([]byte, error) {\n\tif l < 1 {\n\t\treturn emptyBytes, nil\n\t}\n\n\t// avoid common buffer reference\n\treturn d.copySizeN(l)\n}\n"
  },
  {
    "path": "internal/stream/decoding/string_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_stringByteLength(t *testing.T) {\n\tmethod := func(d *decoder) func(byte, reflect.Kind) (int, error) {\n\t\treturn d.stringByteLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:             \"FixStr\",\n\t\t\tCode:             def.FixStr + 1,\n\t\t\tExpected:         1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str8.error\",\n\t\t\tCode:             def.Str8,\n\t\t\tData:             []byte{},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str8.ok\",\n\t\t\tCode:             def.Str8,\n\t\t\tData:             []byte{0xff},\n\t\t\tExpected:         math.MaxUint8,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str16.error\",\n\t\t\tCode:             def.Str16,\n\t\t\tData:             []byte{},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str16.ok\",\n\t\t\tCode:             def.Str16,\n\t\t\tData:             []byte{0xff, 0xff},\n\t\t\tExpected:         math.MaxUint16,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str32.error\",\n\t\t\tCode:             def.Str32,\n\t\t\tData:             []byte{},\n\t\t\tError:            io.EOF,\n\t\t\tReadCount:        0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Str32.ok\",\n\t\t\tCode:             def.Str32,\n\t\t\tData:             []byte{0xff, 0xff, 0xff, 0xff},\n\t\t\tExpected:         math.MaxUint32,\n\t\t\tReadCount:        1,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Nil\",\n\t\t\tCode:             def.Nil,\n\t\t\tExpected:         0,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t\t{\n\t\t\tName:             \"Unexpected\",\n\t\t\tCode:             def.Array16,\n\t\t\tError:            def.ErrCanNotDecode,\n\t\t\tMethodAsWithCode: method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asString(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) (string, error) {\n\t\treturn d.asString\n\t}\n\ttestcases := AsXXXTestCases[string]{\n\t\t{\n\t\t\tName:      \"error.code\",\n\t\t\tData:      []byte{},\n\t\t\tError:     io.EOF,\n\t\t\tReadCount: 0,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"error.string\",\n\t\t\tData:      []byte{def.FixStr + 1},\n\t\t\tError:     io.EOF,\n\t\t\tReadCount: 1,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.FixStr + 1, 'a'},\n\t\t\tExpected:  \"a\",\n\t\t\tReadCount: 2,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc Test_asStringByte(t *testing.T) {\n\tmethod := func(d *decoder) func(reflect.Kind) ([]byte, error) {\n\t\treturn d.asStringByte\n\t}\n\ttestcases := AsXXXTestCases[[]byte]{\n\t\t{\n\t\t\tName:      \"error\",\n\t\t\tData:      []byte{def.FixStr + 1},\n\t\t\tError:     io.EOF,\n\t\t\tReadCount: 1,\n\t\t\tMethodAs:  method,\n\t\t},\n\t\t{\n\t\t\tName:      \"ok\",\n\t\t\tData:      []byte{def.FixStr + 1, 'a'},\n\t\t\tExpected:  []byte{'a'},\n\t\t\tReadCount: 2,\n\t\t\tMethodAs:  method,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/struct.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\ntype structCacheTypeMap struct {\n\tkeys [][]byte\n\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes [][]int // field path (support for embedded structs)\n}\n\ntype structCacheTypeArray struct {\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes [][]int // field path (support for embedded structs)\n}\n\n// struct cache map\nvar (\n\tmapSCTM = sync.Map{}\n\tmapSCTA = sync.Map{}\n)\n\n// getFieldByPath returns the field value by following the path of indices.\n// The bool indicates whether the path was reachable (no nil pointer in the path).\nfunc getFieldByPath(rv reflect.Value, path []int, allowAlloc bool) (reflect.Value, bool) {\n\tfor _, idx := range path {\n\t\t// Handle pointer indirection if needed\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\tif rv.IsNil() {\n\t\t\t\tif !allowAlloc {\n\t\t\t\t\treturn reflect.Value{}, false\n\t\t\t\t}\n\t\t\t\t// Allocate new value if pointer is nil\n\t\t\t\trv.Set(reflect.New(rv.Type().Elem()))\n\t\t\t}\n\t\t\trv = rv.Elem()\n\t\t}\n\t\trv = rv.Field(idx)\n\t}\n\treturn rv, true\n}\n\nfunc (d *decoder) setStruct(code byte, rv reflect.Value, k reflect.Kind) error {\n\tif len(extCoders) > 0 {\n\t\tinnerType, data, err := d.readIfExtType(code)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif data != nil {\n\t\t\tfor i := range extCoders {\n\t\t\t\tif extCoders[i].IsType(code, innerType, len(data)) {\n\t\t\t\t\tv, err := extCoders[i].ToValue(code, data, k)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\n\t\t\t\t\t// Validate that the receptacle is of the right value type.\n\t\t\t\t\tif rv.Type() == reflect.TypeOf(v) {\n\t\t\t\t\t\trv.Set(reflect.ValueOf(v))\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif d.asArray {\n\t\treturn d.setStructFromArray(code, rv, k)\n\t}\n\treturn d.setStructFromMap(code, rv, k)\n}\n\nfunc (d *decoder) setStructFromArray(code byte, rv reflect.Value, k reflect.Kind) error {\n\t// get length\n\tl, err := d.sliceLength(code, k)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// find or create reference\n\tvar scta *structCacheTypeArray\n\tcache, findCache := mapSCTA.Load(rv.Type())\n\tif !findCache {\n\t\tscta = &structCacheTypeArray{}\n\t\tfields := d.CollectFields(rv.Type(), nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tscta.hasEmbedded = hasEmbedded\n\n\t\tfor _, field := range fields {\n\t\t\tif hasEmbedded {\n\t\t\t\tscta.indexes = append(scta.indexes, field.Path)\n\t\t\t} else {\n\t\t\t\tscta.simpleIndexes = append(scta.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t}\n\t\tmapSCTA.Store(rv.Type(), scta)\n\t} else {\n\t\tscta = cache.(*structCacheTypeArray)\n\t}\n\n\t// set value\n\tif scta.hasEmbedded {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif i < len(scta.indexes) {\n\t\t\t\tcode, err := d.readSize1()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tallowAlloc := !d.isCodeNil(code)\n\t\t\t\tfieldValue, ok := getFieldByPath(rv, scta.indexes[i], allowAlloc)\n\t\t\t\tif ok {\n\t\t\t\t\terr = d.decodeWithCode(code, fieldValue)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t} else if !d.isCodeNil(code) {\n\t\t\t\t\treturn d.errorTemplate(code, k)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = d.jumpOffset()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif i < len(scta.simpleIndexes) {\n\t\t\t\terr = d.decode(rv.Field(scta.simpleIndexes[i]))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = d.jumpOffset()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (d *decoder) setStructFromMap(code byte, rv reflect.Value, k reflect.Kind) error {\n\t// get length\n\tl, err := d.mapLength(code, k)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar sctm *structCacheTypeMap\n\tcache, cacheFind := mapSCTM.Load(rv.Type())\n\tif !cacheFind {\n\t\tsctm = &structCacheTypeMap{}\n\t\tfields := d.CollectFields(rv.Type(), nil)\n\n\t\t// detect embedded fields\n\t\thasEmbedded := false\n\t\tfor _, f := range fields {\n\t\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\t\thasEmbedded = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tsctm.hasEmbedded = hasEmbedded\n\n\t\tfor _, field := range fields {\n\t\t\tsctm.keys = append(sctm.keys, []byte(field.Name))\n\t\t\tif hasEmbedded {\n\t\t\t\tsctm.indexes = append(sctm.indexes, field.Path)\n\t\t\t} else {\n\t\t\t\tsctm.simpleIndexes = append(sctm.simpleIndexes, field.Path[0])\n\t\t\t}\n\t\t}\n\t\tmapSCTM.Store(rv.Type(), sctm)\n\t} else {\n\t\tsctm = cache.(*structCacheTypeMap)\n\t}\n\n\tif sctm.hasEmbedded {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tdataKey, err := d.asStringByte(k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfieldPath := []int(nil)\n\t\t\tfor keyIndex, keyBytes := range sctm.keys {\n\t\t\t\tif len(keyBytes) != len(dataKey) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfound := true\n\t\t\t\tfor dataIndex := range dataKey {\n\t\t\t\t\tif dataKey[dataIndex] != keyBytes[dataIndex] {\n\t\t\t\t\t\tfound = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif found {\n\t\t\t\t\tfieldPath = sctm.indexes[keyIndex]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif fieldPath != nil {\n\t\t\t\tcode, err := d.readSize1()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tallowAlloc := !d.isCodeNil(code)\n\t\t\t\tfieldValue, ok := getFieldByPath(rv, fieldPath, allowAlloc)\n\t\t\t\tif ok {\n\t\t\t\t\terr = d.decodeWithCode(code, fieldValue)\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\treturn err\n\t\t\t\t\t}\n\t\t\t\t} else if !d.isCodeNil(code) {\n\t\t\t\t\treturn d.errorTemplate(code, k)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = d.jumpOffset()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < l; i++ {\n\t\t\tdataKey, err := d.asStringByte(k)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tfieldIndex := -1\n\t\t\tfor keyIndex, keyBytes := range sctm.keys {\n\t\t\t\tif len(keyBytes) != len(dataKey) {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tfound := true\n\t\t\t\tfor dataIndex := range dataKey {\n\t\t\t\t\tif dataKey[dataIndex] != keyBytes[dataIndex] {\n\t\t\t\t\t\tfound = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif found {\n\t\t\t\t\tfieldIndex = sctm.simpleIndexes[keyIndex]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif fieldIndex >= 0 {\n\t\t\t\terr = d.decode(rv.Field(fieldIndex))\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terr = d.jumpOffset()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (d *decoder) jumpOffset() error {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tswitch {\n\tcase code == def.True, code == def.False, code == def.Nil:\n\t\t// do nothing\n\n\tcase d.isPositiveFixNum(code) || d.isNegativeFixNum(code):\n\t\t// do nothing\n\tcase code == def.Uint8, code == def.Int8:\n\t\t_, err = d.readSize1()\n\t\treturn err\n\tcase code == def.Uint16, code == def.Int16:\n\t\t_, err = d.readSize2()\n\t\treturn err\n\tcase code == def.Uint32, code == def.Int32, code == def.Float32:\n\t\t_, err = d.readSize4()\n\t\treturn err\n\tcase code == def.Uint64, code == def.Int64, code == def.Float64:\n\t\t_, err = d.readSize8()\n\t\treturn err\n\n\tcase d.isFixString(code):\n\t\t_, err = d.readSizeN(int(code - def.FixStr))\n\t\treturn err\n\tcase code == def.Str8, code == def.Bin8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(int(b))\n\t\treturn err\n\tcase code == def.Str16, code == def.Bin16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(int(binary.BigEndian.Uint16(bs)))\n\t\treturn err\n\tcase code == def.Str32, code == def.Bin32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(int(binary.BigEndian.Uint32(bs)))\n\t\treturn err\n\n\tcase d.isFixSlice(code):\n\t\tl := int(code - def.FixArray)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase code == def.Array16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint16(bs))\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase code == def.Array32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint32(bs))\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase d.isFixMap(code):\n\t\tl := int(code - def.FixMap)\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase code == def.Map16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint16(bs))\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\tcase code == def.Map32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tl := int(binary.BigEndian.Uint32(bs))\n\t\tfor i := 0; i < l*2; i++ {\n\t\t\tif err = d.jumpOffset(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase code == def.Fixext1:\n\t\t_, err = d.readSizeN(def.Byte1 + def.Byte1)\n\t\treturn err\n\tcase code == def.Fixext2:\n\t\t_, err = d.readSizeN(def.Byte1 + def.Byte2)\n\t\treturn err\n\tcase code == def.Fixext4:\n\t\t_, err = d.readSizeN(def.Byte1 + def.Byte4)\n\t\treturn err\n\tcase code == def.Fixext8:\n\t\t_, err = d.readSizeN(def.Byte1 + def.Byte8)\n\t\treturn err\n\tcase code == def.Fixext16:\n\t\t_, err = d.readSizeN(def.Byte1 + def.Byte16)\n\t\treturn err\n\n\tcase code == def.Ext8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(def.Byte1 + int(b))\n\t\treturn err\n\tcase code == def.Ext16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(def.Byte1 + int(binary.BigEndian.Uint16(bs)))\n\t\treturn err\n\tcase code == def.Ext32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\t_, err = d.readSizeN(def.Byte1 + int(binary.BigEndian.Uint32(bs)))\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/decoding/struct_test.go",
    "content": "package decoding\n\nimport (\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_setStruct_ext(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(byte, reflect.Kind) (any, error) {\n\t\t\treturn func(code byte, k reflect.Kind) (any, error) {\n\t\t\t\treturn nil, d.setStruct(code, rv, k)\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:             \"Ext.error\",\n\t\t\t\tCode:             def.Fixext1,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ExtCoder.error\",\n\t\t\t\tCode:             def.Fixext1,\n\t\t\t\tData:             []byte{3, 0},\n\t\t\t\tReadCount:        2,\n\t\t\t\tError:            ErrTestExtStreamDecoder,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ExtCoder.ok\",\n\t\t\t\tCode:             def.Fixext4,\n\t\t\t\tData:             []byte{255, 0, 0, 0, 0},\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\tngDec := testExt2StreamDecoder{}\n\tAddExtDecoder(&ngDec)\n\tdefer RemoveExtDecoder(&ngDec)\n\n\tv1 := new(time.Time)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.EqualEqualer(t, *v1, time.Unix(0, 0))\n}\n\nfunc Test_setStructFromMap(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(byte, reflect.Kind) (any, error) {\n\t\t\treturn func(code byte, k reflect.Kind) (any, error) {\n\t\t\t\treturn nil, d.setStructFromMap(code, rv, k)\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:             \"error.length\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.key\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.decode\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'v', def.Array16},\n\t\t\t\tReadCount:        4,\n\t\t\t\tError:            def.ErrCanNotDecode,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.jump\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 2, def.FixStr + 1, 'v', 0, def.FixStr + 1, 'b'},\n\t\t\t\tReadCount:        6,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Map16,\n\t\t\t\tData:             []byte{0, 1, def.FixStr + 1, 'v', def.PositiveFixIntMin + 7},\n\t\t\t\tReadCount:        4,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\ttype st struct {\n\t\tV int `msgpack:\"v\"`\n\t}\n\n\tv1 := new(st)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.Equal(t, v1.V, 7)\n}\n\nfunc Test_setStructFromArray(t *testing.T) {\n\trun := func(t *testing.T, rv reflect.Value) {\n\t\tmethod := func(d *decoder) func(byte, reflect.Kind) (any, error) {\n\t\t\treturn func(code byte, k reflect.Kind) (any, error) {\n\t\t\t\treturn nil, d.setStructFromArray(code, rv, k)\n\t\t\t}\n\t\t}\n\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:             \"error.length\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{},\n\t\t\t\tReadCount:        0,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.key\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1},\n\t\t\t\tReadCount:        1,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.decode\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.Array16},\n\t\t\t\tReadCount:        2,\n\t\t\t\tError:            def.ErrCanNotDecode,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"error.jump\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 2, 0},\n\t\t\t\tReadCount:        2,\n\t\t\t\tError:            io.EOF,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:             \"ok\",\n\t\t\t\tCode:             def.Array16,\n\t\t\t\tData:             []byte{0, 1, def.PositiveFixIntMin + 8},\n\t\t\t\tReadCount:        2,\n\t\t\t\tMethodAsWithCode: method,\n\t\t\t},\n\t\t}\n\t\tfor _, tc := range testcases {\n\t\t\ttc.Run(t)\n\t\t}\n\t}\n\n\ttype st struct {\n\t\tV int `msgpack:\"v\"`\n\t}\n\n\tv1 := new(st)\n\trun(t, reflect.ValueOf(v1).Elem())\n\ttu.Equal(t, v1.V, 8)\n}\n\nfunc Test_jumpOffset(t *testing.T) {\n\tmethod := func(d *decoder) (any, error) {\n\t\treturn nil, d.jumpOffset()\n\t}\n\n\ttestcases := AsXXXTestCases[any]{\n\t\t{\n\t\t\tName:           \"error.read.code\",\n\t\t\tData:           []byte{},\n\t\t\tReadCount:      0,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"True.ok\",\n\t\t\tData:           []byte{def.True},\n\t\t\tReadCount:      1,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"False.ok\",\n\t\t\tData:           []byte{def.False},\n\t\t\tReadCount:      1,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"PositiveFixNum.ok\",\n\t\t\tData:           []byte{def.PositiveFixIntMin + 1},\n\t\t\tReadCount:      1,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"NegativeFixNum.ok\",\n\t\t\tData:           []byte{0xf0},\n\t\t\tReadCount:      1,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint8.error\",\n\t\t\tData:           []byte{def.Uint8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int8.error\",\n\t\t\tData:           []byte{def.Int8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint8.ok\",\n\t\t\tData:           []byte{def.Uint8, 1},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int8.ok\",\n\t\t\tData:           []byte{def.Int8, 1},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint16.error\",\n\t\t\tData:           []byte{def.Uint16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int16.error\",\n\t\t\tData:           []byte{def.Int16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint16.ok\",\n\t\t\tData:           []byte{def.Uint16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int16.ok\",\n\t\t\tData:           []byte{def.Int16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint32.error\",\n\t\t\tData:           []byte{def.Uint32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int32.error\",\n\t\t\tData:           []byte{def.Int32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Float32.error\",\n\t\t\tData:           []byte{def.Float32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint32.ok\",\n\t\t\tData:           []byte{def.Uint32, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int32.ok\",\n\t\t\tData:           []byte{def.Int32, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Float32.ok\",\n\t\t\tData:           []byte{def.Float32, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint64.error\",\n\t\t\tData:           []byte{def.Uint64},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int64.error\",\n\t\t\tData:           []byte{def.Int64},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Float64.error\",\n\t\t\tData:           []byte{def.Float64},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Uint64.ok\",\n\t\t\tData:           []byte{def.Uint64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Int64.ok\",\n\t\t\tData:           []byte{def.Int64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Float64.ok\",\n\t\t\tData:           []byte{def.Float64, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixStr.ng\",\n\t\t\tData:           []byte{def.FixStr + 1},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixStr.ok\",\n\t\t\tData:           []byte{def.FixStr + 1, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str8.ng.length\",\n\t\t\tData:           []byte{def.Str8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str8.ng.str\",\n\t\t\tData:           []byte{def.Str8, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str8.ok\",\n\t\t\tData:           []byte{def.Str8, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin8.ng.length\",\n\t\t\tData:           []byte{def.Bin8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin8.ng.str\",\n\t\t\tData:           []byte{def.Bin8, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin8.ok\",\n\t\t\tData:           []byte{def.Bin8, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str16.ng.length\",\n\t\t\tData:           []byte{def.Str16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str16.ng.str\",\n\t\t\tData:           []byte{def.Str16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str16.ok\",\n\t\t\tData:           []byte{def.Str16, 0, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin16.ng.length\",\n\t\t\tData:           []byte{def.Bin16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin16.ng.str\",\n\t\t\tData:           []byte{def.Bin16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin16.ok\",\n\t\t\tData:           []byte{def.Bin16, 0, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str32.ng.length\",\n\t\t\tData:           []byte{def.Str32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str32.ng.str\",\n\t\t\tData:           []byte{def.Str32, 0, 0, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Str32.ok\",\n\t\t\tData:           []byte{def.Str32, 0, 0, 0, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin32.ng.length\",\n\t\t\tData:           []byte{def.Bin32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin32.ng.str\",\n\t\t\tData:           []byte{def.Bin32, 0, 0, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Bin32.ok\",\n\t\t\tData:           []byte{def.Bin32, 0, 0, 0, 1, 'a'},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixSlice.ng\",\n\t\t\tData:           []byte{def.FixArray + 1},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixSlice.ok\",\n\t\t\tData:           []byte{def.FixArray + 1, 0xc1},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array16.ng.len\",\n\t\t\tData:           []byte{def.Array16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array16.ng.jump\",\n\t\t\tData:           []byte{def.Array16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array16.ok\",\n\t\t\tData:           []byte{def.Array16, 0, 1, 0xc1},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array32.ng.len\",\n\t\t\tData:           []byte{def.Array32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array32.ng.jump\",\n\t\t\tData:           []byte{def.Array32, 0, 0, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Array32.ok\",\n\t\t\tData:           []byte{def.Array32, 0, 0, 0, 1, 0xc1},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixMap.ng\",\n\t\t\tData:           []byte{def.FixMap + 1},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"FixMap.ok\",\n\t\t\tData:           []byte{def.FixMap + 1, 0xc1, 0xc1},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map16.ng.len\",\n\t\t\tData:           []byte{def.Map16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map16.ng.jump\",\n\t\t\tData:           []byte{def.Map16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map16.ok\",\n\t\t\tData:           []byte{def.Map16, 0, 1, 0xc1, 0xc1},\n\t\t\tReadCount:      4,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map32.ng.len\",\n\t\t\tData:           []byte{def.Map32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map32.ng.jump\",\n\t\t\tData:           []byte{def.Map32, 0, 0, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Map32.ok\",\n\t\t\tData:           []byte{def.Map32, 0, 0, 0, 1, 0xc1, 0xc1},\n\t\t\tReadCount:      4,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext1.ng\",\n\t\t\tData:           []byte{def.Fixext1},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext1.ok\",\n\t\t\tData:           []byte{def.Fixext1, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext2.ng\",\n\t\t\tData:           []byte{def.Fixext2},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext2.ok\",\n\t\t\tData:           []byte{def.Fixext2, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext4.ng\",\n\t\t\tData:           []byte{def.Fixext4},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext4.ok\",\n\t\t\tData:           []byte{def.Fixext4, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext8.ng\",\n\t\t\tData:           []byte{def.Fixext8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext8.ok\",\n\t\t\tData:           []byte{def.Fixext8, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext16.ng\",\n\t\t\tData:           []byte{def.Fixext16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Fixext16.ok\",\n\t\t\tData:           []byte{def.Fixext16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\tReadCount:      2,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext8.ng.size\",\n\t\t\tData:           []byte{def.Ext8},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext8.ng.size.n\",\n\t\t\tData:           []byte{def.Ext8, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext8.ok\",\n\t\t\tData:           []byte{def.Ext8, 1, 0},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext16.ng.size\",\n\t\t\tData:           []byte{def.Ext16},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext16.ng.size.n\",\n\t\t\tData:           []byte{def.Ext16, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext16.ok\",\n\t\t\tData:           []byte{def.Ext16, 0, 1, 0},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext32.ng.size\",\n\t\t\tData:           []byte{def.Ext32},\n\t\t\tReadCount:      1,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext32.ng.size.n\",\n\t\t\tData:           []byte{def.Ext32, 0, 0, 0, 1},\n\t\t\tReadCount:      2,\n\t\t\tError:          io.EOF,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Ext32.ok\",\n\t\t\tData:           []byte{def.Ext32, 0, 0, 0, 1, 0},\n\t\t\tReadCount:      3,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t\t{\n\t\t\tName:           \"Unexpected\",\n\t\t\tData:           []byte{0xc1},\n\t\t\tReadCount:      1,\n\t\t\tMethodAsCustom: method,\n\t\t},\n\t}\n\tfor _, tc := range testcases {\n\t\ttc.Run(t)\n\t}\n}\n"
  },
  {
    "path": "internal/stream/decoding/uint.go",
    "content": "package decoding\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (d *decoder) asUint(k reflect.Kind) (uint64, error) {\n\tcode, err := d.readSize1()\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\treturn d.asUintWithCode(code, k)\n}\n\nfunc (d *decoder) asUintWithCode(code byte, k reflect.Kind) (uint64, error) {\n\tswitch {\n\tcase d.isPositiveFixNum(code):\n\t\treturn uint64(code), nil\n\n\tcase d.isNegativeFixNum(code):\n\t\treturn uint64(int8(code)), nil\n\n\tcase code == def.Uint8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn uint64(b), nil\n\n\tcase code == def.Int8:\n\t\tb, err := d.readSize1()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn uint64(int8(b)), nil\n\n\tcase code == def.Uint16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint16(bs)\n\t\treturn uint64(v), nil\n\n\tcase code == def.Int16:\n\t\tbs, err := d.readSize2()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := int16(binary.BigEndian.Uint16(bs))\n\t\treturn uint64(v), nil\n\n\tcase code == def.Uint32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := binary.BigEndian.Uint32(bs)\n\t\treturn uint64(v), nil\n\n\tcase code == def.Int32:\n\t\tbs, err := d.readSize4()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\tv := int32(binary.BigEndian.Uint32(bs))\n\t\treturn uint64(v), nil\n\n\tcase code == def.Uint64:\n\t\tbs, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn binary.BigEndian.Uint64(bs), nil\n\n\tcase code == def.Int64:\n\t\tbs, err := d.readSize8()\n\t\tif err != nil {\n\t\t\treturn 0, err\n\t\t}\n\t\treturn binary.BigEndian.Uint64(bs), nil\n\n\tcase code == def.Nil:\n\t\treturn 0, nil\n\t}\n\n\treturn 0, d.errorTemplate(code, k)\n}\n"
  },
  {
    "path": "internal/stream/decoding/uint_test.go",
    "content": "package decoding\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_asUint(t *testing.T) {\n\tt.Run(\"read error\", func(t *testing.T) {\n\t\td := decoder{\n\t\t\tr:   tu.NewErrReader(),\n\t\t\tbuf: common.GetBuffer(),\n\t\t}\n\t\tv, err := d.asUint(reflect.Uint)\n\t\ttu.IsError(t, err, tu.ErrReaderErr)\n\t\ttu.Equal(t, v, 0)\n\t})\n\tt.Run(\"ok\", func(t *testing.T) {\n\t\td := decoder{\n\t\t\tr:   bytes.NewReader([]byte{1}),\n\t\t\tbuf: common.GetBuffer(),\n\t\t}\n\t\tv, err := d.asUint(reflect.Uint)\n\t\ttu.NoError(t, err)\n\t\ttu.Equal(t, v, 1)\n\t})\n}\n\nfunc Test_asUintWithCode(t *testing.T) {\n\ttestcases := []struct {\n\t\tname     string\n\t\tcode     byte\n\t\tlength   int\n\t\texpected uint64\n\t\terrSkip  bool\n\t}{\n\t\t{\n\t\t\tname:     \"Uint8\",\n\t\t\tcode:     def.Uint8,\n\t\t\tlength:   1,\n\t\t\texpected: math.MaxUint8,\n\t\t},\n\t\t{\n\t\t\tname:     \"Int8\",\n\t\t\tcode:     def.Int8,\n\t\t\tlength:   1,\n\t\t\texpected: math.MaxUint64,\n\t\t},\n\t\t{\n\t\t\tname:     \"Uint16\",\n\t\t\tcode:     def.Uint16,\n\t\t\tlength:   2,\n\t\t\texpected: math.MaxUint16,\n\t\t},\n\t\t{\n\t\t\tname:     \"Int16\",\n\t\t\tcode:     def.Int16,\n\t\t\tlength:   2,\n\t\t\texpected: math.MaxUint64,\n\t\t},\n\t\t{\n\t\t\tname:     \"Uint32\",\n\t\t\tcode:     def.Uint32,\n\t\t\tlength:   4,\n\t\t\texpected: math.MaxUint32,\n\t\t},\n\t\t{\n\t\t\tname:     \"Int32\",\n\t\t\tcode:     def.Int32,\n\t\t\tlength:   4,\n\t\t\texpected: math.MaxUint64,\n\t\t},\n\t\t{\n\t\t\tname:     \"Uint64\",\n\t\t\tcode:     def.Uint64,\n\t\t\tlength:   8,\n\t\t\texpected: math.MaxUint64,\n\t\t},\n\t\t{\n\t\t\tname:     \"Int64\",\n\t\t\tcode:     def.Int64,\n\t\t\tlength:   8,\n\t\t\texpected: math.MaxUint64,\n\t\t},\n\t\t{\n\t\t\tname:     \"Nil\",\n\t\t\tcode:     def.Nil,\n\t\t\texpected: 0,\n\t\t\terrSkip:  true,\n\t\t},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name+\"\", func(t *testing.T) {\n\t\t\tt.Run(\"ng\", func(t *testing.T) {\n\t\t\t\tif tc.errSkip {\n\t\t\t\t\tt.Log(\"this testcase is skipped by skip flag\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\td := decoder{\n\t\t\t\t\tr:   tu.NewErrReader(),\n\t\t\t\t\tbuf: common.GetBuffer(),\n\t\t\t\t}\n\t\t\t\tdefer common.PutBuffer(d.buf)\n\t\t\t\t_, err := d.asUintWithCode(tc.code, reflect.String)\n\t\t\t\ttu.IsError(t, err, tu.ErrReaderErr)\n\t\t\t})\n\t\t\tt.Run(\"ok\", func(t *testing.T) {\n\t\t\t\tdata := make([]byte, tc.length)\n\t\t\t\tfor i := range data {\n\t\t\t\t\tdata[i] = 0xff\n\t\t\t\t}\n\n\t\t\t\td := decoder{\n\t\t\t\t\tr:   bytes.NewReader(data),\n\t\t\t\t\tbuf: common.GetBuffer(),\n\t\t\t\t}\n\t\t\t\tdefer common.PutBuffer(d.buf)\n\t\t\t\tv, err := d.asUintWithCode(tc.code, reflect.String)\n\t\t\t\ttu.NoError(t, err)\n\t\t\t\ttu.Equal(t, v, tc.expected)\n\n\t\t\t\tp := make([]byte, 1)\n\t\t\t\tn, err := d.r.Read(p)\n\t\t\t\ttu.IsError(t, err, io.EOF)\n\t\t\t\ttu.Equal(t, n, 0)\n\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/stream/encoding/bool.go",
    "content": "package encoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\nfunc (e *encoder) writeBool(v bool) error {\n\tif v {\n\t\treturn e.setByte1Int(def.True)\n\t}\n\treturn e.setByte1Int(def.False)\n}\n"
  },
  {
    "path": "internal/stream/encoding/bool_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asBool(t *testing.T) {\n\tmethod := func(e *encoder) func(bool) error {\n\t\treturn e.writeBool\n\t}\n\ttestcases := AsXXXTestCases[bool]{\n\t\t{\n\t\t\tName:         \"True.error\",\n\t\t\tValue:        true,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"True.ok\",\n\t\t\tValue:      true,\n\t\t\tExpected:   []byte{def.True},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/byte.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nvar typeByte = reflect.TypeOf(byte(0))\n\nfunc (e *encoder) isByteSlice(rv reflect.Value) bool {\n\treturn rv.Type().Elem() == typeByte\n}\n\nfunc (e *encoder) writeByteSliceLength(l int) error {\n\tif l <= math.MaxUint8 {\n\t\tif err := e.setByte1Int(def.Bin8); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte1Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Bin16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if uint(l) <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Bin32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/byte_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeByteSliceLength(t *testing.T) {\n\tmethod := func(e *encoder) func(int) error {\n\t\treturn e.writeByteSliceLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:         \"Bin8.error.def\",\n\t\t\tValue:        5,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Bin8.error.value\",\n\t\t\tValue:        5,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Bin8},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Bin8.ok\",\n\t\t\tValue:      5,\n\t\t\tExpected:   []byte{def.Bin8, 0x05},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Bin16.error.def\",\n\t\t\tValue:        256,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Bin16.error.value\",\n\t\t\tValue:        256,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Bin16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Bin16.ok\",\n\t\t\tValue:      256,\n\t\t\tExpected:   []byte{def.Bin16, 0x01, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Bin32.error.def\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Bin32.error.value\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Bin32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Bin32.ok\",\n\t\t\tValue:      65536,\n\t\t\tExpected:   []byte{def.Bin32, 0x00, 0x01, 0x00, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/complex.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeComplex64(v complex64) error {\n\tif err := e.setByte1Int(def.Fixext8); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte1Int(int(def.ComplexTypeCode())); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte4Uint64(uint64(math.Float32bits(real(v)))); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte4Uint64(uint64(math.Float32bits(imag(v)))); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) writeComplex128(v complex128) error {\n\tif err := e.setByte1Int(def.Fixext16); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte1Int(int(def.ComplexTypeCode())); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte8Uint64(math.Float64bits(real(v))); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte8Uint64(math.Float64bits(imag(v))); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/complex_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeComplex64(t *testing.T) {\n\tmethod := func(e *encoder) func(complex64) error {\n\t\treturn e.writeComplex64\n\t}\n\tv := complex64(complex(1, 2))\n\ttestcases := AsXXXTestCases[complex64]{\n\t\t{\n\t\t\tName:         \"error.def\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.code\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Fixext8},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.real\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Fixext8, byte(def.ComplexTypeCode())},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.imag\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   7,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains: []byte{\n\t\t\t\tdef.Fixext8, byte(def.ComplexTypeCode()),\n\t\t\t\t0x3f, 0x80, 0x00, 0x00,\n\t\t\t},\n\t\t\tMethod: method,\n\t\t},\n\t\t{\n\t\t\tName:  \"ok\",\n\t\t\tValue: v,\n\t\t\tExpected: []byte{\n\t\t\t\tdef.Fixext8, byte(def.ComplexTypeCode()),\n\t\t\t\t0x3f, 0x80, 0x00, 0x00,\n\t\t\t\t0x40, 0x00, 0x00, 0x00,\n\t\t\t},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_writeComplex128(t *testing.T) {\n\tmethod := func(e *encoder) func(complex128) error {\n\t\treturn e.writeComplex128\n\t}\n\tv := complex128(complex(1, 2))\n\ttestcases := AsXXXTestCases[complex128]{\n\t\t{\n\t\t\tName:         \"error.def\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.code\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Fixext16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.real\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Fixext16, byte(def.ComplexTypeCode())},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.imag\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   11,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains: []byte{\n\t\t\t\tdef.Fixext16, byte(def.ComplexTypeCode()),\n\t\t\t\t0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t},\n\t\t\tMethod: method,\n\t\t},\n\t\t{\n\t\t\tName:  \"ok\",\n\t\t\tValue: v,\n\t\t\tExpected: []byte{\n\t\t\t\tdef.Fixext16, byte(def.ComplexTypeCode()),\n\t\t\t\t0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/encoding.go",
    "content": "package encoding\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype encoder struct {\n\tw       io.Writer\n\tasArray bool\n\tbuf     *common.Buffer\n\tcommon.Common\n}\n\n// Encode writes MessagePack-encoded byte array of v to writer.\nfunc Encode(w io.Writer, v any, asArray bool) error {\n\te := encoder{\n\t\tw:       w,\n\t\tbuf:     common.GetBuffer(),\n\t\tasArray: asArray,\n\t}\n\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() == reflect.Ptr {\n\t\trv = rv.Elem()\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\trv = rv.Elem()\n\t\t}\n\t}\n\n\terr := e.create(rv)\n\tif err == nil {\n\t\terr = e.buf.Flush(e.w)\n\t}\n\tcommon.PutBuffer(e.buf)\n\treturn err\n}\n\nfunc (e *encoder) create(rv reflect.Value) error {\n\tswitch rv.Kind() {\n\tcase reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:\n\t\tv := rv.Uint()\n\t\treturn e.writeUint(v)\n\n\tcase reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:\n\t\tv := rv.Int()\n\t\treturn e.writeInt(v)\n\n\tcase reflect.Float32:\n\t\treturn e.writeFloat32(rv.Float())\n\n\tcase reflect.Float64:\n\t\treturn e.writeFloat64(rv.Float())\n\n\tcase reflect.Bool:\n\t\treturn e.writeBool(rv.Bool())\n\n\tcase reflect.String:\n\t\treturn e.writeString(rv.String())\n\n\tcase reflect.Complex64:\n\t\treturn e.writeComplex64(complex64(rv.Complex()))\n\n\tcase reflect.Complex128:\n\t\treturn e.writeComplex128(rv.Complex())\n\n\tcase reflect.Slice:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil()\n\t\t}\n\t\tl := rv.Len()\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\tif err := e.writeByteSliceLength(l); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn e.setBytes(rv.Bytes())\n\t\t}\n\n\t\t// format\n\t\tif err := e.writeSliceLength(l); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif find, err := e.writeFixedSlice(rv); err != nil {\n\t\t\treturn err\n\t\t} else if find {\n\t\t\treturn nil\n\t\t}\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structWriteFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructWriter(elem)\n\t\t} else {\n\t\t\tf = e.create\n\t\t}\n\n\t\t// objects\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err := f(rv.Index(i)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase reflect.Array:\n\t\tl := rv.Len()\n\t\t// bin format\n\t\tif e.isByteSlice(rv) {\n\t\t\tif err := e.writeByteSliceLength(l); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// objects\n\t\t\tfor i := 0; i < l; i++ {\n\t\t\t\tif err := e.setByte1Uint64(rv.Index(i).Uint()); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\t// format\n\t\tif err := e.writeSliceLength(l); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// func\n\t\telem := rv.Type().Elem()\n\t\tvar f structWriteFunc\n\t\tif elem.Kind() == reflect.Struct {\n\t\t\tf = e.getStructWriter(elem)\n\t\t} else {\n\t\t\tf = e.create\n\t\t}\n\n\t\t// objects\n\t\tfor i := 0; i < l; i++ {\n\t\t\tif err := f(rv.Index(i)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase reflect.Map:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil()\n\t\t}\n\n\t\tl := rv.Len()\n\t\tif err := e.writeMapLength(l); err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tif find, err := e.writeFixedMap(rv); err != nil {\n\t\t\treturn err\n\t\t} else if find {\n\t\t\treturn nil\n\t\t}\n\n\t\t// key-value\n\t\tkeys := rv.MapKeys()\n\t\tfor _, k := range keys {\n\t\t\tif err := e.create(k); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := e.create(rv.MapIndex(k)); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\n\tcase reflect.Struct:\n\t\treturn e.writeStruct(rv)\n\n\tcase reflect.Ptr:\n\t\tif rv.IsNil() {\n\t\t\treturn e.writeNil()\n\t\t}\n\n\t\treturn e.create(rv.Elem())\n\n\tcase reflect.Interface:\n\t\treturn e.create(rv.Elem())\n\n\tcase reflect.Invalid:\n\t\treturn e.writeNil()\n\tdefault:\n\t\treturn fmt.Errorf(\"%v is %w type\", rv.Kind(), def.ErrUnsupportedType)\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/encoding_test.go",
    "content": "package encoding\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"io\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nconst dummyByte = 0xc1\n\ntype TestWriter struct {\n\tWrittenBytes []byte\n}\n\nvar _ io.Writer = (*TestWriter)(nil)\n\nvar ErrTestWriter = errors.New(\"expected written error\")\n\nfunc (w *TestWriter) Write(p []byte) (n int, err error) {\n\tw.WrittenBytes = append(w.WrittenBytes, p...)\n\tif bytes.Contains(p, []byte{dummyByte}) {\n\t\treturn 0, ErrTestWriter\n\t}\n\treturn len(p), nil\n}\n\nfunc NewTestWriter() *TestWriter {\n\treturn &TestWriter{}\n}\n\ntype AsXXXTestCase[T any] struct {\n\tName            string\n\tValue           T\n\tExpected        []byte\n\tContains        []byte\n\tBufferSize      int\n\tPreWriteSize    int\n\tError           error\n\tAsArray         bool\n\tMethod          func(*encoder) func(T) error\n\tMethodForFixed  func(*encoder) func(reflect.Value) (bool, error)\n\tMethodForStruct func(*encoder) func(reflect.Value) error\n}\n\ntype AsXXXTestCases[T any] []AsXXXTestCase[T]\n\nfunc (tcs AsXXXTestCases[T]) Run(t *testing.T) {\n\tfor _, tc := range tcs {\n\t\ttc.Run(t)\n\t}\n}\n\nfunc (tc *AsXXXTestCase[T]) Run(t *testing.T) {\n\tt.Helper()\n\n\tif tc.Method == nil && tc.MethodForFixed == nil && tc.MethodForStruct == nil {\n\t\tt.Fatal(\"must set either Method or MethodForFixed or MethodForStruct\")\n\t}\n\n\tmethod := func(e *encoder) error {\n\t\tif tc.Method != nil {\n\t\t\treturn tc.Method(e)(tc.Value)\n\t\t}\n\t\tif tc.MethodForFixed != nil {\n\t\t\t_, err := tc.MethodForFixed(e)(reflect.ValueOf(tc.Value))\n\t\t\treturn err\n\t\t}\n\t\tif tc.MethodForStruct != nil {\n\t\t\treturn tc.MethodForStruct(e)(reflect.ValueOf(tc.Value))\n\t\t}\n\t\tpanic(\"unreachable\")\n\t}\n\n\tt.Run(tc.Name, func(t *testing.T) {\n\t\tw := NewTestWriter()\n\t\te := encoder{\n\t\t\tw:       w,\n\t\t\tbuf:     common.GetBuffer(),\n\t\t\tCommon:  common.Common{},\n\t\t\tasArray: tc.AsArray,\n\t\t}\n\n\t\tif tc.BufferSize < tc.PreWriteSize {\n\t\t\tt.Fatal(\"buffer size must be greater than pre write size\")\n\t\t}\n\n\t\te.buf.Data = make([]byte, tc.BufferSize)\n\t\tif tc.PreWriteSize > 0 {\n\t\t\tfor i := 0; i < tc.PreWriteSize; i++ {\n\t\t\t\t_ = e.buf.Write(e.w, dummyByte)\n\t\t\t}\n\t\t}\n\n\t\terr := method(&e)\n\t\t_ = e.buf.Flush(w)\n\t\tcommon.PutBuffer(e.buf)\n\n\t\tif tc.PreWriteSize > 0 {\n\t\t\ttu.IsError(t, err, ErrTestWriter)\n\t\t\tif !bytes.Contains(w.WrittenBytes, tc.Contains) {\n\t\t\t\tt.Fatalf(\"[% 02x] does not contain in [% 02x]\", tc.Contains, w.WrittenBytes)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t\tif tc.Error != nil {\n\t\t\ttu.IsError(t, err, tc.Error)\n\t\t\treturn\n\t\t}\n\n\t\ttu.NoError(t, err)\n\t\ttu.EqualSlice(t, w.WrittenBytes, tc.Expected)\n\t})\n}\n\nfunc TestEncode(t *testing.T) {\n\tv := 1\n\tvv := &v\n\n\tw := NewTestWriter()\n\terr := Encode(w, &vv, false)\n\ttu.NoError(t, err)\n\n\ttu.EqualSlice(t, w.WrittenBytes, []byte{def.PositiveFixIntMin + 1})\n}\n\nfunc Test_create(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) error {\n\t\treturn e.create\n\t}\n\n\tt.Run(\"uint8\", func(t *testing.T) {\n\t\tvalue := uint8(1)\n\t\ttestcases := AsXXXTestCases[uint8]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.PositiveFixIntMin + 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"uint16\", func(t *testing.T) {\n\t\tvalue := uint16(1)\n\t\ttestcases := AsXXXTestCases[uint16]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.PositiveFixIntMin + 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"uint32\", func(t *testing.T) {\n\t\tvalue := uint32(1)\n\t\ttestcases := AsXXXTestCases[uint32]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.PositiveFixIntMin + 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"uint64\", func(t *testing.T) {\n\t\tvalue := uint64(1)\n\t\ttestcases := AsXXXTestCases[uint64]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.PositiveFixIntMin + 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"uint\", func(t *testing.T) {\n\t\tvalue := uint(1)\n\t\ttestcases := AsXXXTestCases[uint]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.PositiveFixIntMin + 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"int8\", func(t *testing.T) {\n\t\tvalue := int8(-1)\n\t\ttestcases := AsXXXTestCases[int8]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{0xff},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"int16\", func(t *testing.T) {\n\t\tvalue := int16(-1)\n\t\ttestcases := AsXXXTestCases[int16]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{0xff},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"int32\", func(t *testing.T) {\n\t\tvalue := int32(-1)\n\t\ttestcases := AsXXXTestCases[int32]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{0xff},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"int64\", func(t *testing.T) {\n\t\tvalue := int64(-1)\n\t\ttestcases := AsXXXTestCases[int64]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{0xff},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"int\", func(t *testing.T) {\n\t\tvalue := int(-1)\n\t\ttestcases := AsXXXTestCases[int]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{0xff},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"float32\", func(t *testing.T) {\n\t\tvalue := float32(1)\n\t\ttestcases := AsXXXTestCases[float32]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.Float32, 0x3f, 0x80, 0x00, 0x00},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"float64\", func(t *testing.T) {\n\t\tvalue := float64(1)\n\t\ttestcases := AsXXXTestCases[float64]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"bool\", func(t *testing.T) {\n\t\tvalue := true\n\t\ttestcases := AsXXXTestCases[bool]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.True},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"string\", func(t *testing.T) {\n\t\tvalue := \"a\"\n\t\ttestcases := AsXXXTestCases[string]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.FixStr + 1, 0x61},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"complex64\", func(t *testing.T) {\n\t\tvalue := complex64(complex(1, 2))\n\t\ttestcases := AsXXXTestCases[complex64]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Fixext8, byte(def.ComplexTypeCode()),\n\t\t\t\t\t0x3f, 0x80, 0x00, 0x00,\n\t\t\t\t\t0x40, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"complex128\", func(t *testing.T) {\n\t\tvalue := complex128(complex(1, 2))\n\t\ttestcases := AsXXXTestCases[complex128]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Fixext16, byte(def.ComplexTypeCode()),\n\t\t\t\t\t0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\t0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\n\ttype st struct {\n\t\tA int\n\t}\n\n\tt.Run(\"slice\", func(t *testing.T) {\n\t\tt.Run(\"nil\", func(t *testing.T) {\n\t\t\tvar value []int\n\t\t\ttestcases := AsXXXTestCases[[]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.Nil},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"bin\", func(t *testing.T) {\n\t\t\tvalue := []byte{1, 2, 3}\n\t\t\ttestcases := AsXXXTestCases[[]byte]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      3,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.Bin8, 0x03},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.Bin8, 0x03, 0x01, 0x02, 0x03},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"fixed\", func(t *testing.T) {\n\t\t\tvalue := []int{1, 2, 3}\n\t\t\ttestcases := AsXXXTestCases[[]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 3},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 3, 0x01, 0x02, 0x03},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"slice_slice\", func(t *testing.T) {\n\t\t\tvalue := [][]int{{1}}\n\t\t\ttestcases := AsXXXTestCases[[][]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 1, def.FixArray + 1, 0x01},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"struct\", func(t *testing.T) {\n\t\t\tvalue := []st{{1}}\n\t\t\ttestcases := AsXXXTestCases[[]st]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 1, def.FixMap + 1, def.FixStr + 1, 0x41, 0x01},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t})\n\n\tt.Run(\"array\", func(t *testing.T) {\n\t\tt.Run(\"bin\", func(t *testing.T) {\n\t\t\tvalue := [3]byte{1, 2, 3}\n\t\t\ttestcases := AsXXXTestCases[[3]byte]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      3,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.Bin8, 0x03},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.Bin8, 0x03, 0x01, 0x02, 0x03},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"fixed\", func(t *testing.T) {\n\t\t\tvalue := [3]int{1, 2, 3}\n\t\t\ttestcases := AsXXXTestCases[[3]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 3},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 3, 0x01, 0x02, 0x03},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"slice_slice\", func(t *testing.T) {\n\t\t\tvalue := [1][]int{{1}}\n\t\t\ttestcases := AsXXXTestCases[[1][]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 1, def.FixArray + 1, 0x01},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"struct\", func(t *testing.T) {\n\t\t\tvalue := [1]st{{1}}\n\t\t\ttestcases := AsXXXTestCases[[1]st]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixArray + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixArray + 1, def.FixMap + 1, def.FixStr + 1, 0x41, 0x01},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t})\n\n\tt.Run(\"map\", func(t *testing.T) {\n\t\tt.Run(\"nil\", func(t *testing.T) {\n\t\t\tvar value map[string]int\n\t\t\ttestcases := AsXXXTestCases[map[string]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.Nil},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"fixed\", func(t *testing.T) {\n\t\t\tvalue := map[string]int{\"a\": 1}\n\t\t\ttestcases := AsXXXTestCases[map[string]int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixMap + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixMap + 1, def.FixStr + 1, 'a', 1},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tt.Run(\"struct\", func(t *testing.T) {\n\t\t\tvalue := map[string]st{\"a\": {1}}\n\t\t\ttestcases := AsXXXTestCases[map[string]st]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.length\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.key\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      2,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixMap + 1},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"error.value\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      4,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tContains:        []byte{def.FixMap + 1, def.FixStr + 1, 'a'},\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.FixMap + 1, def.FixStr + 1, 'a', def.FixMap + 1, def.FixStr + 1, 'A', 1},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t})\n\n\tt.Run(\"struct\", func(t *testing.T) {\n\t\tvalue := st{1}\n\t\ttestcases := AsXXXTestCases[st]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.FixMap + 1, def.FixStr + 1, 'A', 1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"pointer\", func(t *testing.T) {\n\t\tvar v *int\n\t\tvv := &v\n\t\tvalue := &vv\n\t\tt.Run(\"nil\", func(t *testing.T) {\n\t\t\ttestcases := AsXXXTestCases[***int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"nil\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{def.Nil},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t\tu := 1\n\t\tv = &u\n\t\tvv = &v\n\t\tvalue = &vv\n\t\tt.Run(\"int\", func(t *testing.T) {\n\t\t\ttestcases := AsXXXTestCases[***int]{\n\t\t\t\t{\n\t\t\t\t\tName:            \"error\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tPreWriteSize:    1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tName:            \"ok\",\n\t\t\t\t\tValue:           value,\n\t\t\t\t\tExpected:        []byte{1},\n\t\t\t\t\tBufferSize:      1,\n\t\t\t\t\tMethodForStruct: method,\n\t\t\t\t},\n\t\t\t}\n\t\t\ttestcases.Run(t)\n\t\t})\n\t})\n\tt.Run(\"any\", func(t *testing.T) {\n\t\tvalue := any(1)\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{1},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"invalid\", func(t *testing.T) {\n\t\tvar value error\n\t\ttestcases := AsXXXTestCases[error]{\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        []byte{def.Nil},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"invalid\", func(t *testing.T) {\n\t\tvar value func()\n\t\ttestcases := AsXXXTestCases[func()]{\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tError:           def.ErrUnsupportedType,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/encoding/ext.go",
    "content": "package encoding\n\nimport (\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nvar (\n\textCoderMap = map[reflect.Type]ext.StreamEncoder{time.StreamEncoder.Type(): time.StreamEncoder}\n\textCoders   = []ext.StreamEncoder{time.StreamEncoder}\n)\n\n// AddExtEncoder adds encoders for extension types.\nfunc AddExtEncoder(f ext.StreamEncoder) {\n\t// ignore time\n\tif f.Type() == time.Encoder.Type() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Type()]\n\tif !ok {\n\t\textCoderMap[f.Type()] = f\n\t\tupdateExtCoders()\n\t}\n}\n\n// RemoveExtEncoder removes encoders for extension types.\nfunc RemoveExtEncoder(f ext.StreamEncoder) {\n\t// ignore time\n\tif f.Type() == time.Encoder.Type() {\n\t\treturn\n\t}\n\n\t_, ok := extCoderMap[f.Type()]\n\tif ok {\n\t\tdelete(extCoderMap, f.Type())\n\t\tupdateExtCoders()\n\t}\n}\n\nfunc updateExtCoders() {\n\textCoders = make([]ext.StreamEncoder, len(extCoderMap))\n\ti := 0\n\tfor k := range extCoderMap {\n\t\textCoders[i] = extCoderMap[k]\n\t\ti++\n\t}\n}\n"
  },
  {
    "path": "internal/stream/encoding/ext_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\nfunc Test_AddExtEncoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tAddExtEncoder(time.StreamEncoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n\nfunc Test_RemoveExtEncoder(t *testing.T) {\n\tt.Run(\"ignore\", func(t *testing.T) {\n\t\tRemoveExtEncoder(time.StreamEncoder)\n\t\ttu.Equal(t, len(extCoders), 1)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/encoding/float.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeFloat32(v float64) error {\n\tif err := e.setByte1Int(def.Float32); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte4Uint64(uint64(math.Float32bits(float32(v)))); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) writeFloat64(v float64) error {\n\tif err := e.setByte1Int(def.Float64); err != nil {\n\t\treturn err\n\t}\n\tif err := e.setByte8Uint64(math.Float64bits(v)); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/float_test.go",
    "content": "package encoding\n\nimport (\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeFloat32(t *testing.T) {\n\tmethod := func(e *encoder) func(float64) error {\n\t\treturn e.writeFloat32\n\t}\n\tv := 1.23\n\ttestcases := AsXXXTestCases[float64]{\n\t\t{\n\t\t\tName:         \"error.def\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.value\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Float32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:  \"ok\",\n\t\t\tValue: v,\n\t\t\tExpected: []byte{\n\t\t\t\tdef.Float32,\n\t\t\t\t0x3f, 0x9d, 0x70, 0xa4,\n\t\t\t},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_writeFloat64(t *testing.T) {\n\tmethod := func(e *encoder) func(float64) error {\n\t\treturn e.writeFloat64\n\t}\n\tv := 1.23\n\ttestcases := AsXXXTestCases[float64]{\n\t\t{\n\t\t\tName:         \"error.def\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"error.value\",\n\t\t\tValue:        v,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Float64},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:  \"ok\",\n\t\t\tValue: v,\n\t\t\tExpected: []byte{\n\t\t\t\tdef.Float64,\n\t\t\t\t0x3f, 0xf3, 0xae, 0x14, 0x7a, 0xe1, 0x47, 0xae,\n\t\t\t},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/int.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) isNegativeFixInt64(v int64) bool {\n\treturn def.NegativeFixintMin <= v && v <= def.NegativeFixintMax\n}\n\nfunc (e *encoder) writeInt(v int64) error {\n\tif v >= 0 {\n\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if e.isNegativeFixInt64(v) {\n\t\tif err := e.setByte1Int64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v >= math.MinInt8 {\n\t\tif err := e.setByte1Int(def.Int8); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte1Int64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v >= math.MinInt16 {\n\t\tif err := e.setByte1Int(def.Int16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v >= math.MinInt32 {\n\t\tif err := e.setByte1Int(def.Int32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := e.setByte1Int(def.Int64); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte8Int64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/int_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asInt(t *testing.T) {\n\tmethod := func(e *encoder) func(int64) error {\n\t\treturn e.writeInt\n\t}\n\ttestcases := AsXXXTestCases[int64]{\n\t\t{\n\t\t\tName:         \"Uint.error\",\n\t\t\tValue:        math.MaxInt32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Uint.ok\",\n\t\t\tValue:      math.MaxInt32,\n\t\t\tExpected:   []byte{def.Uint32, 0x7f, 0xff, 0xff, 0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"NegativeFix.error\",\n\t\t\tValue:        -1,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"NegativeFix.ok\",\n\t\t\tValue:      -1,\n\t\t\tExpected:   []byte{0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int8.error.def\",\n\t\t\tValue:        math.MinInt8,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int8.error.value\",\n\t\t\tValue:        math.MinInt8,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Int8},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Int8.ok\",\n\t\t\tValue:      math.MinInt8,\n\t\t\tExpected:   []byte{def.Int8, 0x80},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int16.error.def\",\n\t\t\tValue:        math.MinInt16,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int16.error.value\",\n\t\t\tValue:        math.MinInt16,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Int16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Int16.ok\",\n\t\t\tValue:      math.MinInt16,\n\t\t\tExpected:   []byte{def.Int16, 0x80, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int32.error.def\",\n\t\t\tValue:        math.MinInt32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int32.error.value\",\n\t\t\tValue:        math.MinInt32,\n\t\t\tBufferSize:   5,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Int32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Int32.ok\",\n\t\t\tValue:      math.MinInt32,\n\t\t\tExpected:   []byte{def.Int32, 0x80, 0x00, 0x00, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int64.error.def\",\n\t\t\tValue:        math.MinInt64,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Int64.error.value\",\n\t\t\tValue:        math.MinInt64,\n\t\t\tBufferSize:   9,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Int64},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Int64.ok\",\n\t\t\tValue:      math.MinInt64,\n\t\t\tExpected:   []byte{def.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/map.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeMapLength(l int) error {\n\t// format\n\tif l <= 0x0f {\n\t\tif err := e.setByte1Int(def.FixMap + l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Map16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if uint(l) <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Map32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) writeFixedMap(rv reflect.Value) (bool, error) {\n\tswitch m := rv.Interface().(type) {\n\tcase map[string]int:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]uint:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]float32:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeFloat32(float64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]float64:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeFloat64(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]int8:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]int16:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]int32:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]int64:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[string]uint8:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]uint16:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]uint32:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[string]uint64:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeString(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[int]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[uint]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[float32]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeFloat32(float64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[float32]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeFloat32(float64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[float64]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeFloat64(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[float64]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeFloat64(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[int8]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int8]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int16]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int16]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int32]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int32]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(int64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int64]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[int64]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeInt(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase map[uint8]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint8]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint16]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint16]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint32]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint32]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(uint64(k)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint64]string:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\tcase map[uint64]bool:\n\t\tfor k, v := range m {\n\t\t\tif err := e.writeUint(k); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\t}\n\treturn false, nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/map_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeMapLength(t *testing.T) {\n\tmethod := func(e *encoder) func(int) error {\n\t\treturn e.writeMapLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:         \"FixMap.error\",\n\t\t\tValue:        5,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"FixMap.ok\",\n\t\t\tValue:      5,\n\t\t\tExpected:   []byte{def.FixMap + 5},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Map16.error.def\",\n\t\t\tValue:        32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Map16.error.value\",\n\t\t\tValue:        32,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Map16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Map16.ok\",\n\t\t\tValue:      32,\n\t\t\tExpected:   []byte{def.Map16, 0x00, 0x20},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Map32.error.def\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Map32.error.value\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Map32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Map32.ok\",\n\t\t\tValue:      65536,\n\t\t\tExpected:   []byte{def.Map32, 0x00, 0x01, 0x00, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_writeFixedMap(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) (bool, error) {\n\t\treturn e.writeFixedMap\n\t}\n\n\tt.Run(\"map[string]int\", func(t *testing.T) {\n\t\tvalue := map[string]int{\"a\": -1}\n\t\ttestcases := AsXXXTestCases[map[string]int]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.FixStr + 1, 0x61, 0xff},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]uint\", func(t *testing.T) {\n\t\tvalue := map[string]uint{\"a\": 1}\n\t\ttestcases := AsXXXTestCases[map[string]uint]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.FixStr + 1, 0x61, 0x01},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]float32\", func(t *testing.T) {\n\t\tvalue := map[string]float32{\"a\": 1}\n\t\ttestcases := AsXXXTestCases[map[string]float32]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.FixStr + 1, 0x61, def.Float32, 0x3f, 0x80, 0x00, 0x00},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]float64\", func(t *testing.T) {\n\t\tvalue := map[string]float64{\"a\": 1}\n\t\ttestcases := AsXXXTestCases[map[string]float64]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]bool\", func(t *testing.T) {\n\t\tvalue := map[string]bool{\"a\": true}\n\t\ttestcases := AsXXXTestCases[map[string]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.FixStr + 1, 0x61, def.True},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]string\", func(t *testing.T) {\n\t\tvalue := map[string]string{\"a\": \"b\"}\n\t\ttestcases := AsXXXTestCases[map[string]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.FixStr + 1, 0x61, def.FixStr + 1, 0x62},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]int8\", func(t *testing.T) {\n\t\tvalue := map[string]int8{\"a\": math.MinInt8}\n\t\ttestcases := AsXXXTestCases[map[string]int8]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Int8, 0x80,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]int16\", func(t *testing.T) {\n\t\tvalue := map[string]int16{\"a\": math.MinInt16}\n\t\ttestcases := AsXXXTestCases[map[string]int16]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Int16, 0x80, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]int32\", func(t *testing.T) {\n\t\tvalue := map[string]int32{\"a\": math.MinInt32}\n\t\ttestcases := AsXXXTestCases[map[string]int32]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]int64\", func(t *testing.T) {\n\t\tvalue := map[string]int64{\"a\": math.MinInt64}\n\t\ttestcases := AsXXXTestCases[map[string]int64]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]uint8\", func(t *testing.T) {\n\t\tvalue := map[string]uint8{\"a\": math.MaxUint8}\n\t\ttestcases := AsXXXTestCases[map[string]uint8]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Uint8, 0xff,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]uint16\", func(t *testing.T) {\n\t\tvalue := map[string]uint16{\"a\": math.MaxUint16}\n\t\ttestcases := AsXXXTestCases[map[string]uint16]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Uint16, 0xff, 0xff,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]uint32\", func(t *testing.T) {\n\t\tvalue := map[string]uint32{\"a\": math.MaxUint32}\n\t\ttestcases := AsXXXTestCases[map[string]uint32]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[string]uint64\", func(t *testing.T) {\n\t\tvalue := map[string]uint64{\"a\": math.MaxUint64}\n\t\ttestcases := AsXXXTestCases[map[string]uint64]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.FixStr + 1, 0x61},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int]string\", func(t *testing.T) {\n\t\tvalue := map[int]string{math.MinInt8: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[int]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int8, 0x80},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.Int8, 0x80, def.FixStr + 1, 0x61},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int]bool\", func(t *testing.T) {\n\t\tvalue := map[int]bool{math.MinInt8: true}\n\t\ttestcases := AsXXXTestCases[map[int]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int8, 0x80},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.Int8, 0x80, def.True},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint]string\", func(t *testing.T) {\n\t\tvalue := map[uint]string{math.MaxUint8: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[uint]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint8, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.Uint8, 0xff, def.FixStr + 1, 0x61},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint]bool\", func(t *testing.T) {\n\t\tvalue := map[uint]bool{math.MaxUint8: true}\n\t\ttestcases := AsXXXTestCases[map[uint]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint8, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.Uint8, 0xff, def.True},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[float32]string\", func(t *testing.T) {\n\t\tvalue := map[float32]string{1: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[float32]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Float32, 0x3f, 0x80, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Float32, 0x3f, 0x80, 0x00, 0x00,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[float32]bool\", func(t *testing.T) {\n\t\tvalue := map[float32]bool{1: true}\n\t\ttestcases := AsXXXTestCases[map[float32]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Float32, 0x3f, 0x80, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Float32, 0x3f, 0x80, 0x00, 0x00,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[float64]string\", func(t *testing.T) {\n\t\tvalue := map[float64]string{1: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[float64]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[float64]bool\", func(t *testing.T) {\n\t\tvalue := map[float64]bool{1: true}\n\t\ttestcases := AsXXXTestCases[map[float64]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Float64, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int8]string\", func(t *testing.T) {\n\t\tvalue := map[int8]string{math.MinInt8: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[int8]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int8, 0x80},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int8, 0x80,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int8]bool\", func(t *testing.T) {\n\t\tvalue := map[int8]bool{math.MinInt8: true}\n\t\ttestcases := AsXXXTestCases[map[int8]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int8, 0x80},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int8, 0x80,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int16]string\", func(t *testing.T) {\n\t\tvalue := map[int16]string{math.MinInt16: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[int16]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     4,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int16, 0x80, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int16, 0x80, 0x00,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int16]bool\", func(t *testing.T) {\n\t\tvalue := map[int16]bool{math.MinInt16: true}\n\t\ttestcases := AsXXXTestCases[map[int16]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     4,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int16, 0x80, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int16, 0x80, 0x00,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int32]string\", func(t *testing.T) {\n\t\tvalue := map[int32]string{math.MinInt32: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[int32]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int32, 0x80, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int32]bool\", func(t *testing.T) {\n\t\tvalue := map[int32]bool{math.MinInt32: true}\n\t\ttestcases := AsXXXTestCases[map[int32]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int32, 0x80, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int64]string\", func(t *testing.T) {\n\t\tvalue := map[int64]string{math.MinInt64: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[int64]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[int64]bool\", func(t *testing.T) {\n\t\tvalue := map[int64]bool{math.MinInt64: true}\n\t\ttestcases := AsXXXTestCases[map[int64]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\n\tt.Run(\"map[uint8]string\", func(t *testing.T) {\n\t\tvalue := map[uint8]string{math.MaxUint8: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[uint8]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint8, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint8, 0xff,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint8]bool\", func(t *testing.T) {\n\t\tvalue := map[uint8]bool{math.MaxUint8: true}\n\t\ttestcases := AsXXXTestCases[map[uint8]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     3,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint8, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint8, 0xff,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint16]string\", func(t *testing.T) {\n\t\tvalue := map[uint16]string{math.MaxUint16: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[uint16]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     4,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint16, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint16, 0xff, 0xff,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint16]bool\", func(t *testing.T) {\n\t\tvalue := map[uint16]bool{math.MaxUint16: true}\n\t\ttestcases := AsXXXTestCases[map[uint16]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     4,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint16, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint16, 0xff, 0xff,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint32]string\", func(t *testing.T) {\n\t\tvalue := map[uint32]string{math.MaxUint32: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[uint32]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint32, 0xff, 0xff, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint32]bool\", func(t *testing.T) {\n\t\tvalue := map[uint32]bool{math.MaxUint32: true}\n\t\ttestcases := AsXXXTestCases[map[uint32]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     6,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint32, 0xff, 0xff, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint64]string\", func(t *testing.T) {\n\t\tvalue := map[uint64]string{math.MaxUint64: \"a\"}\n\t\ttestcases := AsXXXTestCases[map[uint64]string]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.FixStr + 1, 0x61,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"map[uint64]bool\", func(t *testing.T) {\n\t\tvalue := map[uint64]bool{math.MaxUint64: true}\n\t\ttestcases := AsXXXTestCases[map[uint64]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error.key\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"error.value\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     10,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tContains:       []byte{def.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.True,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/encoding/nil.go",
    "content": "package encoding\n\nimport \"github.com/shamaton/msgpack/v3/def\"\n\nfunc (e *encoder) writeNil() error {\n\treturn e.setByte1Int(def.Nil)\n}\n"
  },
  {
    "path": "internal/stream/encoding/set.go",
    "content": "package encoding\n\nfunc (e *encoder) setByte1Int64(value int64) error {\n\treturn e.buf.Write(e.w, byte(value))\n}\n\nfunc (e *encoder) setByte2Int64(value int64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte4Int64(value int64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte8Int64(value int64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>56),\n\t\tbyte(value>>48),\n\t\tbyte(value>>40),\n\t\tbyte(value>>32),\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte1Uint64(value uint64) error {\n\treturn e.buf.Write(e.w, byte(value))\n}\n\nfunc (e *encoder) setByte2Uint64(value uint64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte4Uint64(value uint64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte8Uint64(value uint64) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>56),\n\t\tbyte(value>>48),\n\t\tbyte(value>>40),\n\t\tbyte(value>>32),\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte1Int(value int) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte2Int(value int) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setByte4Int(value int) error {\n\treturn e.buf.Write(e.w,\n\t\tbyte(value>>24),\n\t\tbyte(value>>16),\n\t\tbyte(value>>8),\n\t\tbyte(value),\n\t)\n}\n\nfunc (e *encoder) setBytes(bs []byte) error {\n\treturn e.buf.Write(e.w, bs...)\n}\n"
  },
  {
    "path": "internal/stream/encoding/slice.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeSliceLength(l int) error {\n\t// format size\n\tif l <= 0x0f {\n\t\tif err := e.setByte1Int(def.FixArray + l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Array16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if uint(l) <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Array32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) writeFixedSlice(rv reflect.Value) (bool, error) {\n\tswitch sli := rv.Interface().(type) {\n\tcase []int:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []uint:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []string:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeString(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []float32:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeFloat32(float64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []float64:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeFloat64(float64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []bool:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeBool(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []int8:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []int16:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []int32:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeInt(int64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []int64:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeInt(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []uint8:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []uint16:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []uint32:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeUint(uint64(v)); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\n\tcase []uint64:\n\t\tfor _, v := range sli {\n\t\t\tif err := e.writeUint(v); err != nil {\n\t\t\t\treturn false, err\n\t\t\t}\n\t\t}\n\t\treturn true, nil\n\t}\n\n\treturn false, nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/slice_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeSliceLength(t *testing.T) {\n\tmethod := func(e *encoder) func(int) error {\n\t\treturn e.writeSliceLength\n\t}\n\ttestcases := AsXXXTestCases[int]{\n\t\t{\n\t\t\tName:         \"FixArray.error\",\n\t\t\tValue:        5,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"FixArray.ok\",\n\t\t\tValue:      5,\n\t\t\tExpected:   []byte{def.FixArray + 5},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Array16.error.def\",\n\t\t\tValue:        32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Array16.error.value\",\n\t\t\tValue:        32,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Array16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Array16.ok\",\n\t\t\tValue:      32,\n\t\t\tExpected:   []byte{def.Array16, 0x00, 0x20},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Array32.error.def\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Array32.error.value\",\n\t\t\tValue:        65536,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Array32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Array32.ok\",\n\t\t\tValue:      65536,\n\t\t\tExpected:   []byte{def.Array32, 0x00, 0x01, 0x00, 0x00},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n\nfunc Test_writeFixedSlice(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) (bool, error) {\n\t\treturn e.writeFixedSlice\n\t}\n\n\tt.Run(\"[]int\", func(t *testing.T) {\n\t\tvalue := []int{-1, -2, -3}\n\t\ttestcases := AsXXXTestCases[[]int]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{0xff, 0xfe, 0xfd},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]uint\", func(t *testing.T) {\n\t\tvalue := []uint{1, 2, 3}\n\t\ttestcases := AsXXXTestCases[[]uint]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{0x01, 0x02, 0x03},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]string\", func(t *testing.T) {\n\t\tvalue := []string{\"a\", \"b\", \"c\"}\n\t\ttestcases := AsXXXTestCases[[]string]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{0xa1, 0x61, 0xa1, 0x62, 0xa1, 0x63},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]float32\", func(t *testing.T) {\n\t\tvalue := []float32{4, 5, 6}\n\t\ttestcases := AsXXXTestCases[[]float32]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.Float32, 0x40, 0x80, 0x00, 0x00, def.Float32, 0x40, 0xa0, 0x00, 0x00, def.Float32, 0x40, 0xc0, 0x00, 0x00},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]float64\", func(t *testing.T) {\n\t\tvalue := []float64{4, 5, 6}\n\t\ttestcases := AsXXXTestCases[[]float64]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Float64, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.Float64, 0x40, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.Float64, 0x40, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]bool\", func(t *testing.T) {\n\t\tvalue := []bool{true, false, true}\n\t\ttestcases := AsXXXTestCases[[]bool]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:           \"ok\",\n\t\t\t\tValue:          value,\n\t\t\t\tExpected:       []byte{def.True, def.False, def.True},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]int8\", func(t *testing.T) {\n\t\tvalue := []int8{math.MinInt8, math.MinInt8 + 1, math.MinInt8 + 2}\n\t\ttestcases := AsXXXTestCases[[]int8]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int8, 0x80,\n\t\t\t\t\tdef.Int8, 0x81,\n\t\t\t\t\tdef.Int8, 0x82,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]int16\", func(t *testing.T) {\n\t\tvalue := []int16{math.MinInt16, math.MinInt16 + 1, math.MinInt16 + 2}\n\t\ttestcases := AsXXXTestCases[[]int16]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int16, 0x80, 0x00,\n\t\t\t\t\tdef.Int16, 0x80, 0x01,\n\t\t\t\t\tdef.Int16, 0x80, 0x02,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]int32\", func(t *testing.T) {\n\t\tvalue := []int32{math.MinInt32, math.MinInt32 + 1, math.MinInt32 + 2}\n\t\ttestcases := AsXXXTestCases[[]int32]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x01,\n\t\t\t\t\tdef.Int32, 0x80, 0x00, 0x00, 0x02,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]int64\", func(t *testing.T) {\n\t\tvalue := []int64{math.MinInt64, math.MinInt64 + 1, math.MinInt64 + 2}\n\t\ttestcases := AsXXXTestCases[[]int64]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\n\t\t\t\t\tdef.Int64, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]uint8\", func(t *testing.T) {\n\t\tvalue := []uint8{math.MaxUint8, math.MaxUint8 - 1, math.MaxUint8 - 2}\n\t\ttestcases := AsXXXTestCases[[]uint8]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint8, 0xff,\n\t\t\t\t\tdef.Uint8, 0xfe,\n\t\t\t\t\tdef.Uint8, 0xfd,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]uint16\", func(t *testing.T) {\n\t\tvalue := []uint16{math.MaxUint16, math.MaxUint16 - 1, math.MaxUint16 - 2}\n\t\ttestcases := AsXXXTestCases[[]uint16]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint16, 0xff, 0xff,\n\t\t\t\t\tdef.Uint16, 0xff, 0xfe,\n\t\t\t\t\tdef.Uint16, 0xff, 0xfd,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]uint32\", func(t *testing.T) {\n\t\tvalue := []uint32{math.MaxUint32, math.MaxUint32 - 1, math.MaxUint32 - 2}\n\t\ttestcases := AsXXXTestCases[[]uint32]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xfe,\n\t\t\t\t\tdef.Uint32, 0xff, 0xff, 0xff, 0xfd,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"[]uint64\", func(t *testing.T) {\n\t\tvalue := []uint64{math.MaxUint64, math.MaxUint64 - 1, math.MaxUint64 - 2}\n\t\ttestcases := AsXXXTestCases[[]uint64]{\n\t\t\t{\n\t\t\t\tName:           \"error\",\n\t\t\t\tValue:          value,\n\t\t\t\tBufferSize:     1,\n\t\t\t\tPreWriteSize:   1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,\n\t\t\t\t\tdef.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd,\n\t\t\t\t},\n\t\t\t\tBufferSize:     1,\n\t\t\t\tMethodForFixed: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/encoding/string.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"unsafe\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeString(str string) error {\n\t// NOTE : unsafe\n\tstrBytes := *(*[]byte)(unsafe.Pointer(&str))\n\tl := len(strBytes)\n\tif l < 32 {\n\t\tif err := e.setByte1Int(def.FixStr + l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint8 {\n\t\tif err := e.setByte1Int(def.Str8); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte1Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Str16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := e.setByte1Int(def.Str32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn e.setBytes(strBytes)\n}\n"
  },
  {
    "path": "internal/stream/encoding/string_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_writeString(t *testing.T) {\n\tmethod := func(e *encoder) func(string) error {\n\t\treturn e.writeString\n\t}\n\tstr8 := strings.Repeat(\"a\", math.MaxUint8)\n\tstr16 := strings.Repeat(\"a\", math.MaxUint16)\n\tstr32 := strings.Repeat(\"a\", math.MaxUint16+1)\n\ttestcases := AsXXXTestCases[string]{\n\t\t{\n\t\t\tName:         \"Str8.error.def\",\n\t\t\tValue:        str8,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str8.error.length\",\n\t\t\tValue:        str8,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str8},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str8.error.string\",\n\t\t\tValue:        str8,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str8, 0xff},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:  \"Str8.ok\",\n\t\t\tValue: str8,\n\t\t\tExpected: append(\n\t\t\t\t[]byte{def.Str8, 0xff},\n\t\t\t\t[]byte(str8)...,\n\t\t\t),\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str16.error.def\",\n\t\t\tValue:        str16,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str16.error.length\",\n\t\t\tValue:        str16,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str16.error.string\",\n\t\t\tValue:        str16,\n\t\t\tBufferSize:   4,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str16, 0xff, 0xff},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:  \"Str16.ok\",\n\t\t\tValue: str16,\n\t\t\tExpected: append(\n\t\t\t\t[]byte{def.Str16, 0xff, 0xff},\n\t\t\t\t[]byte(str16)...,\n\t\t\t),\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str32.error.def\",\n\t\t\tValue:        str32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str32.error.length\",\n\t\t\tValue:        str32,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Str32.error.string\",\n\t\t\tValue:        str32,\n\t\t\tBufferSize:   6,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Str32, 0x00, 0x01, 0x00, 0x00},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:  \"Str32.ok\",\n\t\t\tValue: str32,\n\t\t\tExpected: append(\n\t\t\t\t[]byte{def.Str32, 0x00, 0x01, 0x00, 0x00},\n\t\t\t\t[]byte(str32)...,\n\t\t\t),\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "internal/stream/encoding/struct.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"sync\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n)\n\ntype structCache struct {\n\t// common fields\n\tnames  []string\n\tomits  []bool\n\tnoOmit bool\n\n\t// fast path detection\n\thasEmbedded bool\n\n\t// fast path (hasEmbedded == false): direct field access\n\tsimpleIndexes []int\n\n\t// embedded path (hasEmbedded == true): path-based access\n\tindexes   [][]int   // field path (support for embedded structs)\n\tomitPaths [][][]int // embedded omitempty parent paths\n\n\tcommon.Common\n}\n\nvar cachemap = sync.Map{}\n\ntype structWriteFunc func(rv reflect.Value) error\n\n// getFieldByPath returns the field value by following the path of indices.\n// The bool indicates whether the path was reachable (no nil pointer in the path).\nfunc getFieldByPath(rv reflect.Value, path []int) (reflect.Value, bool) {\n\tfor _, idx := range path {\n\t\t// Handle pointer indirection if needed\n\t\tif rv.Kind() == reflect.Ptr {\n\t\t\tif rv.IsNil() {\n\t\t\t\t// Return invalid value if pointer is nil\n\t\t\t\treturn reflect.Value{}, false\n\t\t\t}\n\t\t\trv = rv.Elem()\n\t\t}\n\t\trv = rv.Field(idx)\n\t}\n\treturn rv, true\n}\n\nfunc shouldOmitByParent(rv reflect.Value, omitPaths [][]int) bool {\n\tfor _, path := range omitPaths {\n\t\tparentValue, ok := getFieldByPath(rv, path)\n\t\tif !ok || parentValue.IsZero() {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (e *encoder) getStructWriter(typ reflect.Type) structWriteFunc {\n\tfor i := range extCoders {\n\t\tif extCoders[i].Type() == typ {\n\t\t\treturn func(rv reflect.Value) error {\n\t\t\t\tw := ext.CreateStreamWriter(e.w, e.buf)\n\t\t\t\treturn extCoders[i].Write(w, rv)\n\t\t\t}\n\t\t}\n\t}\n\n\tif e.asArray {\n\t\treturn e.writeStructArray\n\t}\n\treturn e.writeStructMap\n}\n\nfunc (e *encoder) writeStruct(rv reflect.Value) error {\n\tfor i := range extCoders {\n\t\tif extCoders[i].Type() == rv.Type() {\n\t\t\tw := ext.CreateStreamWriter(e.w, e.buf)\n\t\t\treturn extCoders[i].Write(w, rv)\n\t\t}\n\t}\n\n\tif e.asArray {\n\t\treturn e.writeStructArray(rv)\n\t}\n\treturn e.writeStructMap(rv)\n}\n\nfunc (e *encoder) writeStructArray(rv reflect.Value) error {\n\tc := e.getStructCache(rv)\n\n\t// write format\n\tvar num int\n\tif c.hasEmbedded {\n\t\tnum = len(c.indexes)\n\t} else {\n\t\tnum = len(c.simpleIndexes)\n\t}\n\n\tif num <= 0x0f {\n\t\tif err := e.setByte1Int(def.FixArray + num); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if num <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Array16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(num); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if uint(num) <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Array32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(num); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif c.hasEmbedded {\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tfieldValue = reflect.Value{}\n\t\t\t}\n\t\t\tif err := e.create(fieldValue); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor i := 0; i < num; i++ {\n\t\t\tif err := e.create(rv.Field(c.simpleIndexes[i])); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) writeStructMap(rv reflect.Value) error {\n\tc := e.getStructCache(rv)\n\n\tl := 0\n\tif c.hasEmbedded {\n\t\tnum := len(c.indexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnum := len(c.simpleIndexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tif c.noOmit || !c.omits[i] || !rv.Field(c.simpleIndexes[i]).IsZero() {\n\t\t\t\tl++\n\t\t\t}\n\t\t}\n\t}\n\n\t// format size\n\tif l <= 0x0f {\n\t\tif err := e.setByte1Int(def.FixMap + l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if l <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Map16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if uint(l) <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Map32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Int(l); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\n\tif c.hasEmbedded {\n\t\tnum := len(c.indexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue, ok := getFieldByPath(rv, c.indexes[i])\n\t\t\tif shouldOmitByParent(rv, c.omitPaths[i]) || !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\tif err := e.writeString(c.names[i]); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := e.create(fieldValue); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnum := len(c.simpleIndexes)\n\t\tfor i := 0; i < num; i++ {\n\t\t\tfieldValue := rv.Field(c.simpleIndexes[i])\n\t\t\tif c.noOmit || !c.omits[i] || !fieldValue.IsZero() {\n\t\t\t\tif err := e.writeString(c.names[i]); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t\tif err := e.create(fieldValue); err != nil {\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (e *encoder) getStructCache(rv reflect.Value) *structCache {\n\tt := rv.Type()\n\tcache, find := cachemap.Load(t)\n\tif find {\n\t\treturn cache.(*structCache)\n\t}\n\n\tc := &structCache{}\n\tfields := e.CollectFields(t, nil)\n\n\t// detect embedded fields\n\thasEmbedded := false\n\tfor _, f := range fields {\n\t\tif len(f.Path) > 1 || len(f.OmitPaths) > 0 {\n\t\t\thasEmbedded = true\n\t\t\tbreak\n\t\t}\n\t}\n\tc.hasEmbedded = hasEmbedded\n\n\tomitCount := 0\n\tfor _, field := range fields {\n\t\tc.names = append(c.names, field.Name)\n\t\tc.omits = append(c.omits, field.Omit)\n\t\tif hasEmbedded {\n\t\t\tc.indexes = append(c.indexes, field.Path)\n\t\t\tc.omitPaths = append(c.omitPaths, field.OmitPaths)\n\t\t} else {\n\t\t\tc.simpleIndexes = append(c.simpleIndexes, field.Path[0])\n\t\t}\n\t\tif field.Omit {\n\t\t\tomitCount++\n\t\t}\n\t}\n\tc.noOmit = omitCount == 0\n\tcachemap.Store(t, c)\n\treturn c\n}\n"
  },
  {
    "path": "internal/stream/encoding/struct_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc Test_writeStruct(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) error {\n\t\treturn e.writeStruct\n\t}\n\n\tt.Run(\"Ext\", func(t *testing.T) {\n\t\tvalue := time.Time{}\n\t\ttestcases := AsXXXTestCases[time.Time]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:  \"ok\",\n\t\t\t\tValue: value,\n\t\t\t\tExpected: []byte{\n\t\t\t\t\tdef.Ext8,\n\t\t\t\t\t12, 0xff,\n\t\t\t\t\t0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xf1, 0x88, 0x6e, 0x09, 0x00,\n\t\t\t\t},\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Array\", func(t *testing.T) {\n\t\tst, _, b := tu.CreateStruct(1)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tAsArray:         true,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.FixArray + 1}, b...),\n\t\t\t\tAsArray:         true,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Map\", func(t *testing.T) {\n\t\tst, b, _ := tu.CreateStruct(1)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tAsArray:         false,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.FixMap + 1}, b...),\n\t\t\t\tAsArray:         false,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n\nfunc Test_writeStructArray(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) error {\n\t\treturn e.writeStructArray\n\t}\n\n\tt.Run(\"FixArray\", func(t *testing.T) {\n\t\tst, _, b := tu.CreateStruct(0x0f)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.FixArray + byte(0x0f)},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.FixArray + byte(0x0f)}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Array16\", func(t *testing.T) {\n\t\tst, _, b := tu.CreateStruct(math.MaxUint16)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.num\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Array16},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      4,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Array16, 0xff, 0xff},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.Array16, 0xff, 0xff}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Array32\", func(t *testing.T) {\n\t\tst, _, b := tu.CreateStruct(math.MaxUint16 + 1)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.num\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Array32},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      6,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Array32, 0x00, 0x01, 0x00, 0x00},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.Array32, 0x00, 0x01, 0x00, 0x00}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n\nfunc Test_writeStructMap(t *testing.T) {\n\tmethod := func(e *encoder) func(reflect.Value) error {\n\t\treturn e.writeStructMap\n\t}\n\n\tt.Run(\"FixMap\", func(t *testing.T) {\n\t\tst, b, _ := tu.CreateStruct(0x0f)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.key\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.FixMap + byte(0x0f)},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      5,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        append([]byte{def.FixMap + byte(0x0f)}, b[:3]...),\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.FixMap + byte(0x0f)}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Map16\", func(t *testing.T) {\n\t\tst, b, _ := tu.CreateStruct(math.MaxUint16)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.num\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Map16},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.key\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      4,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Map16, 0xff, 0xff},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      7,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        append([]byte{def.Map16, 0xff, 0xff}, b[:3]...),\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.Map16, 0xff, 0xff}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n\tt.Run(\"Map32\", func(t *testing.T) {\n\t\tst, b, _ := tu.CreateStruct(math.MaxUint16 + 1)\n\t\tvalue := reflect.ValueOf(st).Elem().Interface()\n\t\ttestcases := AsXXXTestCases[any]{\n\t\t\t{\n\t\t\t\tName:            \"error.def\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      1,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.num\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      2,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Map32},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.key\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      6,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        []byte{def.Map32, 0x00, 0x01, 0x00, 0x00},\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"error.value\",\n\t\t\t\tValue:           value,\n\t\t\t\tBufferSize:      9,\n\t\t\t\tPreWriteSize:    1,\n\t\t\t\tContains:        append([]byte{def.Map32, 0x00, 0x01, 0x00, 0x00}, b[:3]...),\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t\t{\n\t\t\t\tName:            \"ok\",\n\t\t\t\tValue:           value,\n\t\t\t\tExpected:        append([]byte{def.Map32, 0x00, 0x01, 0x00, 0x00}, b...),\n\t\t\t\tBufferSize:      1,\n\t\t\t\tMethodForStruct: method,\n\t\t\t},\n\t\t}\n\t\ttestcases.Run(t)\n\t})\n}\n"
  },
  {
    "path": "internal/stream/encoding/uint.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc (e *encoder) writeUint(v uint64) error {\n\tif v <= math.MaxInt8 {\n\t\tif err := e.setByte1Uint64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v <= math.MaxUint8 {\n\t\tif err := e.setByte1Int(def.Uint8); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte1Uint64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v <= math.MaxUint16 {\n\t\tif err := e.setByte1Int(def.Uint16); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte2Uint64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else if v <= math.MaxUint32 {\n\t\tif err := e.setByte1Int(def.Uint32); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte4Uint64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t} else {\n\t\tif err := e.setByte1Int(def.Uint64); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := e.setByte8Uint64(v); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/stream/encoding/uint_test.go",
    "content": "package encoding\n\nimport (\n\t\"math\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc Test_asUint(t *testing.T) {\n\tmethod := func(e *encoder) func(uint64) error {\n\t\treturn e.writeUint\n\t}\n\ttestcases := AsXXXTestCases[uint64]{\n\t\t{\n\t\t\tName:         \"PositiveFix.error\",\n\t\t\tValue:        math.MaxInt8,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"PositiveFix.ok\",\n\t\t\tValue:      math.MaxInt8,\n\t\t\tExpected:   []byte{0x7f},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint8.error.def\",\n\t\t\tValue:        math.MaxUint8,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint8.error.value\",\n\t\t\tValue:        math.MaxUint8,\n\t\t\tBufferSize:   2,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Uint8},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Uint8.ok\",\n\t\t\tValue:      math.MaxUint8,\n\t\t\tExpected:   []byte{def.Uint8, 0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint16.error.def\",\n\t\t\tValue:        math.MaxUint16,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint16.error.value\",\n\t\t\tValue:        math.MaxUint16,\n\t\t\tBufferSize:   3,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Uint16},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Uint16.ok\",\n\t\t\tValue:      math.MaxUint16,\n\t\t\tExpected:   []byte{def.Uint16, 0xff, 0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint32.error.def\",\n\t\t\tValue:        math.MaxUint32,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint32.error.value\",\n\t\t\tValue:        math.MaxUint32,\n\t\t\tBufferSize:   5,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Uint32},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Uint32.ok\",\n\t\t\tValue:      math.MaxUint32,\n\t\t\tExpected:   []byte{def.Uint32, 0xff, 0xff, 0xff, 0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint64.error.def\",\n\t\t\tValue:        math.MaxUint64,\n\t\t\tBufferSize:   1,\n\t\t\tPreWriteSize: 1,\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:         \"Uint64.error.value\",\n\t\t\tValue:        math.MaxUint64,\n\t\t\tBufferSize:   9,\n\t\t\tPreWriteSize: 1,\n\t\t\tContains:     []byte{def.Uint64},\n\t\t\tMethod:       method,\n\t\t},\n\t\t{\n\t\t\tName:       \"Uint64.ok\",\n\t\t\tValue:      math.MaxUint64,\n\t\t\tExpected:   []byte{def.Uint64, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},\n\t\t\tBufferSize: 1,\n\t\t\tMethod:     method,\n\t\t},\n\t}\n\ttestcases.Run(t)\n}\n"
  },
  {
    "path": "msgpack.go",
    "content": "package msgpack\n\nimport (\n\t\"fmt\"\n\t\"io\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/internal/decoding\"\n\t\"github.com/shamaton/msgpack/v3/internal/encoding\"\n\tstreamdecoding \"github.com/shamaton/msgpack/v3/internal/stream/decoding\"\n\tstreamencoding \"github.com/shamaton/msgpack/v3/internal/stream/encoding\"\n\t\"github.com/shamaton/msgpack/v3/time\"\n)\n\n// StructAsArray is encoding option.\n// If this option sets true, default encoding sets to array-format.\nvar StructAsArray = false\n\n// Marshal returns the MessagePack-encoded byte array of v.\nfunc Marshal(v interface{}) ([]byte, error) {\n\treturn encoding.Encode(v, StructAsArray)\n}\n\n// MarshalWrite writes MessagePack-encoded byte array of v to writer.\nfunc MarshalWrite(w io.Writer, v interface{}) error {\n\treturn streamencoding.Encode(w, v, StructAsArray)\n}\n\n// Unmarshal analyzes the MessagePack-encoded data and stores\n// the result into the pointer of v.\nfunc Unmarshal(data []byte, v interface{}) error {\n\treturn decoding.Decode(data, v, StructAsArray)\n}\n\n// UnmarshalRead reads the MessagePack-encoded data from reader and stores\n// the result into the pointer of v.\nfunc UnmarshalRead(r io.Reader, v interface{}) error {\n\treturn streamdecoding.Decode(r, v, StructAsArray)\n}\n\n// AddExtCoder adds encoders for extension types.\nfunc AddExtCoder(e ext.Encoder, d ext.Decoder) error {\n\tif e.Code() != d.Code() {\n\t\treturn fmt.Errorf(\"code different %d:%d\", e.Code(), d.Code())\n\t}\n\tencoding.AddExtEncoder(e)\n\tdecoding.AddExtDecoder(d)\n\treturn nil\n}\n\n// AddExtStreamCoder adds stream encoders for extension types.\nfunc AddExtStreamCoder(e ext.StreamEncoder, d ext.StreamDecoder) error {\n\tif e.Code() != d.Code() {\n\t\treturn fmt.Errorf(\"code different %d:%d\", e.Code(), d.Code())\n\t}\n\tstreamencoding.AddExtEncoder(e)\n\tstreamdecoding.AddExtDecoder(d)\n\treturn nil\n}\n\n// RemoveExtCoder removes encoders for extension types.\nfunc RemoveExtCoder(e ext.Encoder, d ext.Decoder) error {\n\tif e.Code() != d.Code() {\n\t\treturn fmt.Errorf(\"code different %d:%d\", e.Code(), d.Code())\n\t}\n\tencoding.RemoveExtEncoder(e)\n\tdecoding.RemoveExtDecoder(d)\n\treturn nil\n}\n\n// RemoveExtStreamCoder removes stream encoders for extension types.\nfunc RemoveExtStreamCoder(e ext.StreamEncoder, d ext.StreamDecoder) error {\n\tif e.Code() != d.Code() {\n\t\treturn fmt.Errorf(\"code different %d:%d\", e.Code(), d.Code())\n\t}\n\tstreamencoding.RemoveExtEncoder(e)\n\tstreamdecoding.RemoveExtDecoder(d)\n\treturn nil\n}\n\n// SetComplexTypeCode sets def.complexTypeCode\nfunc SetComplexTypeCode(code int8) {\n\tdef.SetComplexTypeCode(code)\n}\n\n// SetDecodedTimeAsUTC sets decoded time.Time values to UTC timezone.\nfunc SetDecodedTimeAsUTC() {\n\ttime.SetDecodedAsLocal(false)\n}\n\n// SetDecodedTimeAsLocal sets decoded time.Time values to local timezone.\nfunc SetDecodedTimeAsLocal() {\n\ttime.SetDecodedAsLocal(true)\n}\n"
  },
  {
    "path": "msgpack_example_test.go",
    "content": "package msgpack_test\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"net\"\n\t\"reflect\"\n\n\t\"github.com/shamaton/msgpack/v3\"\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nfunc ExampleAddExtCoder() {\n\terr := msgpack.AddExtCoder(&IPNetEncoder{}, &IPNetDecoder{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tv1 := net.IPNet{IP: net.IP{127, 0, 0, 1}, Mask: net.IPMask{255, 255, 255, 0}}\n\tr1, err := msgpack.Marshal(v1)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Printf(\"encode: % 02x\\n\", r1)\n\n\tvar v2 net.IPNet\n\terr = msgpack.Unmarshal(r1, &v2)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"decode:\", v2)\n\n\t// Output:\n\t// encode: c7 0c 32 31 32 37 2e 30 2e 30 2e 31 2f 32 34\n\t// decode: {127.0.0.0 ffffff00}\n}\n\nfunc ExampleAddExtStreamCoder() {\n\terr := msgpack.AddExtStreamCoder(&IPNetStreamEncoder{}, &IPNetStreamDecoder{})\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\n\tv1 := net.IPNet{IP: net.IP{127, 0, 0, 1}, Mask: net.IPMask{255, 255, 255, 0}}\n\n\tbuf := bytes.Buffer{}\n\terr = msgpack.MarshalWrite(&buf, v1)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Printf(\"encode: % 02x\\n\", buf.Bytes())\n\n\tvar v2 net.IPNet\n\terr = msgpack.UnmarshalRead(&buf, &v2)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tfmt.Println(\"decode:\", v2)\n\n\t// Output:\n\t// encode: c7 0c 32 31 32 37 2e 30 2e 30 2e 31 2f 32 34\n\t// decode: {127.0.0.0 ffffff00}\n}\n\nconst ipNetCode = 50\n\ntype IPNetDecoder struct {\n\text.DecoderCommon\n}\n\nvar _ ext.Decoder = (*IPNetDecoder)(nil)\n\nfunc (td *IPNetDecoder) Code() int8 {\n\treturn ipNetCode\n}\n\nfunc (td *IPNetDecoder) IsType(offset int, d *[]byte) bool {\n\tcode, offset := td.ReadSize1(offset, d)\n\tif code == def.Ext8 {\n\t\t_, offset = td.ReadSize1(offset, d)\n\t\tt, _ := td.ReadSize1(offset, d)\n\t\treturn int8(t) == td.Code()\n\t}\n\treturn false\n}\n\nfunc (td *IPNetDecoder) AsValue(offset int, k reflect.Kind, d *[]byte) (any, int, error) {\n\tcode, offset := td.ReadSize1(offset, d)\n\n\tswitch code {\n\tcase def.Ext8:\n\t\t// size\n\t\tsize, offset := td.ReadSize1(offset, d)\n\t\t// code\n\t\t_, offset = td.ReadSize1(offset, d)\n\t\t// value\n\t\tdata, offset := td.ReadSizeN(offset, int(size), d)\n\n\t\t_, v, err := net.ParseCIDR(string(data))\n\t\tif err != nil {\n\t\t\treturn net.IPNet{}, 0, fmt.Errorf(\"failed to parse CIDR: %w\", err)\n\t\t}\n\t\tif v == nil {\n\t\t\treturn net.IPNet{}, 0, fmt.Errorf(\"parsed CIDR is nil\")\n\t\t}\n\t\treturn *v, offset, nil\n\t}\n\treturn net.IPNet{}, 0, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", td.Code(), k)\n}\n\ntype IPNetStreamDecoder struct{}\n\nvar _ ext.StreamDecoder = (*IPNetStreamDecoder)(nil)\n\nfunc (td *IPNetStreamDecoder) Code() int8 {\n\treturn ipNetCode\n}\n\nfunc (td *IPNetStreamDecoder) IsType(code byte, innerType int8, _ int) bool {\n\treturn code == def.Ext8 && innerType == td.Code()\n}\n\nfunc (td *IPNetStreamDecoder) ToValue(code byte, data []byte, k reflect.Kind) (any, error) {\n\tif code == def.Ext8 {\n\t\t_, v, err := net.ParseCIDR(string(data))\n\t\tif err != nil {\n\t\t\treturn net.IPNet{}, fmt.Errorf(\"failed to parse CIDR: %w\", err)\n\t\t}\n\t\tif v == nil {\n\t\t\treturn net.IPNet{}, fmt.Errorf(\"parsed CIDR is nil\")\n\t\t}\n\t\treturn *v, nil\n\t}\n\treturn net.IPNet{}, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", td.Code(), k)\n}\n\ntype IPNetEncoder struct {\n\text.EncoderCommon\n}\n\nvar _ ext.Encoder = (*IPNetEncoder)(nil)\n\nfunc (s *IPNetEncoder) Code() int8 {\n\treturn ipNetCode\n}\n\nfunc (s *IPNetEncoder) Type() reflect.Type {\n\treturn reflect.TypeOf(net.IPNet{})\n}\n\nfunc (s *IPNetEncoder) CalcByteSize(value reflect.Value) (int, error) {\n\tv := value.Interface().(net.IPNet)\n\treturn def.Byte1 + def.Byte1 + def.Byte1 + len(v.String()), nil\n}\n\nfunc (s *IPNetEncoder) WriteToBytes(value reflect.Value, offset int, bytes *[]byte) int {\n\tv := value.Interface().(net.IPNet)\n\tdata := v.String()\n\n\toffset = s.SetByte1Int(def.Ext8, offset, bytes)\n\toffset = s.SetByte1Int(len(data), offset, bytes)\n\toffset = s.SetByte1Int(int(s.Code()), offset, bytes)\n\toffset = s.SetBytes([]byte(data), offset, bytes)\n\treturn offset\n}\n\ntype IPNetStreamEncoder struct{}\n\nvar _ ext.StreamEncoder = (*IPNetStreamEncoder)(nil)\n\nfunc (s *IPNetStreamEncoder) Code() int8 {\n\treturn ipNetCode\n}\n\nfunc (s *IPNetStreamEncoder) Type() reflect.Type {\n\treturn reflect.TypeOf(net.IPNet{})\n}\n\nfunc (s *IPNetStreamEncoder) Write(w ext.StreamWriter, value reflect.Value) error {\n\tv := value.Interface().(net.IPNet)\n\tdata := v.String()\n\n\tif err := w.WriteByte1Int(def.Ext8); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(len(data)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(int(s.Code())); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteBytes([]byte(data)); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n"
  },
  {
    "path": "msgpack_test.go",
    "content": "package msgpack_test\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"encoding/hex\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n\t\"math/rand\"\n\t\"reflect\"\n\t\"slices\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3\"\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n\textTime \"github.com/shamaton/msgpack/v3/time\"\n)\n\nvar now time.Time\n\nfunc init() {\n\tn := time.Now()\n\tnow = time.Unix(n.Unix(), int64(n.Nanosecond())).UTC()\n}\n\nfunc TestInt(t *testing.T) {\n\t{\n\t\targs := []encdecArg[int]{\n\t\t\t{\n\t\t\t\tn: \"FixInt\",\n\t\t\t\tv: -8,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.NegativeFixintMin <= int8(d[0]) && int8(d[0]) <= def.NegativeFixintMax\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Int8\",\n\t\t\t\tv: -108,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Int8\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Int16\",\n\t\t\t\tv: -30108,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Int16\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Int32\",\n\t\t\t\tv: -1030108,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Int32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t}\n\t{\n\t\targ := encdecArg[int64]{\n\t\t\tn: \"Int64\",\n\t\t\tv: int64(math.MinInt64 + 12345),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Int64\n\t\t\t},\n\t\t}\n\t\tencdec(t, arg)\n\t}\n\n\t// error\n\t{\n\t\targ := encdecArg[uint8]{\n\t\t\tn: \"ErrorDecToUint8\",\n\t\t\tv: -8,\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn def.NegativeFixintMin <= int8(d[0]) && int8(d[0]) <= def.NegativeFixintMax\n\t\t\t},\n\t\t\te: \"value different\",\n\t\t}\n\t\tencdec(t, arg)\n\t}\n\t{\n\t\targ := encdecArg[int32]{\n\t\t\tn: \"ErrorDecToInt32\",\n\t\t\tv: int64(math.MinInt64 + 12345),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Int64\n\t\t\t},\n\t\t\te: \"value different\",\n\t\t}\n\t\tencdec(t, arg)\n\t}\n}\n\nfunc TestUint(t *testing.T) {\n\t{\n\t\targs := []encdecArg[uint]{\n\t\t\t{\n\t\t\t\tn: \"FixUint\",\n\t\t\t\tv: uint(8),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.PositiveFixIntMin <= uint8(d[0]) && uint8(d[0]) <= def.PositiveFixIntMax\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Uint8\",\n\t\t\t\tv: uint(130),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Uint8\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Uint16\",\n\t\t\t\tv: uint(30130),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Uint16\n\t\t\t\t},\n\t\t\t}, {\n\t\t\t\tn: \"Uint32\",\n\t\t\t\tv: uint(1030130),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Uint32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t}\n\t{\n\t\targ := encdecArg[uint64]{\n\t\t\tn: \"Uint64\",\n\t\t\tv: uint64(math.MaxUint64 - 12345),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Uint64\n\t\t\t},\n\t\t}\n\t\tencdec(t, arg)\n\t}\n}\n\nfunc TestFloat(t *testing.T) {\n\tt.Run(\"Float32\", func(t *testing.T) {\n\t\tc := func(d []byte) bool {\n\t\t\treturn d[0] == def.Float32\n\t\t}\n\t\targs := []encdecArg[float32]{{\n\t\t\tn: \"0\",\n\t\t\tv: float32(0),\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"-1\",\n\t\t\tv: float32(-1),\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"SmallestNonzeroFloat\",\n\t\t\tv: float32(math.SmallestNonzeroFloat32),\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"MaxFloat\",\n\t\t\tv: float32(math.MaxFloat32),\n\t\t\tc: c,\n\t\t}}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"Float64\", func(t *testing.T) {\n\t\tc := func(d []byte) bool {\n\t\t\treturn d[0] == def.Float64\n\t\t}\n\t\targs := []encdecArg[float64]{{\n\t\t\tn: \"0\",\n\t\t\tv: float64(0),\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"-1\",\n\t\t\tv: float64(-1),\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"SmallestNonzeroFloat\",\n\t\t\tv: math.SmallestNonzeroFloat64,\n\t\t\tc: c,\n\t\t}, {\n\t\t\tn: \"MaxFloat\",\n\t\t\tv: math.MaxFloat64,\n\t\t\tc: c,\n\t\t}}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"FloatToInt\", func(t *testing.T) {\n\t\targs := []encdecArg[int]{\n\t\t\t{\n\t\t\t\tn: \"FromFloat32\",\n\t\t\t\tv: float32(2.345),\n\t\t\t\tvc: func(v int) error {\n\t\t\t\t\tif v != 2 {\n\t\t\t\t\t\treturn fmt.Errorf(\"different value: %d\", v)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"FromFloat64\",\n\t\t\t\tv: float64(6.789),\n\t\t\t\tvc: func(v int) error {\n\t\t\t\t\tif v != 6 {\n\t\t\t\t\t\treturn fmt.Errorf(\"different value: %d\", v)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// error\n\tt.Run(\"Float32ToFloat64\", func(t *testing.T) {\n\t\targ := encdecArg[float64]{\n\t\t\tn: \"NotEqual\",\n\t\t\tv: float32(math.MaxFloat32),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Float32\n\t\t\t},\n\t\t\te: \"value different\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n\tt.Run(\"Float64ToFloat32\", func(t *testing.T) {\n\t\targ := encdecArg[float32]{\n\t\t\tn: \"ErrorDecToFloat32\",\n\t\t\tv: math.MaxFloat64,\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Float64\n\t\t\t},\n\t\t\te: \"invalid code cb decoding\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n\tt.Run(\"Float64ToString\", func(t *testing.T) {\n\t\targ := encdecArg[string]{\n\t\t\tn: \"ErrorDecToString\",\n\t\t\tv: math.MaxFloat64,\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Float64\n\t\t\t},\n\t\t\te: \"invalid code cb decoding\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n}\n\nfunc TestBool(t *testing.T) {\n\tt.Run(\"Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[bool]{\n\t\t\t{\n\t\t\t\tn: \"True\",\n\t\t\t\tv: true,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.True\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"False\",\n\t\t\t\tv: false,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.False\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// error\n\tt.Run(\"BoolToUint8\", func(t *testing.T) {\n\t\targ := encdecArg[uint8]{\n\t\t\tn: \"ErrorDecToUint8\",\n\t\t\tv: true,\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.True\n\t\t\t},\n\t\t\te: \"invalid code c3 decoding\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n}\n\nfunc TestNil(t *testing.T) {\n\tt.Run(\"Nil\", func(t *testing.T) {\n\t\targs := []encdecArg[*map[any]any]{\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: nil,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t\tvc: func(v *map[any]any) error {\n\t\t\t\t\tif v != nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"not nil: %v\", v)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestString(t *testing.T) {\n\t// len 31\n\tconst base = \"abcdefghijklmnopqrstuvwxyz12345\"\n\n\tt.Run(\"String\", func(t *testing.T) {\n\t\targs := []encdecArg[string]{\n\t\t\t{\n\t\t\t\tn: \"EmptyString\",\n\t\t\t\tv: \"\",\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixStr <= d[0] && d[0] < def.FixStr+32\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"FixStr\",\n\t\t\t\tv: strings.Repeat(base, 1),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixStr <= d[0] && d[0] < def.FixStr+32\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Str8\",\n\t\t\t\tv: strings.Repeat(base, 8),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Str8\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Str16\",\n\t\t\t\tv: strings.Repeat(base, (math.MaxUint16/len(base))-1),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Str16\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Str32\",\n\t\t\t\tv: strings.Repeat(base, (math.MaxUint16/len(base))+1),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Str32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// type different\n\tt.Run(\"StringToBytes\", func(t *testing.T) {\n\t\targ := encdecArg[[]byte]{\n\t\t\tn: \"TypeDifferentButSameValue\",\n\t\t\tv: strings.Repeat(base, 8),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Str8\n\t\t\t},\n\t\t\te: \"value different\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n\tt.Run(\"BytesToString\", func(t *testing.T) {\n\t\targ := encdecArg[string]{\n\t\t\tn: \"TypeDifferentButSameValue\",\n\t\t\tv: []byte(base),\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.Bin8\n\t\t\t},\n\t\t\te: \"value different\",\n\t\t}\n\t\tencdec(t, arg)\n\t})\n}\n\nfunc TestComplex(t *testing.T) {\n\tt.Run(\"Complex64\", func(t *testing.T) {\n\t\targs := []encdecArg[complex64]{\n\t\t\t{\n\t\t\t\tn: \"To64\",\n\t\t\t\tv: complex64(complex(1, 2)),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext8 && int8(d[1]) == def.ComplexTypeCode()\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: nil,\n\t\t\t\te: \"invalid code c0 decoding\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\n\t\targs2 := []encdecArg[complex128]{\n\t\t\t{\n\t\t\t\tn: \"To128\",\n\t\t\t\tv: complex64(complex(1, 2)),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext8 && int8(d[1]) == def.ComplexTypeCode()\n\t\t\t\t},\n\t\t\t\tvc: func(t complex128) error {\n\t\t\t\t\tif imag(t) == 0 || real(t) == 0 {\n\t\t\t\t\t\treturn fmt.Errorf(\"somthing wrong %v\", t)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args2...)\n\t})\n\n\tt.Run(\"Complex128\", func(t *testing.T) {\n\t\targs := []encdecArg[complex128]{\n\t\t\t{\n\t\t\t\tn: \"To128\",\n\t\t\t\tv: complex(math.MaxFloat64, math.SmallestNonzeroFloat64),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext16 && int8(d[1]) == def.ComplexTypeCode()\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: nil,\n\t\t\t\te: \"invalid code c0 decoding\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\n\t\targs2 := []encdecArg[complex64]{\n\t\t\t{\n\t\t\t\tn: \"To64\",\n\t\t\t\tv: complex(math.MaxFloat64, math.SmallestNonzeroFloat64),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext16 && int8(d[1]) == def.ComplexTypeCode()\n\t\t\t\t},\n\t\t\t\tvc: func(t complex64) error {\n\t\t\t\t\tif imag(t) != 0 || real(t) == 0 {\n\t\t\t\t\t\treturn fmt.Errorf(\"somthing wrong %v\", t)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args2...)\n\t})\n\n\tt.Run(\"ComplexTypeCode\", func(t *testing.T) {\n\t\tb64, err := msgpack.Marshal(complex64(complex(3, 4)))\n\t\tNoError(t, err)\n\n\t\tb128, err := msgpack.Marshal(complex128(complex(5, 6)))\n\t\tNoError(t, err)\n\n\t\t// change complex type code\n\t\tmsgpack.SetComplexTypeCode(int8(-99))\n\n\t\tdata := []struct {\n\t\t\tname   string\n\t\t\tb      []byte\n\t\t\terrStr string\n\t\t}{\n\t\t\t{\"From64\", b64, \"fixext8\"},\n\t\t\t{\"From128\", b128, \"fixext16\"},\n\t\t}\n\n\t\tvar r64 complex64\n\t\tvar r128 complex128\n\t\tfor _, d := range data {\n\t\t\tfor _, u := range unmarshallers {\n\t\t\t\tt.Run(d.name+\"To64\"+u.name, func(t *testing.T) {\n\t\t\t\t\tErrorContains(t, u.u(d.b, &r64), d.errStr)\n\t\t\t\t})\n\t\t\t\tt.Run(d.name+\"To128\"+u.name, func(t *testing.T) {\n\t\t\t\t\tErrorContains(t, u.u(d.b, &r128), d.errStr)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestAny(t *testing.T) {\n\tf := func(v interface{}) error {\n\t\tb, err := msgpack.Marshal(v)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvar r interface{}\n\t\terr = msgpack.Unmarshal(b, &r)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif fmt.Sprintf(\"%v\", v) != fmt.Sprintf(\"%v\", r) {\n\t\t\treturn fmt.Errorf(\"different value %v, %v\", v, r)\n\t\t}\n\t\treturn err\n\t}\n\n\ta1 := make([]int, math.MaxUint16)\n\ta2 := make([]int, math.MaxUint16+1)\n\tm1 := map[string]int{}\n\tm2 := map[string]int{}\n\n\tfor i := range a1 {\n\t\ta1[i] = i\n\t\tm1[fmt.Sprint(i)] = 1\n\t}\n\tfor i := range a2 {\n\t\ta2[i] = i\n\t\tm2[fmt.Sprint(i)] = 1\n\t}\n\n\tvars := []interface{}{\n\t\ttrue, false,\n\t\t1, math.MaxUint8, math.MaxUint16, math.MaxUint32, math.MaxUint32 + 1,\n\t\t-1, math.MinInt8, math.MinInt16, math.MinInt32, math.MinInt32 - 1,\n\t\tmath.MaxFloat32, math.MaxFloat64,\n\t\t\"a\", strings.Repeat(\"a\", math.MaxUint8), strings.Repeat(\"a\", math.MaxUint16), strings.Repeat(\"a\", math.MaxUint16+1),\n\t\t[]byte(strings.Repeat(\"a\", math.MaxUint8)),\n\t\t[]byte(strings.Repeat(\"a\", math.MaxUint16)),\n\t\t[]byte(strings.Repeat(\"a\", math.MaxUint16+1)),\n\t\t[]interface{}{1, \"a\", 1.23},\n\t\ta1, a2,\n\t\tmap[interface{}]interface{}{\"1\": 1, 1.23: \"a\"},\n\t\tm1, m2,\n\t\ttime.Unix(now.Unix(), int64(now.Nanosecond())).UTC(),\n\t}\n\n\tfor i, v := range vars {\n\t\tif err := f(v); err != nil {\n\t\t\tt.Error(i, err)\n\t\t}\n\t}\n\n\tt.Run(\"Any\", func(t *testing.T) {\n\t\targs := []encdecArg[any]{\n\t\t\t{n: \"true\", v: any(true)},\n\t\t\t{n: \"false\", v: any(false)},\n\t\t\t{n: \"1\", v: any(1)},\n\t\t\t{n: \"MaxUint8\", v: any(math.MaxUint8)},\n\t\t\t{n: \"MaxUint16\", v: any(math.MaxUint16)},\n\t\t\t{n: \"MaxUint32\", v: any(math.MaxUint32)},\n\t\t\t{n: \"MaxUint32+1\", v: any(math.MaxUint32 + 1)},\n\t\t\t{n: \"-1\", v: any(-1)},\n\t\t\t{n: \"MinInt8\", v: any(math.MinInt8)},\n\t\t\t{n: \"MinInt16\", v: any(math.MinInt16)},\n\t\t\t{n: \"MinInt32\", v: any(math.MinInt32)},\n\t\t\t{n: \"MinInt32-1\", v: any(math.MinInt32 - 1)},\n\t\t\t{n: \"MaxFloat32\", v: any(math.MaxFloat32)},\n\t\t\t{n: \"MaxFloat64\", v: any(math.MaxFloat64)},\n\t\t\t{n: \"Str1\", v: any(\"a\")},\n\t\t\t{n: \"Str255\", v: any(strings.Repeat(\"a\", math.MaxUint8))},\n\t\t\t{n: \"Str65535\", v: any(strings.Repeat(\"a\", math.MaxUint16))},\n\t\t\t{n: \"Str65536\", v: any(strings.Repeat(\"a\", math.MaxUint16+1))},\n\t\t\t{n: \"Bin255\", v: any([]byte(strings.Repeat(\"a\", math.MaxUint8)))},\n\t\t\t{n: \"Bin65535\", v: any([]byte(strings.Repeat(\"a\", math.MaxUint16)))},\n\t\t\t{n: \"Bin65536\", v: any([]byte(strings.Repeat(\"a\", math.MaxUint16+1)))},\n\t\t\t{n: \"Slice3\", v: any([]any{1, \"a\", 1.23})},\n\t\t\t{n: \"Slice65535\", v: any(a1)},\n\t\t\t{n: \"Slice65536\", v: any(a2)},\n\t\t\t{n: \"Map3\", v: any(map[any]any{\"1\": 1, 1.23: \"a\"})},\n\t\t\t{n: \"Map65535\", v: any(m1)},\n\t\t\t{n: \"Map65536\", v: any(m2)},\n\t\t\t{n: \"Time\", v: any(time.Unix(now.Unix(), int64(now.Nanosecond())).UTC())},\n\t\t}\n\t\tfor i := range args {\n\t\t\ti := i\n\t\t\targs[i].skipEq = true\n\t\t\targs[i].vc = func(t any) error {\n\t\t\t\tif fmt.Sprintf(\"%v\", args[i].v) != fmt.Sprintf(\"%v\", t) {\n\t\t\t\t\treturn fmt.Errorf(\"different value %v, %v\", args[i].v, t)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// error\n\tt.Run(\"AnyError\", func(t *testing.T) {\n\t\tvar r any\n\t\terr := msgpack.Unmarshal([]byte{def.Ext32}, &r)\n\t\tErrorContains(t, err, \"too short bytes\")\n\t})\n}\n\nfunc TestBin(t *testing.T) {\n\tmakeByteSlice := func(len int) []byte {\n\t\tv := make([]byte, len)\n\t\tfor i := range v {\n\t\t\tv[i] = byte(rand.Intn(0xff))\n\t\t}\n\t\treturn v\n\t}\n\n\tt.Run(\"Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]byte]{\n\t\t\t{\n\t\t\t\tn: \"Bin8\",\n\t\t\t\tv: makeByteSlice(128),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin8\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Bin16\",\n\t\t\t\tv: makeByteSlice(31280),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin16\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Bin32\",\n\t\t\t\tv: makeByteSlice(1031280),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"Array\", func(t *testing.T) {\n\t\tvar (\n\t\t\ta128     [128]byte\n\t\t\ta31280   [31280]byte\n\t\t\ta1031280 [1031280]byte\n\t\t)\n\t\tfor i := range a128 {\n\t\t\ta128[i] = byte(rand.Intn(0xff))\n\t\t}\n\t\tfor i := range a31280 {\n\t\t\ta31280[i] = byte(rand.Intn(0xff))\n\t\t}\n\t\tfor i := range a1031280 {\n\t\t\ta1031280[i] = byte(rand.Intn(0xff))\n\t\t}\n\t\targs128 := []encdecArg[[128]byte]{\n\t\t\t{\n\t\t\t\tn: \"Bin8\",\n\t\t\t\tv: a128,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin8\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args128...)\n\n\t\targs31280 := []encdecArg[[31280]byte]{\n\t\t\t{\n\t\t\t\tn: \"Bin16\",\n\t\t\t\tv: a31280,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin16\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args31280...)\n\n\t\targs1031280 := []encdecArg[[1031280]byte]{\n\t\t\t{\n\t\t\t\tn: \"Bin32\",\n\t\t\t\tv: a1031280,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args1031280...)\n\n\t\targs := []encdecArg[[1]byte]{\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: nil,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t\te: \"value different\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"Error\", func(t *testing.T) {\n\t\targs1 := []encdecArg[[1]byte]{\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: nil,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t\te: \"value different\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args1...)\n\n\t\tvar a128 [128]byte\n\t\tfor i := range a128 {\n\t\t\ta128[i] = byte(rand.Intn(0xff))\n\t\t}\n\t\targs2 := []encdecArg[[127]byte]{\n\t\t\t{\n\t\t\t\tn: \"Len\",\n\t\t\t\tv: a128,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Bin8\n\t\t\t\t},\n\t\t\t\te: \"[127]uint8 len is 127, but msgpack has 128 elements\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args2...)\n\t})\n}\n\nfunc TestArray(t *testing.T) {\n\tt.Run(\"IntSlice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int]{\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: ([]int)(nil),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"FixArray\",\n\t\t\t\tv: make([]int, 15),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixArray <= d[0] && d[0] <= def.FixArray+0x0f\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Array16\",\n\t\t\t\tv: make([]int, 30015),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Array16\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Array32\",\n\t\t\t\tv: make([]int, 1030015),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Array32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"FloatArray\", func(t *testing.T) {\n\t\tvar v [8]float32\n\t\tfor i := range v {\n\t\t\tv[i] = float32(rand.Intn(0xff))\n\t\t}\n\t\targs := []encdecArg[[8]float32]{\n\t\t\t{\n\t\t\t\tn: \"FixArray\",\n\t\t\t\tv: v,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixArray <= d[0] && d[0] <= def.FixArray+0x0f\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"StringArray\", func(t *testing.T) {\n\t\tvar v [31280]string\n\t\tfor i := range v {\n\t\t\tv[i] = \"a\"\n\t\t}\n\t\targs := []encdecArg[[31280]string]{\n\t\t\t{\n\t\t\t\tn: \"Array16\",\n\t\t\t\tv: v,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Array16\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"BoolArray\", func(t *testing.T) {\n\t\tvar v [1031280]bool\n\t\tfor i := range v {\n\t\t\tv[i] = rand.Intn(0xff) > 0x7f\n\t\t}\n\t\targs := []encdecArg[[1031280]bool]{\n\t\t\t{\n\t\t\t\tn: \"Array32\",\n\t\t\t\tv: v,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Array32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"SliceToArray\", func(t *testing.T) {\n\t\targs := []encdecArg[[1]int]{\n\t\t\t{\n\t\t\t\tn: \"Int\",\n\t\t\t\tv: ([]int)(nil),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t\te: \"value different\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"StringToBytes\", func(t *testing.T) {\n\t\tconst v = \"abcde\"\n\t\targs := []encdecArg[[5]byte]{\n\t\t\t{\n\t\t\t\tn:      \"Test\",\n\t\t\t\tv:      v,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(t [5]byte) error {\n\t\t\t\t\tif v != string(t[:]) {\n\t\t\t\t\t\treturn fmt.Errorf(\"value different %v, %v\", v, string(t[:]))\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestFixedSlice(t *testing.T) {\n\tc := func(d []byte) bool {\n\t\treturn def.FixArray <= d[0] && d[0] <= def.FixArray+0x0f\n\t}\n\n\tt.Run(\"IntSlice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int]{\n\t\t\t{\n\t\t\t\tv: []int{-1, 1},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"UintSlice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]uint]{\n\t\t\t{\n\t\t\t\tv: []uint{0, 100},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Int8Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int8]{\n\t\t\t{\n\t\t\t\tv: []int8{math.MinInt8, math.MaxInt8},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Int16Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int16]{\n\t\t\t{\n\t\t\t\tv: []int16{math.MinInt16, math.MaxInt16},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Int32Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int32]{\n\t\t\t{\n\t\t\t\tv: []int32{math.MinInt32, math.MaxInt32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Int64Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]int64]{\n\t\t\t{\n\t\t\t\tv: []int64{math.MinInt64, math.MaxInt64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Uint8Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]uint8]{\n\t\t\t{\n\t\t\t\tv: []uint8{0, math.MaxUint8},\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\t// byte array\n\t\t\t\t\treturn def.Bin8 == d[0]\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Uint16Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]uint16]{\n\t\t\t{\n\t\t\t\tv: []uint16{0, math.MaxUint16},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Uint32Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]uint32]{\n\t\t\t{\n\t\t\t\tv: []uint32{0, math.MaxUint32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Uint64Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]uint64]{\n\t\t\t{\n\t\t\t\tv: []uint64{0, math.MaxUint64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Float32Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]float32]{\n\t\t\t{\n\t\t\t\tv: []float32{math.SmallestNonzeroFloat32, math.MaxFloat32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"Float64Slice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]float64]{\n\t\t\t{\n\t\t\t\tv: []float64{math.SmallestNonzeroFloat64, math.MaxFloat64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"StringSlice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]string]{\n\t\t\t{\n\t\t\t\tv: []string{\"aaa\", \"bbb\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"BoolSlice\", func(t *testing.T) {\n\t\targs := []encdecArg[[]bool]{\n\t\t\t{\n\t\t\t\tv: []bool{true, false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestFixedMap(t *testing.T) {\n\tc := func(d []byte) bool {\n\t\treturn def.FixMap <= d[0] && d[0] <= def.FixMap+0x0f\n\t}\n\n\tt.Run(\"MapStringInt\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]int]{\n\t\t\t{\n\t\t\t\tv: map[string]int{\"a\": 1, \"b\": 2},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringUint\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]uint]{\n\t\t\t{\n\t\t\t\tv: map[string]uint{\"a\": math.MaxUint32, \"b\": 0},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringString\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]string]{\n\t\t\t{\n\t\t\t\tv: map[string]string{\"a\": \"12345\", \"abcdefghijklmnopqrstuvwxyz\": \"abcdefghijklmnopqrstuvwxyz\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringFloat32\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]float32]{\n\t\t\t{\n\t\t\t\tv: map[string]float32{\"a\": math.MaxFloat32, \"b\": math.SmallestNonzeroFloat32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringFloat64\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]float64]{\n\t\t\t{\n\t\t\t\tv: map[string]float64{\"a\": math.MaxFloat64, \"b\": math.SmallestNonzeroFloat64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringBool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]bool]{\n\t\t\t{\n\t\t\t\tv: map[string]bool{\"a\": true, \"b\": false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"MapStringInt8\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]int8]{\n\t\t\t{\n\t\t\t\tv: map[string]int8{\"a\": math.MinInt8, \"b\": math.MaxInt8},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringInt16\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]int16]{\n\t\t\t{\n\t\t\t\tv: map[string]int16{\"a\": math.MaxInt16, \"b\": math.MinInt16},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringInt32\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]int32]{\n\t\t\t{\n\t\t\t\tv: map[string]int32{\"a\": math.MaxInt32, \"b\": math.MinInt32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringInt64\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]int64]{\n\t\t\t{\n\t\t\t\tv: map[string]int64{\"a\": math.MinInt64, \"b\": math.MaxInt64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringUint8\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]uint8]{\n\t\t\t{\n\t\t\t\tv: map[string]uint8{\"a\": 0, \"b\": math.MaxUint8},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringUint16\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]uint16]{\n\t\t\t{\n\t\t\t\tv: map[string]uint16{\"a\": 0, \"b\": math.MaxUint16},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringUint32\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]uint32]{\n\t\t\t{\n\t\t\t\tv: map[string]uint32{\"a\": 0, \"b\": math.MaxUint32},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapStringUint64\", func(t *testing.T) {\n\t\targs := []encdecArg[map[string]uint64]{\n\t\t\t{\n\t\t\t\tv: map[string]uint64{\"a\": 0, \"b\": math.MaxUint64},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapIntString\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int]string]{\n\t\t\t{\n\t\t\t\tv: map[int]string{0: \"a\", 1: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapIntBool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int]bool]{\n\t\t\t{\n\t\t\t\tv: map[int]bool{1: true, 2: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUintString\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint]string]{\n\t\t\t{\n\t\t\t\tv: map[uint]string{0: \"a\", 1: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUintBool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint]bool]{\n\t\t\t{\n\t\t\t\tv: map[uint]bool{0: true, 255: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapFloat32String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[float32]string]{\n\t\t\t{\n\t\t\t\tv: map[float32]string{math.MaxFloat32: \"a\", math.SmallestNonzeroFloat32: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapFloat32Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[float32]bool]{\n\t\t\t{\n\t\t\t\tv: map[float32]bool{math.SmallestNonzeroFloat32: true, math.MaxFloat32: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapFloat64String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[float64]string]{\n\t\t\t{\n\t\t\t\tv: map[float64]string{math.MaxFloat64: \"a\", math.SmallestNonzeroFloat64: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapFloat64Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[float64]bool]{\n\t\t\t{\n\t\t\t\tv: map[float64]bool{math.SmallestNonzeroFloat64: true, math.MaxFloat64: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt8String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int8]string]{\n\t\t\t{\n\t\t\t\tv: map[int8]string{math.MinInt8: \"a\", math.MaxInt8: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt8Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int8]bool]{\n\t\t\t{\n\t\t\t\tv: map[int8]bool{math.MinInt8: true, math.MaxInt8: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt16String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int16]string]{\n\t\t\t{\n\t\t\t\tv: map[int16]string{math.MaxInt16: \"a\", math.MinInt16: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt16Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int16]bool]{\n\t\t\t{\n\t\t\t\tv: map[int16]bool{math.MaxInt16: true, math.MinInt16: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"MapInt32String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int32]string]{\n\t\t\t{\n\t\t\t\tv: map[int32]string{math.MinInt32: \"a\", math.MaxInt32: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt32Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int32]bool]{\n\t\t\t{\n\t\t\t\tv: map[int32]bool{math.MinInt32: true, math.MaxInt32: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt64String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int64]string]{\n\t\t\t{\n\t\t\t\tv: map[int64]string{math.MaxInt64: \"a\", math.MinInt64: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapInt64Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int64]bool]{\n\t\t\t{\n\t\t\t\tv: map[int64]bool{math.MaxInt64: true, math.MinInt64: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint8String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint8]string]{\n\t\t\t{\n\t\t\t\tv: map[uint8]string{0: \"a\", math.MaxUint8: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint8Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint8]bool]{\n\t\t\t{\n\t\t\t\tv: map[uint8]bool{0: true, math.MaxUint8: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint16String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint16]string]{\n\t\t\t{\n\t\t\t\tv: map[uint16]string{0: \"a\", math.MaxUint16: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint16Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint16]bool]{\n\t\t\t{\n\t\t\t\tv: map[uint16]bool{0: true, math.MaxUint16: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint32String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint32]string]{\n\t\t\t{\n\t\t\t\tv: map[uint32]string{0: \"a\", math.MaxUint32: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint32Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint32]bool]{\n\t\t\t{\n\t\t\t\tv: map[uint32]bool{0: true, math.MaxUint32: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint64String\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint64]string]{\n\t\t\t{\n\t\t\t\tv: map[uint64]string{0: \"a\", math.MaxUint64: \"b\"},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"MapUint64Bool\", func(t *testing.T) {\n\t\targs := []encdecArg[map[uint64]bool]{\n\t\t\t{\n\t\t\t\tv: map[uint64]bool{0: true, math.MaxUint64: false},\n\t\t\t\tc: c,\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestTime(t *testing.T) {\n\tt.Run(\"Time\", func(t *testing.T) {\n\t\targs := []encdecArg[time.Time]{\n\t\t\t{\n\t\t\t\tn: \"Fixext4\",\n\t\t\t\tv: time.Unix(now.Unix(), 0).UTC(),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext4\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Fixext8\",\n\t\t\t\tv: time.Unix(now.Unix(), int64(now.Nanosecond())).UTC(),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Fixext8\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"Error\", func(t *testing.T) {\n\t\tnow := time.Now().Unix()\n\t\tnowByte := make([]byte, 4)\n\t\tbinary.BigEndian.PutUint32(nowByte, uint32(now))\n\n\t\tvar r time.Time\n\t\tc := def.TimeStamp\n\n\t\tfor _, u := range unmarshallers {\n\t\t\tt.Run(u.name+\"64formats\", func(t *testing.T) {\n\t\t\t\tnanoByte := make([]byte, 64)\n\t\t\t\tfor i := range nanoByte[:30] {\n\t\t\t\t\tnanoByte[i] = 0xff\n\t\t\t\t}\n\t\t\t\tb := append([]byte{def.Fixext8, byte(c)}, nanoByte...)\n\t\t\t\terr := u.u(b, &r)\n\t\t\t\tErrorContains(t, err, \"timestamp 64 formats\")\n\t\t\t})\n\t\t\tt.Run(u.name+\"96formats\", func(t *testing.T) {\n\t\t\t\tnanoByte := make([]byte, 96)\n\t\t\t\tfor i := range nanoByte[:32] {\n\t\t\t\t\tnanoByte[i] = 0xff\n\t\t\t\t}\n\t\t\t\tb := append([]byte{def.Ext8, byte(12), byte(c)}, nanoByte...)\n\t\t\t\terr := u.u(b, &r)\n\t\t\t\tErrorContains(t, err, \"timestamp 96 formats\")\n\t\t\t})\n\t\t}\n\n\t\tt.Run(\"ShouldNotReach\", func(t *testing.T) {\n\t\t\tnotReach := []byte{def.Fixext1}\n\t\t\t_, _, err := extTime.Decoder.AsValue(0, reflect.Bool, &notReach)\n\t\t\tErrorContains(t, err, \"should not reach this line\")\n\t\t})\n\n\t\tt.Run(\"ShouldNotReachStream\", func(t *testing.T) {\n\t\t\t_, err := extTime.StreamDecoder.ToValue(def.Fixext1, nil, reflect.Bool)\n\t\t\tErrorContains(t, err, \"should not reach this line\")\n\t\t})\n\t})\n\n\tloc := time.Local\n\tutc8 := time.FixedZone(\"UTC-8\", -8*60*60)\n\n\ttime.Local = utc8\n\tt.Cleanup(func() {\n\t\ttime.Local = loc\n\t\tmsgpack.SetDecodedTimeAsUTC()\n\t})\n\tt.Run(\"Default\", func(t *testing.T) {\n\t\targs := []encdecArg[time.Time]{\n\t\t\t{\n\t\t\t\tn: \"case\",\n\t\t\t\tv: time.Unix(now.Unix(), 0),\n\t\t\t\tvc: func(r time.Time) error {\n\t\t\t\t\ttu.Equal(t, now.Unix(), r.Unix())\n\t\t\t\t\ttu.Equal(t, r.Location(), time.UTC)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true, // skip equal check because of location difference\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"UTC\", func(t *testing.T) {\n\t\tmsgpack.SetDecodedTimeAsUTC()\n\t\targs := []encdecArg[time.Time]{\n\t\t\t{\n\t\t\t\tn: \"case\",\n\t\t\t\tv: time.Unix(now.Unix(), 0),\n\t\t\t\tvc: func(r time.Time) error {\n\t\t\t\t\ttu.Equal(t, now.Unix(), r.Unix())\n\t\t\t\t\ttu.Equal(t, r.Location(), time.UTC)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t\tskipEq: true, // skip equal check because of location difference\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\tt.Run(\"Local\", func(t *testing.T) {\n\t\tmsgpack.SetDecodedTimeAsLocal()\n\t\targs := []encdecArg[time.Time]{\n\t\t\t{\n\t\t\t\tn: \"case\",\n\t\t\t\tv: time.Unix(now.Unix(), 0),\n\t\t\t\tvc: func(r time.Time) error {\n\t\t\t\t\ttu.Equal(t, r.Location(), time.Local)\n\t\t\t\t\ttu.Equal(t, r.Location(), utc8)\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestMap(t *testing.T) {\n\tmapIntInt := func(l int) map[int]int {\n\t\tm := make(map[int]int, l)\n\t\tfor i := 0; i < l; i++ {\n\t\t\tm[i] = i + 1\n\t\t}\n\t\treturn m\n\t}\n\tt.Run(\"MapCode\", func(t *testing.T) {\n\t\targs := []encdecArg[map[int]int]{\n\t\t\t{\n\t\t\t\tn: \"FixMap\",\n\t\t\t\tv: map[int]int{1: 2, 3: 4, 5: 6, 7: 8, 9: 10},\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixMap <= d[0] && d[0] <= def.FixMap+0x0f\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Map16\",\n\t\t\t\tv: mapIntInt(1000),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map16\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Map32\",\n\t\t\t\tv: mapIntInt(math.MaxUint16 + 1),\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map32\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\tt.Run(\"DiffType\", func(t *testing.T) {\n\t\tv := mapIntInt(100)\n\t\targs := []encdecArg[map[uint]uint]{\n\t\t\t{\n\t\t\t\tn: \"IntIntToUintUint\",\n\t\t\t\tv: v,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map16\n\t\t\t\t},\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(r map[uint]uint) error {\n\t\t\t\t\tfor k, vv := range v {\n\t\t\t\t\t\tif rv, ok := r[uint(k)]; !ok || rv != uint(vv) {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"value differentee\")\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif len(v) != len(r) {\n\t\t\t\t\t\treturn fmt.Errorf(\"value different. v:%d, r:%d\", len(v), len(r))\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// error\n\tt.Run(\"Error\", func(t *testing.T) {\n\t\tv1 := make(map[string]int, 100)\n\t\tfor i := 0; i < 100; i++ {\n\t\t\tv1[fmt.Sprintf(\"%03d\", i)] = i\n\t\t}\n\t\tv2 := make(map[int]string, 100)\n\t\tfor i := 0; i < 100; i++ {\n\t\t\tv2[i] = fmt.Sprint(i % 10)\n\t\t}\n\t\targs := []encdecArg[map[int]int]{\n\t\t\t{\n\t\t\t\tn: \"InvalidKey\",\n\t\t\t\tv: v1,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map16\n\t\t\t\t},\n\t\t\t\te: \"invalid code a3 decoding\",\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"InvalidValue\",\n\t\t\t\tv: v2,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map16\n\t\t\t\t},\n\t\t\t\te: \"invalid code a1 decoding\",\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n}\n\nfunc TestPointer(t *testing.T) {\n\tt.Run(\"Pointer\", func(t *testing.T) {\n\t\tv := 250\n\t\tvv := &v\n\t\tvar vvv *int\n\t\targs := []encdecArg[*int]{\n\t\t\t{\n\t\t\t\tn: \"Int\",\n\t\t\t\tv: vv,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Uint8\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tn: \"Nil\",\n\t\t\t\tv: vvv,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Nil\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\t\tencdec(t, args...)\n\t})\n\n\t// error\n\tt.Run(\"ReceiverMustBePointer\", func(t *testing.T) {\n\t\tfor _, u := range unmarshallers {\n\t\t\tvar r int\n\t\t\tt.Run(u.name, func(t *testing.T) {\n\t\t\t\terr := u.u([]byte{def.Nil}, r)\n\t\t\t\tErrorContains(t, err, \"receiver not pointer\")\n\t\t\t})\n\t\t}\n\t})\n}\n\nfunc TestUnsupported(t *testing.T) {\n\tb := []byte{0xc0}\n\n\tt.Run(\"Uintptr\", func(t *testing.T) {\n\t\tfor _, m := range marshallers {\n\t\t\tt.Run(m.name, func(t *testing.T) {\n\t\t\t\tvar v uintptr\n\t\t\t\t_, err := m.m(v)\n\t\t\t\tErrorContains(t, err, \"uintptr is unsupported type\")\n\t\t\t})\n\t\t}\n\t\tfor _, u := range unmarshallers {\n\t\t\tt.Run(u.name, func(t *testing.T) {\n\t\t\t\tvar r uintptr\n\t\t\t\terr := u.u(b, &r)\n\t\t\t\tErrorContains(t, err, \"uintptr is unsupported type\")\n\t\t\t})\n\t\t}\n\t})\n\tt.Run(\"Chan\", func(t *testing.T) {\n\t\tfor _, m := range marshallers {\n\t\t\tt.Run(m.name, func(t *testing.T) {\n\t\t\t\tvar v chan string\n\t\t\t\t_, err := m.m(v)\n\t\t\t\tErrorContains(t, err, \"chan is unsupported type\")\n\t\t\t})\n\t\t}\n\t\tfor _, u := range unmarshallers {\n\t\t\tt.Run(u.name, func(t *testing.T) {\n\t\t\t\tvar r chan string\n\t\t\t\terr := u.u(b, &r)\n\t\t\t\tErrorContains(t, err, \"chan is unsupported type\")\n\t\t\t})\n\t\t}\n\t})\n\tt.Run(\"Func\", func(t *testing.T) {\n\t\tfor _, m := range marshallers {\n\t\t\tt.Run(m.name, func(t *testing.T) {\n\t\t\t\tvar v func()\n\t\t\t\t_, err := m.m(v)\n\t\t\t\tErrorContains(t, err, \"func is unsupported type\")\n\t\t\t})\n\t\t}\n\t\tfor _, u := range unmarshallers {\n\t\t\tt.Run(u.name, func(t *testing.T) {\n\t\t\t\tvar r func()\n\t\t\t\terr := u.u(b, &r)\n\t\t\t\tErrorContains(t, err, \"func is unsupported type\")\n\t\t\t})\n\t\t}\n\t})\n\tt.Run(\"Error\", func(t *testing.T) {\n\t\t// error reflect kind is invalid. current version set nil (0xc0)\n\t\tfor _, m := range marshallers {\n\t\t\tfor _, u := range unmarshallers {\n\t\t\t\tt.Run(m.name+u.name, func(t *testing.T) {\n\t\t\t\t\tvar v, r error\n\t\t\t\t\tbb, err := m.m(v)\n\t\t\t\t\tNoError(t, err)\n\t\t\t\t\tif bb[0] != def.Nil {\n\t\t\t\t\t\tt.Fatalf(\"code is different %d, %d\", b[0], def.Nil)\n\t\t\t\t\t}\n\n\t\t\t\t\terr = u.u(b, &r)\n\t\t\t\t\tNoError(t, err)\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t})\n\t{\n\t\t// error reflect kind is invalid. current version set nil (0xc0)\n\t\tvar v, r error\n\t\tbb, err := msgpack.Marshal(v)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif bb[0] != def.Nil {\n\t\t\tt.Errorf(\"code is different %d, %d\", bb[0], def.Nil)\n\t\t}\n\t\terr = msgpack.Unmarshal(b, &r)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif r != nil {\n\t\t\tt.Error(\"error should be nil\")\n\t\t}\n\t}\n}\n\n/////////////////////////////////////////////////////////////////\n\nfunc TestStruct(t *testing.T) {\n\tt.Run(\"Code\", func(t *testing.T) {\n\t\ttestStructCode(t)\n\t})\n\tt.Run(\"Tag\", func(t *testing.T) {\n\t\ttestStructTag(t)\n\t})\n\tt.Run(\"Omitempty\", func(t *testing.T) {\n\t\tTestStructTagOmitempty(t)\n\t})\n\tt.Run(\"Array\", func(t *testing.T) {\n\t\ttestStructArray(t)\n\t})\n\tt.Run(\"Embedded\", func(t *testing.T) {\n\t\ttestEmbedded(t)\n\t})\n\tt.Run(\"EmbeddedStruct\", func(t *testing.T) {\n\t\ttestEmbeddedStruct(t)\n\t})\n\tt.Run(\"Jump\", func(t *testing.T) {\n\t\ttestStructJump(t)\n\t})\n\tt.Run(\"UseCase\", func(t *testing.T) {\n\t\tb := msgpack.StructAsArray\n\t\tdefer func() {\n\t\t\tmsgpack.StructAsArray = b\n\t\t}()\n\t\ttestStructUseCase(t)\n\t\tmsgpack.StructAsArray = true\n\t\ttestStructUseCase(t)\n\t})\n}\n\nfunc testEmbedded(t *testing.T) {\n\ttype Emb struct {\n\t\tInt int\n\t}\n\ttype A struct {\n\t\tEmb\n\t}\n\tv := A{Emb: Emb{Int: 2}}\n\n\targ := encdecArg[A]{\n\t\tv: v,\n\t\tvc: func(t A) error {\n\t\t\tif v.Int != t.Int {\n\t\t\t\treturn fmt.Errorf(\"value is different %v, %v\", v, t)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\tencdec(t, arg)\n}\n\nfunc testEmbeddedStruct(t *testing.T) {\n\tb := msgpack.StructAsArray\n\tdefer func() {\n\t\tmsgpack.StructAsArray = b\n\t}()\n\n\tt.Run(\"SimpleEmbedded\", func(t *testing.T) {\n\t\ttype Embedded struct {\n\t\t\tEmbeddedField int\n\t\t\tName          string\n\t\t}\n\t\ttype Parent struct {\n\t\t\tEmbedded\n\t\t\tParentField string\n\t\t}\n\n\t\toriginal := Parent{\n\t\t\tEmbedded:    Embedded{EmbeddedField: 42, Name: \"test\"},\n\t\t\tParentField: \"parent\",\n\t\t}\n\n\t\t// Test with msgpack\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Parent\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Parent]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Parent) error {\n\t\t\t\t\t// Verify fields are promoted\n\t\t\t\t\ttu.Equal(t, p.EmbeddedField, 42)\n\t\t\t\t\ttu.Equal(t, p.Name, \"test\")\n\t\t\t\t\ttu.Equal(t, p.ParentField, \"parent\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Parent\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.EmbeddedField != jsonDecoded.EmbeddedField ||\n\t\t\tmsgDecoded.Name != jsonDecoded.Name ||\n\t\t\tmsgDecoded.ParentField != jsonDecoded.ParentField {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"EmbeddedWithTag\", func(t *testing.T) {\n\t\ttype Embedded struct {\n\t\t\tField int\n\t\t}\n\t\ttype Parent struct {\n\t\t\tEmbedded `msgpack:\"emb\"`\n\t\t\tRegular  string\n\t\t}\n\n\t\toriginal := Parent{\n\t\t\tEmbedded: Embedded{Field: 99},\n\t\t\tRegular:  \"value\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Parent\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Parent]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Parent) error {\n\t\t\t\t\t// Tagged embedded struct should not be promoted\n\t\t\t\t\t//nolint:staticcheck // QF1008 for test\n\t\t\t\t\ttu.Equal(t, p.Embedded.Field, 99)\n\t\t\t\t\ttu.Equal(t, p.Regular, \"value\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Parent\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\t//nolint:staticcheck // QF1008 for test\n\t\tif msgDecoded.Embedded.Field != jsonDecoded.Embedded.Field ||\n\t\t\tmsgDecoded.Regular != jsonDecoded.Regular {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"MultiLevelEmbedding\", func(t *testing.T) {\n\t\ttype Deep struct {\n\t\t\tDeepField int\n\t\t}\n\t\ttype Middle struct {\n\t\t\tDeep\n\t\t\tMiddleField string\n\t\t}\n\t\ttype Top struct {\n\t\t\tMiddle\n\t\t\tTopField bool\n\t\t}\n\n\t\toriginal := Top{\n\t\t\tMiddle: Middle{\n\t\t\t\tDeep:        Deep{DeepField: 100},\n\t\t\t\tMiddleField: \"middle\",\n\t\t\t},\n\t\t\tTopField: true,\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Top\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Top]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Top) error {\n\t\t\t\t\ttu.Equal(t, p.DeepField, 100)\n\t\t\t\t\ttu.Equal(t, p.MiddleField, \"middle\")\n\t\t\t\t\ttu.Equal(t, p.TopField, true)\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Top\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.DeepField != jsonDecoded.DeepField ||\n\t\t\tmsgDecoded.MiddleField != jsonDecoded.MiddleField ||\n\t\t\tmsgDecoded.TopField != jsonDecoded.TopField {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"FieldShadowing\", func(t *testing.T) {\n\t\ttype Base struct {\n\t\t\tName string\n\t\t\tAge  int\n\t\t}\n\t\ttype Derived struct {\n\t\t\tBase\n\t\t\tName string // Shadows Base.Name\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tBase: Base{Name: \"base\", Age: 30},\n\t\t\tName: \"derived\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Derived\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\ttu.Equal(t, p.Name, \"derived\")\n\t\t\t\t\ttu.Equal(t, p.Age, 30)\n\t\t\t\t\ttu.Equal(t, p.Base.Name, \"\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Derived\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.Name != jsonDecoded.Name || msgDecoded.Age != jsonDecoded.Age {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"TaggedFieldPriority\", func(t *testing.T) {\n\t\ttype Tagged struct {\n\t\t\tName string `msgpack:\"Name\" json:\"Name\"`\n\t\t}\n\t\ttype Plain struct {\n\t\t\tName string\n\t\t}\n\t\ttype Derived struct {\n\t\t\tTagged\n\t\t\tPlain\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tTagged: Tagged{Name: \"tagged\"},\n\t\t\tPlain:  Plain{Name: \"plain\"},\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Derived\n\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\ttu.Equal(t, p.Tagged.Name, \"tagged\")\n\t\t\t\t\ttu.Equal(t, p.Plain.Name, \"\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Derived\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.Tagged.Name != jsonDecoded.Tagged.Name ||\n\t\t\tmsgDecoded.Plain.Name != jsonDecoded.Plain.Name {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"EmbeddedOmitEmpty\", func(t *testing.T) {\n\t\ttype Embedded struct {\n\t\t\tA int\n\t\t\tB string\n\t\t}\n\t\ttype Parent struct {\n\t\t\tEmbedded `msgpack:\",omitempty\"`\n\t\t\tC        int\n\t\t}\n\n\t\tmsgpack.StructAsArray = false\n\t\tencdec(t, encdecArg[map[string]any]{\n\t\t\tv:      Parent{Embedded: Embedded{}, C: 1},\n\t\t\tskipEq: true,\n\t\t\tvc: func(p map[string]any) error {\n\t\t\t\tif _, ok := p[\"A\"]; ok {\n\t\t\t\t\treturn fmt.Errorf(\"embedded field A should be omitted\")\n\t\t\t\t}\n\t\t\t\tif _, ok := p[\"B\"]; ok {\n\t\t\t\t\treturn fmt.Errorf(\"embedded field B should be omitted\")\n\t\t\t\t}\n\t\t\t\tif _, ok := p[\"C\"]; !ok {\n\t\t\t\t\treturn fmt.Errorf(\"field C should be present\")\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\n\t\tencdec(t, encdecArg[map[string]any]{\n\t\t\tv:      Parent{Embedded: Embedded{A: 1, B: \"b\"}, C: 2},\n\t\t\tskipEq: true,\n\t\t\tvc: func(p map[string]any) error {\n\t\t\t\tif _, ok := p[\"A\"]; !ok {\n\t\t\t\t\treturn fmt.Errorf(\"embedded field A should be present\")\n\t\t\t\t}\n\t\t\t\tif _, ok := p[\"B\"]; !ok {\n\t\t\t\t\treturn fmt.Errorf(\"embedded field B should be present\")\n\t\t\t\t}\n\t\t\t\tif _, ok := p[\"C\"]; !ok {\n\t\t\t\t\treturn fmt.Errorf(\"field C should be present\")\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\n\t\tmsgpack.StructAsArray = true\n\t\tencdec(t, encdecArg[Parent]{\n\t\t\tv: Parent{Embedded: Embedded{}, C: 1},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn len(d) == 4 &&\n\t\t\t\t\td[0] == def.FixArray+0x03 &&\n\t\t\t\t\td[1] == 0x01 &&\n\t\t\t\t\td[2] == def.Nil &&\n\t\t\t\t\td[3] == def.Nil\n\t\t\t},\n\t\t\tvc: func(p Parent) error {\n\t\t\t\tif p.A != 0 || p.B != \"\" || p.C != 1 {\n\t\t\t\t\treturn fmt.Errorf(\"unexpected array decode: %+v\", p)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\n\t\tencdec(t, encdecArg[Parent]{\n\t\t\tv: Parent{Embedded: Embedded{A: 1, B: \"b\"}, C: 2},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn len(d) == 5 &&\n\t\t\t\t\td[0] == def.FixArray+0x03 &&\n\t\t\t\t\td[1] == 0x02 &&\n\t\t\t\t\td[2] == 0x01 &&\n\t\t\t\t\td[3] == 0xa1 &&\n\t\t\t\t\td[4] == 'b'\n\t\t\t},\n\t\t\tvc: func(p Parent) error {\n\t\t\t\tif p.A != 1 || p.B != \"b\" || p.C != 2 {\n\t\t\t\t\treturn fmt.Errorf(\"unexpected array decode: %+v\", p)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\t})\n\n\tt.Run(\"AmbiguousFields\", func(t *testing.T) {\n\t\ttype A struct {\n\t\t\tField string\n\t\t}\n\t\ttype B struct {\n\t\t\tField string\n\t\t}\n\t\ttype Derived struct {\n\t\t\tA\n\t\t\tB\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tA: A{Field: \"from A\"},\n\t\t\tB: B{Field: \"from B\"},\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\t// Decode to map to check what fields are present\n\t\tvar msgDecoded map[string]interface{}\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[map[string]any]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p map[string]any) error {\n\t\t\t\t\t// Ambiguous field should be omitted\n\t\t\t\t\tif _, exists := p[\"Field\"]; exists {\n\t\t\t\t\t\tt.Errorf(\"Ambiguous field 'Field' should be omitted\")\n\t\t\t\t\t}\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonMap map[string]interface{}\n\t\t_ = json.Unmarshal(jsonBytes, &jsonMap)\n\n\t\tif len(msgDecoded) != len(jsonMap) {\n\t\t\tt.Errorf(\"Field count differs: msgpack=%d, json=%d\", len(msgDecoded), len(jsonMap))\n\t\t}\n\t})\n\n\tt.Run(\"PointerEmbedded\", func(t *testing.T) {\n\t\ttype Base struct {\n\t\t\tValue int\n\t\t}\n\t\ttype Derived struct {\n\t\t\t*Base\n\t\t\tExtra string\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tBase:  &Base{Value: 123},\n\t\t\tExtra: \"extra\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Derived\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\tif p.Base == nil {\n\t\t\t\t\t\treturn fmt.Errorf(\"base pointer should not be nil after unmarshal\")\n\t\t\t\t\t}\n\t\t\t\t\ttu.Equal(t, p.Value, 123)\n\t\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Derived\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.Value != jsonDecoded.Value || msgDecoded.Extra != jsonDecoded.Extra {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"PointerEmbeddedNil\", func(t *testing.T) {\n\t\ttype Base struct {\n\t\t\tValue int\n\t\t}\n\t\ttype Derived struct {\n\t\t\t*Base\n\t\t\tExtra string\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tBase:  nil,\n\t\t\tExtra: \"extra\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tmsgpack.StructAsArray = false\n\t\tencdec(t, encdecArg[Derived]{\n\t\t\tv:      original,\n\t\t\tskipEq: true,\n\t\t\tvc: func(p Derived) error {\n\t\t\t\tif p.Base != nil {\n\t\t\t\t\treturn fmt.Errorf(\"base pointer should be nil after unmarshal\")\n\t\t\t\t}\n\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\n\t\tmsgpack.StructAsArray = true\n\t\tencdec(t, encdecArg[Derived]{\n\t\t\tv:      original,\n\t\t\tskipEq: true,\n\t\t\tvc: func(p Derived) error {\n\t\t\t\tif p.Base != nil {\n\t\t\t\t\treturn fmt.Errorf(\"base pointer should be nil after unmarshal\")\n\t\t\t\t}\n\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\treturn nil\n\t\t\t},\n\t\t})\n\t\t/*\n\n\t\t\tvar msgDecoded Derived\n\n\t\t\tfor _, isArray := range []bool{false, true} {\n\t\t\t\tmsgpack.StructAsArray = isArray\n\t\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\t\tv:      original,\n\t\t\t\t\tskipEq: true,\n\t\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\t\tif p.Base != nil {\n\t\t\t\t\t\t\treturn fmt.Errorf(\"base pointer should be nil after unmarshal\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Compare with JSON\n\t\t\tjsonBytes, _ := json.Marshal(original)\n\t\t\tvar jsonDecoded Derived\n\t\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\t\t\ttu.Equal(t, jsonDecoded, msgDecoded)\n\t\t*/\n\n\t\toriginal.Base = &Base{Value: 123}\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\t//nolint:staticcheck // QF1008 for test\n\t\t\t\t\ttu.Equal(t, p.Base.Value, 123)\n\t\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"TagSameAsStructName\", func(t *testing.T) {\n\t\t// Edge case: tag with same name as struct field\n\t\ttype Inner struct {\n\t\t\tValue int\n\t\t}\n\t\ttype Outer struct {\n\t\t\tInner `msgpack:\"Inner\"`\n\t\t\tOther string\n\t\t}\n\n\t\toriginal := Outer{\n\t\t\tInner: Inner{Value: 456},\n\t\t\tOther: \"test\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Outer\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Outer]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Outer) error {\n\t\t\t\t\t//nolint:staticcheck // QF1008 for test\n\t\t\t\t\ttu.Equal(t, p.Inner.Value, 456)\n\t\t\t\t\ttu.Equal(t, p.Other, \"test\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Outer\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\t//nolint:staticcheck // QF1008 for test\n\t\tif msgDecoded.Inner.Value != jsonDecoded.Inner.Value ||\n\t\t\tmsgDecoded.Other != jsonDecoded.Other {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"MixedEmbeddedAndRegular\", func(t *testing.T) {\n\t\ttype Timestamp struct {\n\t\t\tCreatedAt string\n\t\t\tUpdatedAt string\n\t\t}\n\t\ttype Document struct {\n\t\t\tTimestamp\n\t\t\tID      int\n\t\t\tContent string\n\t\t\tTitle   string\n\t\t}\n\n\t\toriginal := Document{\n\t\t\tTimestamp: Timestamp{\n\t\t\t\tCreatedAt: \"2024-01-01\",\n\t\t\t\tUpdatedAt: \"2024-01-02\",\n\t\t\t},\n\t\t\tID:      42,\n\t\t\tContent: \"test content\",\n\t\t\tTitle:   \"test title\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Document\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Document]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Document) error {\n\t\t\t\t\ttu.Equal(t, p.CreatedAt, \"2024-01-01\")\n\t\t\t\t\ttu.Equal(t, p.UpdatedAt, \"2024-01-02\")\n\t\t\t\t\ttu.Equal(t, p.ID, 42)\n\t\t\t\t\ttu.Equal(t, p.Content, \"test content\")\n\t\t\t\t\ttu.Equal(t, p.Title, \"test title\")\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Document\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.CreatedAt != jsonDecoded.CreatedAt ||\n\t\t\tmsgDecoded.UpdatedAt != jsonDecoded.UpdatedAt ||\n\t\t\tmsgDecoded.ID != jsonDecoded.ID ||\n\t\t\tmsgDecoded.Content != jsonDecoded.Content ||\n\t\t\tmsgDecoded.Title != jsonDecoded.Title {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"EmbeddedWithPrivateFields\", func(t *testing.T) {\n\t\ttype Base struct {\n\t\t\tPublic  string\n\t\t\tprivate int\n\t\t}\n\t\ttype Derived struct {\n\t\t\tBase\n\t\t\tExtra string\n\t\t}\n\n\t\toriginal := Derived{\n\t\t\tBase:  Base{Public: \"public\", private: 123},\n\t\t\tExtra: \"extra\",\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded Derived\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[Derived]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p Derived) error {\n\t\t\t\t\t// Only public fields should be marshaled\n\t\t\t\t\ttu.Equal(t, p.Public, \"public\")\n\t\t\t\t\ttu.Equal(t, p.Extra, \"extra\")\n\t\t\t\t\ttu.Equal(t, p.private, 0) // private field should be zero value\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded Derived\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.Public != jsonDecoded.Public || msgDecoded.Extra != jsonDecoded.Extra {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n\n\tt.Run(\"ComplexNestedEmbedding\", func(t *testing.T) {\n\t\ttype A struct {\n\t\t\tFieldA string\n\t\t}\n\t\ttype B struct {\n\t\t\tA\n\t\t\tFieldB int\n\t\t}\n\t\ttype C struct {\n\t\t\tB\n\t\t\tFieldC bool\n\t\t}\n\t\ttype D struct {\n\t\t\tC\n\t\t\tFieldD float64\n\t\t}\n\n\t\toriginal := D{\n\t\t\tC: C{\n\t\t\t\tB: B{\n\t\t\t\t\tA:      A{FieldA: \"a\"},\n\t\t\t\t\tFieldB: 1,\n\t\t\t\t},\n\t\t\t\tFieldC: true,\n\t\t\t},\n\t\t\tFieldD: 3.14,\n\t\t}\n\n\t\t_, err := msgpack.MarshalAsMap(original)\n\t\tif err != nil {\n\t\t\tt.Fatalf(\"msgpack.Marshal failed: %v\", err)\n\t\t}\n\n\t\tvar msgDecoded D\n\n\t\t// Test stream encoding/decoding and cross-compatibility\n\t\tfor _, isArray := range []bool{false, true} {\n\t\t\tmsgpack.StructAsArray = isArray\n\t\t\tencdec(t, encdecArg[D]{\n\t\t\t\tv:      original,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(p D) error {\n\t\t\t\t\t// All fields should be promoted to top level\n\t\t\t\t\ttu.Equal(t, p.FieldA, \"a\")\n\t\t\t\t\ttu.Equal(t, p.FieldB, 1)\n\t\t\t\t\ttu.Equal(t, p.FieldC, true)\n\t\t\t\t\ttu.Equal(t, p.FieldD, 3.14)\n\t\t\t\t\tmsgDecoded = p\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\n\t\t// Compare with JSON\n\t\tjsonBytes, _ := json.Marshal(original)\n\t\tvar jsonDecoded D\n\t\t_ = json.Unmarshal(jsonBytes, &jsonDecoded)\n\n\t\tif msgDecoded.FieldA != jsonDecoded.FieldA ||\n\t\t\tmsgDecoded.FieldB != jsonDecoded.FieldB ||\n\t\t\tmsgDecoded.FieldC != jsonDecoded.FieldC ||\n\t\t\tmsgDecoded.FieldD != jsonDecoded.FieldD {\n\t\t\tt.Errorf(\"msgpack and json results differ:\\nmsgpack: %+v\\njson: %+v\",\n\t\t\t\tmsgDecoded, jsonDecoded)\n\t\t}\n\t})\n}\n\nfunc testStructTag(t *testing.T) {\n\ttype vSt struct {\n\t\tOne int    `msgpack:\"Three\"`\n\t\tTwo string `msgpack:\"four\"`\n\t\tHfn bool   `msgpack:\"-\"`\n\t}\n\ttype rSt struct {\n\t\tThree int\n\t\tFour  string `msgpack:\"four\"`\n\t\tHfn   bool\n\t}\n\tv := vSt{One: 1, Two: \"2\", Hfn: true}\n\n\tmsgpack.StructAsArray = false\n\n\targ := encdecArg[rSt]{\n\t\tv: v,\n\t\tc: func(d []byte) bool {\n\t\t\treturn d[0] == def.FixMap+0x02\n\t\t},\n\t\tskipEq: true,\n\t\tvc: func(r rSt) error {\n\t\t\tif v.One != r.Three || v.Two != r.Four || r.Hfn != false {\n\t\t\t\treturn fmt.Errorf(\"error: %v, %v\", v, r)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\tencdec(t, arg)\n}\n\nfunc TestStructTagOmitempty(t *testing.T) {\n\ttype vSt struct {\n\t\tOne   int    `msgpack:\",omitempty\"`\n\t\tTwo   string `msgpack:\"four,omitempty\"`\n\t\tHfn   bool   `msgpack:\"-,omitempty\"`\n\t\tSlice []int  `msgpack:\",omitempty\"`\n\t}\n\ttype rSt struct {\n\t\tOne   int\n\t\tFour  string `msgpack:\"four\"`\n\t\tHfn   bool   `msgpack:\"-\"`\n\t\tSlice []int\n\t}\n\n\tcases := []struct {\n\t\tname  string\n\t\tv     vSt\n\t\tc     func(d []byte) bool\n\t\tarray bool\n\t}{\n\t\t{\n\t\t\tname: \"all empty\",\n\t\t\tv:    vSt{},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x00 && len(d) == 1\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"int\",\n\t\t\tv:    vSt{One: 1},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x01\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"string\",\n\t\t\tv:    vSt{Two: \"2\"},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x01 && d[1] == 0xa4 && d[2] == 'f' && d[3] == 'o' && d[4] == 'u' && d[5] == 'r'\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"bool\",\n\t\t\tv:    vSt{Hfn: true},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x00 && len(d) == 1\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"slice\",\n\t\t\tv:    vSt{Slice: []int{}},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x01 &&\n\t\t\t\t\td[1] == 0xa5 && d[2] == 'S' && d[3] == 'l' && d[4] == 'i' && d[5] == 'c' && d[6] == 'e' &&\n\t\t\t\t\td[7] == def.FixArray+0x00\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"slice values\",\n\t\t\tv:    vSt{Slice: []int{1, 2, 3}},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixMap+0x01 &&\n\t\t\t\t\td[1] == 0xa5 && d[2] == 'S' && d[3] == 'l' && d[4] == 'i' && d[5] == 'c' && d[6] == 'e' &&\n\t\t\t\t\td[7] == def.FixArray+0x03 && d[8] == 0x01 && d[9] == 0x02 && d[10] == 0x03\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"array all empty\",\n\t\t\tv:    vSt{},\n\t\t\tc: func(d []byte) bool {\n\t\t\t\treturn d[0] == def.FixArray+0x03\n\t\t\t},\n\t\t\tarray: true,\n\t\t},\n\t}\n\tfor _, c := range cases {\n\t\tt.Run(c.name, func(t *testing.T) {\n\t\t\tmsgpack.StructAsArray = c.array\n\t\t\tv := c.v\n\t\t\targ := encdecArg[rSt]{\n\t\t\t\tv:      v,\n\t\t\t\tc:      c.c,\n\t\t\t\tskipEq: true,\n\t\t\t\tvc: func(r rSt) error {\n\t\t\t\t\tif v.One != r.One || v.Two != r.Four || r.Hfn != false || !slices.Equal(v.Slice, r.Slice) {\n\t\t\t\t\t\treturn fmt.Errorf(\"error: %v, %v\", v, r)\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t},\n\t\t\t}\n\t\t\tencdec(t, arg)\n\t\t})\n\t}\n}\n\nfunc testStructArray(t *testing.T) {\n\ttype vSt struct {\n\t\tOne  int\n\t\tTwo  string\n\t\tTen  float32\n\t\tSkip float32\n\t}\n\ttype rSt struct {\n\t\tThree int\n\t\tFour  string\n\t\tTem   float32\n\t}\n\tv := vSt{One: 1, Two: \"2\", Ten: 1.234}\n\n\tmsgpack.StructAsArray = true\n\n\targ := encdecArg[rSt]{\n\t\tv: v,\n\t\tc: func(d []byte) bool {\n\t\t\treturn d[0] == def.FixArray+0x04\n\t\t},\n\t\tskipEq: true,\n\t\tvc: func(r rSt) error {\n\t\t\tif v.One != r.Three || v.Two != r.Four || v.Ten != r.Tem {\n\t\t\t\treturn fmt.Errorf(\"error: %v, %v\", v, r)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\tencdec(t, arg)\n}\n\nfunc testStructCode(t *testing.T) {\n\ttype st1 struct {\n\t\tInt int\n\t}\n\ttype st16 struct {\n\t\tI1  int\n\t\tI2  int\n\t\tI3  int\n\t\tI4  int\n\t\tI5  int\n\t\tI6  int\n\t\tI7  int\n\t\tI8  int\n\t\tI9  int\n\t\tI10 int\n\t\tI11 int\n\t\tI12 int\n\t\tI13 int\n\t\tI14 int\n\t\tI15 int\n\t\tI16 int\n\t}\n\tv1 := st1{Int: math.MinInt32}\n\tv16 := st16{\n\t\tI1: 1, I2: 2, I3: 3, I4: 4, I5: 5, I6: 6, I7: 7, I8: 8, I9: 9, I10: 10,\n\t\tI11: 11, I12: 12, I13: 13, I14: 14, I15: 15, I16: 16,\n\t}\n\n\tt.Run(\"Map\", func(t *testing.T) {\n\t\tt.Run(\"st1\", func(t *testing.T) {\n\t\t\targ := encdecArg[st1]{\n\t\t\t\tv: v1,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixMap <= d[0] && d[0] <= def.FixMap+0x0f\n\t\t\t\t},\n\t\t\t}\n\t\t\tencdec(t, arg)\n\t\t})\n\t\tt.Run(\"st16\", func(t *testing.T) {\n\t\t\targ := encdecArg[st16]{\n\t\t\t\tv: v16,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Map16\n\t\t\t\t},\n\t\t\t}\n\t\t\tencdec(t, arg)\n\t\t})\n\t})\n\n\tmsgpack.StructAsArray = true\n\tdefer func() {\n\t\tmsgpack.StructAsArray = false\n\t}()\n\n\tt.Run(\"Array\", func(t *testing.T) {\n\t\tt.Run(\"st1\", func(t *testing.T) {\n\t\t\targ := encdecArg[st1]{\n\t\t\t\tv: v1,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn def.FixArray <= d[0] && d[0] <= def.FixArray+0x0f\n\t\t\t\t},\n\t\t\t}\n\t\t\tencdec(t, arg)\n\t\t})\n\t\tt.Run(\"st16\", func(t *testing.T) {\n\t\t\targ := encdecArg[st16]{\n\t\t\t\tv: v16,\n\t\t\t\tc: func(d []byte) bool {\n\t\t\t\t\treturn d[0] == def.Array16\n\t\t\t\t},\n\t\t\t}\n\t\t\tencdec(t, arg)\n\t\t})\n\t})\n}\n\nfunc testStructUseCase(t *testing.T) {\n\ttype child3 struct {\n\t\tInt int\n\t}\n\ttype child2 struct {\n\t\tInt2Uint        map[int]uint\n\t\tFloat2Bool      map[float32]bool\n\t\tDuration2Struct map[time.Duration]child3\n\t}\n\ttype child struct {\n\t\tIntArray      []int\n\t\tUintArray     []uint\n\t\tFloatArray    []float32\n\t\tBoolArray     []bool\n\t\tStringArray   []string\n\t\tTimeArray     []time.Time\n\t\tDurationArray []time.Duration\n\t\tChild         child2\n\t}\n\ttype st struct {\n\t\tInt8        int8\n\t\tInt16       int16\n\t\tInt32       int32\n\t\tInt64       int64\n\t\tUint8       byte\n\t\tUint16      uint16\n\t\tUint32      uint32\n\t\tUint64      uint64\n\t\tFloat       float32\n\t\tDouble      float64\n\t\tBool        bool\n\t\tString      string\n\t\tPointer     *int\n\t\tNil         *int\n\t\tTime        time.Time\n\t\tDuration    time.Duration\n\t\tChild       child\n\t\tChild3Array []child3\n\t}\n\tp := rand.Int()\n\tv := &st{\n\t\tInt32:    -32,\n\t\tInt8:     -8,\n\t\tInt16:    -16,\n\t\tInt64:    -64,\n\t\tUint32:   32,\n\t\tUint8:    8,\n\t\tUint16:   16,\n\t\tUint64:   64,\n\t\tFloat:    1.23,\n\t\tDouble:   2.3456,\n\t\tBool:     true,\n\t\tString:   \"Parent\",\n\t\tPointer:  &p,\n\t\tNil:      nil,\n\t\tTime:     now,\n\t\tDuration: 123 * time.Second,\n\n\t\t// child\n\t\tChild: child{\n\t\t\tIntArray:      []int{-1, -2, -3, -4, -5},\n\t\t\tUintArray:     []uint{1, 2, 3, 4, 5},\n\t\t\tFloatArray:    []float32{-1.2, -3.4, -5.6, -7.8},\n\t\t\tBoolArray:     []bool{true, true, false, false, true},\n\t\t\tStringArray:   []string{\"str\", \"ing\", \"arr\", \"ay\"},\n\t\t\tTimeArray:     []time.Time{now, now, now},\n\t\t\tDurationArray: []time.Duration{1 * time.Nanosecond, 2 * time.Nanosecond},\n\n\t\t\t// childchild\n\t\t\tChild: child2{\n\t\t\t\tInt2Uint:        map[int]uint{-1: 2, -3: 4},\n\t\t\t\tFloat2Bool:      map[float32]bool{-1.1: true, -2.2: false},\n\t\t\t\tDuration2Struct: map[time.Duration]child3{1 * time.Hour: {Int: 1}, 2 * time.Hour: {Int: 2}},\n\t\t\t},\n\t\t},\n\n\t\tChild3Array: []child3{{Int: 100}, {Int: 1000000}, {Int: 100000000}},\n\t}\n\n\tmsgpack.StructAsArray = false\n\tencdec(t, encdecArg[st]{n: \"Map\", v: v})\n\n\tmsgpack.StructAsArray = true\n\tencdec(t, encdecArg[st]{n: \"Array\", v: v})\n\n\tmsgpack.StructAsArray = false\n}\n\nfunc testStructJump(t *testing.T) {\n\ttype v1 struct{ A interface{} }\n\ttype r1 struct{ B interface{} }\n\n\ta1 := make([]int, math.MaxUint16)\n\ta2 := make([]int, math.MaxUint16+1)\n\tm1 := map[string]int{}\n\tm2 := map[string]int{}\n\n\tfor i := range a1 {\n\t\ta1[i] = i\n\t\tm1[fmt.Sprint(i)] = 1\n\t}\n\tfor i := range a2 {\n\t\ta2[i] = i\n\t\tm2[fmt.Sprint(i)] = 1\n\t}\n\n\tvs := []v1{\n\t\t{A: true},\n\t\t{A: 1},\n\t\t{A: -1},\n\t\t{A: math.MaxUint8},\n\t\t{A: math.MinInt8},\n\t\t{A: math.MaxUint16},\n\t\t{A: math.MinInt16},\n\t\t{A: math.MaxUint32 + 1},\n\t\t{A: math.MinInt32 - 1},\n\t\t{A: math.MaxFloat64},\n\t\t{A: \"a\"},\n\t\t{A: strings.Repeat(\"b\", math.MaxUint8)},\n\t\t{A: []byte(strings.Repeat(\"c\", math.MaxUint8))},\n\t\t{A: strings.Repeat(\"e\", math.MaxUint16)},\n\t\t{A: []byte(strings.Repeat(\"d\", math.MaxUint16))},\n\t\t{A: strings.Repeat(\"f\", math.MaxUint16+1)},\n\t\t{A: []byte(strings.Repeat(\"g\", math.MaxUint16+1))},\n\t\t{A: []int{1}},\n\t\t{A: a1},\n\t\t{A: a2},\n\t\t{A: map[string]int{\"a\": 1}},\n\t\t{A: m1},\n\t\t{A: m2},\n\t\t{A: time.Unix(now.Unix(), int64(now.Nanosecond()))},\n\t}\n\tmsgpack.StructAsArray = false\n\n\tfor _, v := range vs {\n\t\tn := fmt.Sprint(v)\n\t\tif len(n) > 32 {\n\t\t\tn = n[:32]\n\t\t}\n\t\targ := encdecArg[r1]{\n\t\t\tn:      n,\n\t\t\tv:      v,\n\t\t\tskipEq: true,\n\t\t\tvc: func(r r1) error {\n\t\t\t\tif fmt.Sprint(v.A) == fmt.Sprint(r.B) {\n\t\t\t\t\treturn fmt.Errorf(\"value equal %v, %v\", v, r)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t}\n\t\tencdec(t, arg)\n\t}\n}\n\n/////////////////////////////////////////////////////////////\n\nfunc TestExt(t *testing.T) {\n\terr := msgpack.AddExtCoder(encoder, decoder)\n\tNoError(t, err)\n\terr = msgpack.AddExtStreamCoder(streamEncoder, streamDecoder)\n\tNoError(t, err)\n\n\t{\n\t\tv := ExtInt{\n\t\t\tInt8:        math.MinInt8,\n\t\t\tInt16:       math.MinInt16,\n\t\t\tInt32:       math.MinInt32,\n\t\t\tInt64:       math.MinInt32 - 1,\n\t\t\tUint8:       math.MaxUint8,\n\t\t\tUint16:      math.MaxUint16,\n\t\t\tUint32:      math.MaxUint32,\n\t\t\tUint64:      math.MaxUint32 + 1,\n\t\t\tByte2Int:    rand.Intn(math.MaxUint16),\n\t\t\tByte4Int:    rand.Intn(math.MaxInt32) - rand.Intn(math.MaxInt32-1),\n\t\t\tByte4Uint32: math.MaxUint32 - 1,\n\t\t\tBytes:       []byte{1, 2, 3}, // 3\n\t\t}\n\t\tencdec(t, encdecArg[ExtInt]{n: \"AddCoder\", v: v})\n\t}\n\n\terr = msgpack.RemoveExtCoder(encoder, decoder)\n\tNoError(t, err)\n\terr = msgpack.RemoveExtStreamCoder(streamEncoder, streamDecoder)\n\tNoError(t, err)\n\n\t{\n\t\tv := ExtInt{\n\t\t\tInt8:        math.MinInt8,\n\t\t\tInt16:       math.MinInt16,\n\t\t\tInt32:       math.MinInt32,\n\t\t\tInt64:       math.MinInt32 - 1,\n\t\t\tUint8:       math.MaxUint8,\n\t\t\tUint16:      math.MaxUint16,\n\t\t\tUint32:      math.MaxUint32,\n\t\t\tUint64:      math.MaxUint32 + 1,\n\t\t\tByte2Int:    rand.Intn(math.MaxUint16),\n\t\t\tByte4Int:    rand.Intn(math.MaxInt32) - rand.Intn(math.MaxInt32-1),\n\t\t\tByte4Uint32: math.MaxUint32 - 1,\n\t\t\tBytes:       []byte{4, 5, 6}, // 3\n\t\t}\n\t\tencdec(t, encdecArg[ExtInt]{n: \"RemoveCoder\", v: v})\n\t}\n\n\tt.Run(\"ErrorExtCoder\", func(t *testing.T) {\n\t\terr = msgpack.AddExtCoder(&testExt2Encoder{}, &testExt2Decoder{})\n\t\tErrorContains(t, err, \"code different\")\n\n\t\terr = msgpack.RemoveExtCoder(&testExt2Encoder{}, &testExt2Decoder{})\n\t\tErrorContains(t, err, \"code different\")\n\n\t\terr = msgpack.AddExtStreamCoder(&testExt2StreamEncoder{}, &testExt2StreamDecoder{})\n\t\tErrorContains(t, err, \"code different\")\n\n\t\terr = msgpack.RemoveExtStreamCoder(&testExt2StreamEncoder{}, &testExt2StreamDecoder{})\n\t\tErrorContains(t, err, \"code different\")\n\t})\n}\n\ntype ExtStruct struct {\n\tInt8        int8\n\tInt16       int16\n\tInt32       int32\n\tInt64       int64\n\tUint8       uint8\n\tUint16      uint16\n\tUint32      uint32\n\tUint64      uint64\n\tByte2Int    int\n\tByte4Int    int\n\tByte4Uint32 uint32\n\tBytes       []byte // 3\n}\ntype ExtInt ExtStruct\n\nvar decoder = new(testDecoder)\n\ntype testDecoder struct {\n\text.DecoderCommon\n}\n\nvar _ ext.Decoder = (*testDecoder)(nil)\n\nvar extIntCode = int8(-2)\n\nfunc (td *testDecoder) Code() int8 {\n\treturn extIntCode\n}\n\nfunc (td *testDecoder) IsType(offset int, d *[]byte) bool {\n\tcode, offset := td.ReadSize1(offset, d)\n\tif code == def.Ext8 {\n\t\tc, offset := td.ReadSize1(offset, d)\n\t\tt, _ := td.ReadSize1(offset, d)\n\t\treturn c == 15+15+10+3 && int8(t) == td.Code()\n\t}\n\treturn false\n}\n\nfunc (td *testDecoder) AsValue(offset int, k reflect.Kind, d *[]byte) (interface{}, int, error) {\n\tcode, offset := td.ReadSize1(offset, d)\n\n\tswitch code {\n\tcase def.Ext8:\n\t\t// size\n\t\t_, offset = td.ReadSize1(offset, d)\n\t\t// code\n\t\t_, offset = td.ReadSize1(offset, d)\n\t\ti8, offset := td.ReadSize1(offset, d)\n\t\ti16, offset := td.ReadSize2(offset, d)\n\t\ti32, offset := td.ReadSize4(offset, d)\n\t\ti64, offset := td.ReadSize8(offset, d)\n\t\tu8, offset := td.ReadSize1(offset, d)\n\t\tu16, offset := td.ReadSize2(offset, d)\n\t\tu32, offset := td.ReadSize4(offset, d)\n\t\tu64, offset := td.ReadSize8(offset, d)\n\t\tb16, offset := td.ReadSize2(offset, d)\n\t\tb32, offset := td.ReadSize4(offset, d)\n\t\tbu32, offset := td.ReadSize4(offset, d)\n\t\tbs, offset := td.ReadSizeN(offset, 3, d)\n\t\treturn ExtInt{\n\t\t\tInt8:        int8(i8),\n\t\t\tInt16:       int16(binary.BigEndian.Uint16(i16)),\n\t\t\tInt32:       int32(binary.BigEndian.Uint32(i32)),\n\t\t\tInt64:       int64(binary.BigEndian.Uint64(i64)),\n\t\t\tUint8:       u8,\n\t\t\tUint16:      binary.BigEndian.Uint16(u16),\n\t\t\tUint32:      binary.BigEndian.Uint32(u32),\n\t\t\tUint64:      binary.BigEndian.Uint64(u64),\n\t\t\tByte2Int:    int(binary.BigEndian.Uint16(b16)),\n\t\t\tByte4Int:    int(int32(binary.BigEndian.Uint32(b32))),\n\t\t\tByte4Uint32: binary.BigEndian.Uint32(bu32),\n\t\t\tBytes:       bs,\n\t\t}, offset, nil\n\t}\n\n\treturn ExtInt{}, 0, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", code, k)\n}\n\nvar streamDecoder = new(testStreamDecoder)\n\ntype testStreamDecoder struct{}\n\nvar _ ext.StreamDecoder = (*testStreamDecoder)(nil)\n\nfunc (td *testStreamDecoder) Code() int8 {\n\treturn extIntCode\n}\n\nfunc (td *testStreamDecoder) IsType(code byte, innerType int8, dataLength int) bool {\n\tif code == def.Ext8 {\n\t\treturn dataLength == 15+15+10+3 && innerType == td.Code()\n\t}\n\treturn false\n}\n\nfunc (td *testStreamDecoder) ToValue(code byte, data []byte, k reflect.Kind) (any, error) {\n\tswitch code {\n\tcase def.Ext8:\n\t\ti8 := data[:1]\n\t\ti16 := data[1:3]\n\t\ti32 := data[3:7]\n\t\ti64 := data[7:15]\n\t\tu8 := data[15:16]\n\t\tu16 := data[16:18]\n\t\tu32 := data[18:22]\n\t\tu64 := data[22:30]\n\t\tb16 := data[30:32]\n\t\tb32 := data[32:36]\n\t\tbu32 := data[36:40]\n\t\tbs := data[40:43]\n\t\treturn ExtInt{\n\t\t\tInt8:        int8(i8[0]),\n\t\t\tInt16:       int16(binary.BigEndian.Uint16(i16)),\n\t\t\tInt32:       int32(binary.BigEndian.Uint32(i32)),\n\t\t\tInt64:       int64(binary.BigEndian.Uint64(i64)),\n\t\t\tUint8:       u8[0],\n\t\t\tUint16:      binary.BigEndian.Uint16(u16),\n\t\t\tUint32:      binary.BigEndian.Uint32(u32),\n\t\t\tUint64:      binary.BigEndian.Uint64(u64),\n\t\t\tByte2Int:    int(binary.BigEndian.Uint16(b16)),\n\t\t\tByte4Int:    int(int32(binary.BigEndian.Uint32(b32))),\n\t\t\tByte4Uint32: binary.BigEndian.Uint32(bu32),\n\t\t\tBytes:       bs,\n\t\t}, nil\n\t}\n\n\treturn ExtInt{}, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", code, k)\n}\n\nvar encoder = new(testEncoder)\n\ntype testEncoder struct {\n\text.EncoderCommon\n}\n\nvar _ ext.Encoder = (*testEncoder)(nil)\n\nfunc (s *testEncoder) Code() int8 {\n\treturn extIntCode\n}\n\nfunc (s *testEncoder) Type() reflect.Type {\n\treturn reflect.TypeOf(ExtInt{})\n}\n\nfunc (s *testEncoder) CalcByteSize(value reflect.Value) (int, error) {\n\tt := value.Interface().(ExtInt)\n\treturn def.Byte1 + def.Byte1 + def.Byte1 + 15 + 15 + 10 + len(t.Bytes), nil\n}\n\nfunc (s *testEncoder) WriteToBytes(value reflect.Value, offset int, bytes *[]byte) int {\n\tt := value.Interface().(ExtInt)\n\toffset = s.SetByte1Int(def.Ext8, offset, bytes)\n\toffset = s.SetByte1Int(15+15+10+len(t.Bytes), offset, bytes)\n\toffset = s.SetByte1Int(int(s.Code()), offset, bytes)\n\n\toffset = s.SetByte1Int64(int64(t.Int8), offset, bytes)\n\toffset = s.SetByte2Int64(int64(t.Int16), offset, bytes)\n\toffset = s.SetByte4Int64(int64(t.Int32), offset, bytes)\n\toffset = s.SetByte8Int64(t.Int64, offset, bytes)\n\n\toffset = s.SetByte1Uint64(uint64(t.Uint8), offset, bytes)\n\toffset = s.SetByte2Uint64(uint64(t.Uint16), offset, bytes)\n\toffset = s.SetByte4Uint64(uint64(t.Uint32), offset, bytes)\n\toffset = s.SetByte8Uint64(t.Uint64, offset, bytes)\n\n\toffset = s.SetByte2Int(t.Byte2Int, offset, bytes)\n\toffset = s.SetByte4Int(t.Byte4Int, offset, bytes)\n\n\toffset = s.SetByte4Uint32(t.Byte4Uint32, offset, bytes)\n\toffset = s.SetBytes(t.Bytes, offset, bytes)\n\treturn offset\n}\n\nvar streamEncoder = new(testStreamEncoder)\n\ntype testStreamEncoder struct{}\n\nvar _ ext.StreamEncoder = (*testStreamEncoder)(nil)\n\nfunc (s *testStreamEncoder) Code() int8 {\n\treturn extIntCode\n}\n\nfunc (s *testStreamEncoder) Type() reflect.Type {\n\treturn reflect.TypeOf(ExtInt{})\n}\n\nfunc (s *testStreamEncoder) Write(w ext.StreamWriter, value reflect.Value) error {\n\tt := value.Interface().(ExtInt)\n\tif err := w.WriteByte1Int(def.Ext8); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(15 + 15 + 10 + len(t.Bytes)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(int(s.Code())); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.WriteByte1Int64(int64(t.Int8)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte2Int64(int64(t.Int16)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte4Int64(int64(t.Int32)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte8Int64(t.Int64); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.WriteByte1Uint64(uint64(t.Uint8)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte2Uint64(uint64(t.Uint16)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte4Uint64(uint64(t.Uint32)); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte8Uint64(t.Uint64); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.WriteByte2Int(t.Byte2Int); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte4Int(t.Byte4Int); err != nil {\n\t\treturn err\n\t}\n\n\tif err := w.WriteByte4Uint32(t.Byte4Uint32); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteBytes(t.Bytes); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n/////////////////////////////////////////////////////////\n\ntype Ext2Struct struct {\n\tV int\n}\ntype Ext2Int Ext2Struct\n\nconst (\n\ttestExt2DecoderCode = 3\n\ttestExt2EncoderCode = -3\n)\n\ntype testExt2Decoder struct{}\n\nvar _ ext.Decoder = (*testExt2Decoder)(nil)\n\nfunc (td *testExt2Decoder) Code() int8 {\n\treturn testExt2DecoderCode\n}\n\nfunc (td *testExt2Decoder) IsType(_ int, _ *[]byte) bool {\n\treturn false\n}\n\nfunc (td *testExt2Decoder) AsValue(_ int, k reflect.Kind, _ *[]byte) (interface{}, int, error) {\n\treturn Ext2Int{}, 0, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", td.Code(), k)\n}\n\ntype testExt2StreamDecoder struct{}\n\nvar _ ext.StreamDecoder = (*testExt2StreamDecoder)(nil)\n\nfunc (td *testExt2StreamDecoder) Code() int8 {\n\treturn testExt2DecoderCode\n}\n\nfunc (td *testExt2StreamDecoder) IsType(_ byte, _ int8, _ int) bool {\n\treturn false\n}\n\nfunc (td *testExt2StreamDecoder) ToValue(_ byte, _ []byte, k reflect.Kind) (any, error) {\n\treturn Ext2Int{}, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", td.Code(), k)\n}\n\ntype testExt2Encoder struct {\n\text.EncoderCommon\n}\n\nvar _ ext.Encoder = (*testExt2Encoder)(nil)\n\nfunc (s *testExt2Encoder) Code() int8 {\n\treturn testExt2EncoderCode\n}\n\nfunc (s *testExt2Encoder) Type() reflect.Type {\n\treturn reflect.TypeOf(ExtInt{})\n}\n\nfunc (s *testExt2Encoder) CalcByteSize(_ reflect.Value) (int, error) {\n\treturn 0, nil\n}\n\nfunc (s *testExt2Encoder) WriteToBytes(_ reflect.Value, offset int, _ *[]byte) int {\n\treturn offset\n}\n\ntype testExt2StreamEncoder struct{}\n\nvar _ ext.StreamEncoder = (*testExt2StreamEncoder)(nil)\n\nfunc (s *testExt2StreamEncoder) Code() int8 {\n\treturn testExt2EncoderCode\n}\n\nfunc (s *testExt2StreamEncoder) Type() reflect.Type {\n\treturn reflect.TypeOf(ExtInt{})\n}\n\nfunc (s *testExt2StreamEncoder) Write(_ ext.StreamWriter, _ reflect.Value) error {\n\treturn fmt.Errorf(\"should not reach this line!! code %x\", s.Code())\n}\n\n/////////////////////////////////////////////////////////\n\ntype Issue44Struct1 struct {\n\tBin8  []byte\n\tBin16 []byte\n\tBin32 []byte\n}\n\ntype Issue44Struct2 struct {\n\tS1 *Issue44Struct1\n\tS2 *Issue44Struct2 // should not blow up on recursion\n\n\tBin8  []byte\n\tBin16 []byte\n\tBin32 []byte\n}\n\ntype Issue44Struct3 struct {\n\tBin8  string\n\tBin16 string\n\tBin32 string\n}\n\ntype Issue44Struct4 struct {\n\tS1 *Issue44Struct3\n\tS2 *Issue44Struct4 // should not blow up on recursion\n\n\tBin8  string\n\tBin16 string\n\tBin32 string\n}\n\n// https://github.com/shamaton/msgpack/issues/44\nfunc TestIssue44(t *testing.T) {\n\tv := &Issue44Struct2{\n\t\tS1: &Issue44Struct1{\n\t\t\tBin8:  []byte(\"a\"),\n\t\t\tBin16: []byte(strings.Repeat(\"b\", 256)),\n\t\t\tBin32: []byte(strings.Repeat(\"c\", 256*256)),\n\t\t},\n\t\tS2: &Issue44Struct2{\n\t\t\tBin8:  []byte(\"d\"),\n\t\t\tBin16: []byte(strings.Repeat(\"e\", 256)),\n\t\t\tBin32: []byte(strings.Repeat(\"f\", 256*256)),\n\t\t},\n\t\tBin8:  []byte(\"g\"),\n\t\tBin16: []byte(strings.Repeat(\"h\", 256)),\n\t\tBin32: []byte(strings.Repeat(\"i\", 256*256)),\n\t}\n\n\tt.Run(\"byte slice\", func(t *testing.T) {\n\t\tb, err := msgpack.Marshal(v)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tbuf := bytes.NewBuffer(nil)\n\t\tif err = msgpack.MarshalWrite(buf, v); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(buf.Bytes(), b) {\n\t\t\tt.Fatalf(\"Marshal is not equal simple: [% 02x], streaming: [% 02x]\", buf.Bytes(), b)\n\t\t}\n\n\t\tv2 := &Issue44Struct2{}\n\t\tif err = msgpack.Unmarshal(b, v2); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(v, v2) {\n\t\t\tt.Fatalf(\"Unmarshal is not equal orig: '%#v', got '%#v'\", v, v2)\n\t\t}\n\n\t\tv3 := &Issue44Struct2{}\n\t\tif err = msgpack.UnmarshalRead(buf, v3); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(v, v3) {\n\t\t\tt.Fatalf(\"Unmarshal Streaming is not equal orig: '%#v', got '%#v'\", v, v3)\n\t\t}\n\t})\n\tt.Run(\"string\", func(t *testing.T) {\n\t\tvv := &Issue44Struct4{\n\t\t\tS1: &Issue44Struct3{\n\t\t\t\tBin8:  \"a\",\n\t\t\t\tBin16: strings.Repeat(\"b\", 256),\n\t\t\t\tBin32: strings.Repeat(\"c\", 256*256),\n\t\t\t},\n\t\t\tS2: &Issue44Struct4{\n\t\t\t\tBin8:  \"d\",\n\t\t\t\tBin16: strings.Repeat(\"e\", 256),\n\t\t\t\tBin32: strings.Repeat(\"f\", 256*256),\n\t\t\t},\n\t\t\tBin8:  \"g\",\n\t\t\tBin16: strings.Repeat(\"h\", 256),\n\t\t\tBin32: strings.Repeat(\"i\", 256*256),\n\t\t}\n\n\t\tb, err := msgpack.Marshal(vv)\n\t\tif err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tbuf := bytes.NewBuffer(nil)\n\t\tif err = msgpack.MarshalWrite(buf, vv); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(buf.Bytes(), b) {\n\t\t\tt.Fatalf(\"Marshal is not equal simple: [% 02x], streaming: [% 02x]\", buf.Bytes(), b)\n\t\t}\n\n\t\tv2 := &Issue44Struct2{}\n\t\tif err = msgpack.Unmarshal(b, v2); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(v, v2) {\n\t\t\tt.Fatalf(\"Unmarshal is not equal orig: '%#v', got '%#v'\", v, v2)\n\t\t}\n\n\t\tv3 := &Issue44Struct2{}\n\t\tif err = msgpack.UnmarshalRead(buf, v3); err != nil {\n\t\t\tpanic(err)\n\t\t}\n\t\tif !reflect.DeepEqual(v, v3) {\n\t\t\tt.Fatalf(\"Unmarshal Streaming is not equal orig: '%#v', got '%#v'\", v, v3)\n\t\t}\n\t})\n}\n\n/////////////////////////////////////////////////////////\n\ntype (\n\tchecker      func(data []byte) bool\n\tmarshaller   func(v any) ([]byte, error)\n\tunmarshaller func(data []byte, v any) error\n)\n\nvar marshallers = []struct {\n\tname string\n\tm    marshaller\n}{\n\t{\"Marshal\", msgpack.Marshal},\n\t{\"MarshalWrite\", func(v any) ([]byte, error) {\n\t\tbuf := bytes.Buffer{}\n\t\terr := msgpack.MarshalWrite(&buf, v)\n\t\treturn buf.Bytes(), err\n\t}},\n}\n\nvar unmarshallers = []struct {\n\tname string\n\tu    unmarshaller\n}{\n\t{\"Unmarshal\", msgpack.Unmarshal},\n\t{\"UnmarshalRead\", func(data []byte, v any) error {\n\t\treturn msgpack.UnmarshalRead(bytes.NewReader(data), v)\n\t}},\n}\n\ntype encdecArg[T any] struct {\n\tn      string\n\tv      any\n\tr      T\n\tc      checker\n\tskipEq bool\n\tvc     func(t T) error\n\te      string\n}\n\nfunc encdec[T any](t *testing.T, args ...encdecArg[T]) {\n\tt.Helper()\n\n\tfor _, arg := range args {\n\t\tt.Run(arg.n, func(t *testing.T) {\n\t\t\tfor _, m := range marshallers {\n\t\t\t\tfor _, u := range unmarshallers {\n\t\t\t\t\tt.Run(m.name+\"-\"+u.name, func(t *testing.T) {\n\t\t\t\t\t\tvar e error\n\t\t\t\t\t\tdefer func() {\n\t\t\t\t\t\t\tif e != nil {\n\t\t\t\t\t\t\t\tif len(arg.e) < 1 {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"unexpected error: %v\", e)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif !strings.Contains(e.Error(), arg.e) {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"error does not contain '%s'. err: %v\", arg.e, e)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tif len(arg.e) > 0 {\n\t\t\t\t\t\t\t\t\tt.Fatalf(\"error should occur, but nil. expected: %s\", arg.e)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}()\n\n\t\t\t\t\t\td, err := m.m(arg.v)\n\t\t\t\t\t\tif err != nil {\n\t\t\t\t\t\t\te = err\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif arg.c != nil && !arg.c(d) {\n\t\t\t\t\t\t\te = fmt.Errorf(\"different %s\", hex.Dump(d))\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif err = u.u(d, &arg.r); err != nil {\n\t\t\t\t\t\t\te = err\n\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif !arg.skipEq {\n\t\t\t\t\t\t\tif err = equalCheck(arg.v, arg.r); err != nil {\n\t\t\t\t\t\t\t\te = err\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif arg.vc != nil {\n\t\t\t\t\t\t\tif err = arg.vc(arg.r); err != nil {\n\t\t\t\t\t\t\t\te = err\n\t\t\t\t\t\t\t\treturn\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\n// for check value\nfunc getValue(v interface{}) interface{} {\n\trv := reflect.ValueOf(v)\n\tif rv.Kind() == reflect.Ptr {\n\t\trv = rv.Elem()\n\t}\n\tif rv.Kind() == reflect.Ptr {\n\t\trv = rv.Elem()\n\t}\n\tif rv.Kind() == reflect.Invalid {\n\t\treturn nil\n\t}\n\treturn rv.Interface()\n}\n\nfunc equalCheck(in, out interface{}) error {\n\ti := getValue(in)\n\to := getValue(out)\n\tif !reflect.DeepEqual(i, o) {\n\t\treturn errors.New(fmt.Sprint(\"value different \\n[in]:\", i, \" \\n[out]:\", o))\n\t}\n\treturn nil\n}\n\nfunc NoError(t *testing.T, err error) {\n\tt.Helper()\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n}\n\nfunc ErrorContains(t *testing.T, err error, errStr string) {\n\tif err == nil {\n\t\tt.Fatal(\"error should occur\")\n\t}\n\tif !strings.Contains(err.Error(), errStr) {\n\t\tt.Fatalf(\"error does not contain '%s'. err: %v\", errStr, err)\n\t}\n}\n"
  },
  {
    "path": "testdata/crashers/007424b0caabdaf653d7efeb3ce6c1c127f628c6",
    "content": "0000000"
  },
  {
    "path": "testdata/crashers/01d1844ec3cdec0e8d60d81fcded73f920270e9c",
    "content": "000000"
  },
  {
    "path": "testdata/crashers/049b2af75fc4ee7160c7ea9bad41a5167b501d32",
    "content": "000"
  },
  {
    "path": "testdata/crashers/051d081de15ae4680b4156046787aae72ae0adcc",
    "content": "0"
  },
  {
    "path": "testdata/crashers/063fea9d12105a80ee56a482aac428543fcf8d49",
    "content": "0000000000000"
  },
  {
    "path": "testdata/crashers/080c57e02ab7e704e2a2e93aad7674a574dc9d69",
    "content": "000000000"
  },
  {
    "path": "testdata/crashers/0d45579ce9ef9c1ca6e945d3f21ad31097f0c3c0",
    "content": "0000000000000000000000000"
  },
  {
    "path": "testdata/crashers/0f7994b18fb75394c81005c925dd1ae153ad57ad",
    "content": "000"
  },
  {
    "path": "testdata/crashers/121a9af889bd4ca2266be5a4f680d3bead8d02d6",
    "content": ""
  },
  {
    "path": "testdata/crashers/19eb9972c2a406f15bbae850ac33b42ebd88f7a7",
    "content": "00000000000"
  },
  {
    "path": "testdata/crashers/1a3492dbf0b80d08f12ce49c620239e48b74c08c",
    "content": "0000000000"
  },
  {
    "path": "testdata/crashers/1ae8bba51072f9ff2bdf587596cfb0edf8a5cd12",
    "content": "0000000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/1b274070ce90f8ccdf0fc33a4afd4e1455766f8b",
    "content": ""
  },
  {
    "path": "testdata/crashers/1d49f1635e901393bf65a263810508bea7ec9d51",
    "content": "00"
  },
  {
    "path": "testdata/crashers/1e2c5c5ac7754f3e3fd858ce644b6621da2f4d03",
    "content": "0000000000"
  },
  {
    "path": "testdata/crashers/236cfc19fdc31facdfe306e479a52bb3c08cb540",
    "content": "00000"
  },
  {
    "path": "testdata/crashers/2478b7ed4fe72f5030a22146ecf365adba0dc780",
    "content": "0000"
  },
  {
    "path": "testdata/crashers/24b5d7868ba6df6da0e26365e10fc15bcf72cca6",
    "content": "00"
  },
  {
    "path": "testdata/crashers/255b827f8c0a593c5ee7610cdbd31c656f166a37",
    "content": "00"
  },
  {
    "path": "testdata/crashers/2a8cbfc34aa4aefa008e9e18276e32fa5e8f56d8",
    "content": "0000"
  },
  {
    "path": "testdata/crashers/2ba0c664eff181eeb2b101f60c5ca66397f4c386",
    "content": "00000"
  },
  {
    "path": "testdata/crashers/2c34cfd27e783430e24c2af05361af3540b4d6ad",
    "content": "0"
  },
  {
    "path": "testdata/crashers/2c4dd5af849b5cda2b7769dc52706e5fa746de73",
    "content": "00"
  },
  {
    "path": "testdata/crashers/2cdb9f5adf53f1054ce8e6ceba007396ce6b734b",
    "content": "00000000"
  },
  {
    "path": "testdata/crashers/30140397fe38ee61f01eff44b5cfa48285e47889",
    "content": ""
  },
  {
    "path": "testdata/crashers/321500ed9a1796dca3d559d8f129ed31a8790035",
    "content": "000000000000000000000"
  },
  {
    "path": "testdata/crashers/3219e4d65ac8671a452900514bc3c7aea2e71be3",
    "content": "00000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/36a5cc93968072de9d120643033589df4f316997",
    "content": "0000000000000000"
  },
  {
    "path": "testdata/crashers/3abe9a29f2b95f34da65d88b969e58f4b46b6309",
    "content": "0000000000000000000"
  },
  {
    "path": "testdata/crashers/3e5a9e8b50fcdcbe08f8138de6b95b5cd5b69bf2",
    "content": "00000000000000000"
  },
  {
    "path": "testdata/crashers/3f0062c38d031b015f1a8bb82bd370b65d5ca35a",
    "content": "0000000000000000"
  },
  {
    "path": "testdata/crashers/4670a8e0d21a624c0d42fd6dc76ef408d2b4e195",
    "content": "0"
  },
  {
    "path": "testdata/crashers/47393c214b8f5a3d3c098e3985d24bd1e8d82a85",
    "content": "000000"
  },
  {
    "path": "testdata/crashers/48947b6f943721ce84ef81e887a16bde2759f7ab",
    "content": "000000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/49989f6a8875777519c822a92c821cbb95bfc360",
    "content": "000000000"
  },
  {
    "path": "testdata/crashers/4aaffe149efbd0ab6f122a4dc6e9e9aa0a602799",
    "content": "00000000000000"
  },
  {
    "path": "testdata/crashers/4b65bf83d9b292f65bb5d1b056d68a4811732ef3",
    "content": "0"
  },
  {
    "path": "testdata/crashers/4c156cb396c967d81bf3615cbd5ba74221a9c622",
    "content": "NilBoolãIntМFloat32@I\u000eVFloat64\t!\u0012oStringf"
  },
  {
    "path": "testdata/crashers/4fb8cfeaaac80a1c829b22a43089ef470bcfe5b8",
    "content": ""
  },
  {
    "path": "testdata/crashers/502804b3665c5eb935d6f66e7677f75242f516bb",
    "content": "00000000000000000"
  },
  {
    "path": "testdata/crashers/56ff31c3b76d37929e45071a36ca5aa0bc386e09",
    "content": "0000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/5bc56c0f00870625b5016a8d242ebe5c2a58802b",
    "content": "00000000000000000000000000"
  },
  {
    "path": "testdata/crashers/5e8c489081abe671d760e1840b526f43bc7e6aa3",
    "content": "000000000000000000000@I\u000eVFloat64\t!\u0012oString"
  },
  {
    "path": "testdata/crashers/5ec02b6349403b523d33576c7e2de27fb345edf0",
    "content": "0000"
  },
  {
    "path": "testdata/crashers/6351ed5a9ac9cbb709ad15b4193edb52b8d37e84",
    "content": "0"
  },
  {
    "path": "testdata/crashers/673480b070ea0508c3510627c81a4b519fb7d2f5",
    "content": "0"
  },
  {
    "path": "testdata/crashers/683f06bff1a62b73193352f06a7194f0bf60ffb8",
    "content": "000000000000000000000"
  },
  {
    "path": "testdata/crashers/68a5e75e9b42928454b320fe8f64ea107e61f60f",
    "content": "000000"
  },
  {
    "path": "testdata/crashers/68be1e92e40e77926e1d9a5c2d800da023f6a4e9",
    "content": "0000000000000000000000000"
  },
  {
    "path": "testdata/crashers/6b7395dabfc4d5a76e276f222c64c4bf7771ffb7",
    "content": "00000000000"
  },
  {
    "path": "testdata/crashers/707235f5352edef615d64d00d83fcf92c9dffa57",
    "content": "00000000000000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/71819c849b41ee2f4a5b08321b9fc8bf21326ddf",
    "content": "0"
  },
  {
    "path": "testdata/crashers/730377e1be92f426661e434d4f1cf20a10e16991",
    "content": "00"
  },
  {
    "path": "testdata/crashers/73728d128f628772a64990a72340d9fd7987e29b",
    "content": "0"
  },
  {
    "path": "testdata/crashers/73cc8fe38acd489c2b1fed0a66222aac4e04cc98",
    "content": "00000000000000000000"
  },
  {
    "path": "testdata/crashers/74fe2a4034b08b5ecb014b2596e7f21ab55ea729",
    "content": ""
  },
  {
    "path": "testdata/crashers/79aed363731b28a60abf16190df3d60fd1d88e54",
    "content": "00000"
  },
  {
    "path": "testdata/crashers/7a1d04a0253fbb956c8119c40dc917cb460dabb0",
    "content": "NilBool£Int\u0003Float32@I\u000eVFloat64\t!\u0012oStri"
  },
  {
    "path": "testdata/crashers/7a96d469f87b8c0fa00a944669469db9c8246714",
    "content": "000"
  },
  {
    "path": "testdata/crashers/7b21df3bb234142e7b2dfc81f84eb621f9c7a617",
    "content": "000000000000"
  },
  {
    "path": "testdata/crashers/8611c05469f8e623e1e035e578d1d50ff2a54e11",
    "content": "0000"
  },
  {
    "path": "testdata/crashers/861648845b817281bffa42d8ca1c46443cef5cd8",
    "content": "000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/86f9eb6ebcae33f4d3663f90adf430f6d7b5e57c",
    "content": "00000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/8a90278d26f66fd78e4e38da237c201707bf7ab3",
    "content": "0000"
  },
  {
    "path": "testdata/crashers/8de4d4284d8227a753986639b1d6e698bc683d8a",
    "content": "000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/8e4cb24fea75d067b0d9a5598fdeb66490777000",
    "content": "000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/964ac50bf26ecb3d0253e5e288484776bbf0abdf",
    "content": "000000000"
  },
  {
    "path": "testdata/crashers/98d2aa10f9c5e6d9b1a6fb3dcc6583aa5631882a",
    "content": "0000000"
  },
  {
    "path": "testdata/crashers/9ae8dabd9621f44592757414f83d26df04e55bca",
    "content": "000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/9b982d96821f364683a7a9cc2495cccc7d5bb705",
    "content": "0000000000000000000000000"
  },
  {
    "path": "testdata/crashers/9ded617601151e2a3dde370fe42f206f6dd38f42",
    "content": "00"
  },
  {
    "path": "testdata/crashers/9e2487eee9a3b9f415c36aed893ed2da3d3bace6",
    "content": ""
  },
  {
    "path": "testdata/crashers/9f733d3115030339e63922d6e35920f9dba1207e",
    "content": "00000000000000000000000"
  },
  {
    "path": "testdata/crashers/a0bb3eef10ad343fdf00adc2c7a2fab0e4dd679f",
    "content": "00000000000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/a611449daf97af318de6495f22c907ecb1f83076",
    "content": "0000000"
  },
  {
    "path": "testdata/crashers/a8c1d81ff50e57abc043f8bbcc87ce0e123285a7",
    "content": "00000000000"
  },
  {
    "path": "testdata/crashers/aa1a1bd5b7953186af6c9f2e8f757247fdffa9ce",
    "content": "NilBoolãIntМFloat32\u001e@I\u000eVFloat64˪\t!\u0012oStringfoo"
  },
  {
    "path": "testdata/crashers/b7471e724dfba20b71265eb8f8315ff5add6ccad",
    "content": ""
  },
  {
    "path": "testdata/crashers/b9df95e660f5bc5d66f2ad7c49339cb3d62d2a99",
    "content": "00000000"
  },
  {
    "path": "testdata/crashers/bc22b685617fec260cb94cb1ab9822e393924a35",
    "content": "0000000000000000000"
  },
  {
    "path": "testdata/crashers/c1a1ed4a1a749c9e38da920c66a4c425e169566b",
    "content": "0000000000000"
  },
  {
    "path": "testdata/crashers/c41c1a47577c69284cae60d785ddb240dc3739db",
    "content": "0000000000000000000000000"
  },
  {
    "path": "testdata/crashers/c4ee5a4632d4f9a51ba57a70cfa2cae832460857",
    "content": "000"
  },
  {
    "path": "testdata/crashers/c9388db618e924f41e419ccddc068b443657ffa4",
    "content": ""
  },
  {
    "path": "testdata/crashers/ce7c29332788aa93186591aceaad307ffbdf9735",
    "content": "00"
  },
  {
    "path": "testdata/crashers/da39a3ee5e6b4b0d3255bfef95601890afd80709",
    "content": ""
  },
  {
    "path": "testdata/crashers/df0c1e8999119939ea4f07c2daeb57b868bb0719",
    "content": "000"
  },
  {
    "path": "testdata/crashers/e2d6b6d4d9b8346067d2252bfbcefff99a24ed21",
    "content": "0000000"
  },
  {
    "path": "testdata/crashers/e62ebb1ab82b8cf630f2b393d89c367dd0b25924",
    "content": "000000000"
  },
  {
    "path": "testdata/crashers/e906f0d49a1b91f0b93d64c36bf5a764924ce45f",
    "content": "000000000000000"
  },
  {
    "path": "testdata/crashers/ead2a4908cb1750ae6f619656ebf74b153edab25",
    "content": "000000000000000000"
  },
  {
    "path": "testdata/crashers/eae5f62c3fc844275194f17d530d26ceafcf941b",
    "content": "0"
  },
  {
    "path": "testdata/crashers/edb2dfda8124a5c5935dd1d449f493e868d9f9c0",
    "content": "000000000000000000000000000"
  },
  {
    "path": "testdata/crashers/f023f3307ef4fe6b9d8ea2c0ea4fb3bc954f2888",
    "content": "00000000000000000000000"
  },
  {
    "path": "testdata/crashers/f1ec5f959e75412b01270a861f1f1ecdfda1cb9c",
    "content": "0"
  },
  {
    "path": "testdata/crashers/f4aaa2a22e1038e4abda4636592d330fc9fc693b",
    "content": "000"
  },
  {
    "path": "testdata/crashers/f7cb64ffc60ab1f9e0aecbd9c560af1d743fe314",
    "content": "00000"
  },
  {
    "path": "testdata/crashers/f86f8b65ecd59bddb8df4850b538b863021ea14a",
    "content": "000000000000000000"
  },
  {
    "path": "testdata/crashers/f87f13e299cb66c824237b662a5623647d3af86e",
    "content": "00000000000"
  },
  {
    "path": "testdata/crashers/fa85f6319c6d39864527629c9b25c4b086f398b7",
    "content": "00000000000000"
  },
  {
    "path": "testdata/crashers/fc7077d7ef5f47af404835e9ea6401f258b27f83",
    "content": "0000000000000000000000000000000"
  },
  {
    "path": "time/decode.go",
    "content": "package time\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nvar zero = time.Unix(0, 0)\n\nvar Decoder = new(timeDecoder)\n\ntype timeDecoder struct {\n\text.DecoderCommon\n}\n\nvar _ ext.Decoder = (*timeDecoder)(nil)\n\nfunc (td *timeDecoder) Code() int8 {\n\treturn def.TimeStamp\n}\n\nfunc (td *timeDecoder) readSize1Safe(index int, d *[]byte) (byte, int, bool) {\n\tif len(*d) < index+def.Byte1 {\n\t\treturn 0, 0, false\n\t}\n\tv, next := td.ReadSize1(index, d)\n\treturn v, next, true\n}\n\nfunc (td *timeDecoder) readSize4Safe(index int, d *[]byte) ([]byte, int, bool) {\n\tif len(*d) < index+def.Byte4 {\n\t\treturn nil, 0, false\n\t}\n\tv, next := td.ReadSize4(index, d)\n\treturn v, next, true\n}\n\nfunc (td *timeDecoder) readSize8Safe(index int, d *[]byte) ([]byte, int, bool) {\n\tif len(*d) < index+def.Byte8 {\n\t\treturn nil, 0, false\n\t}\n\tv, next := td.ReadSize8(index, d)\n\treturn v, next, true\n}\n\nfunc (td *timeDecoder) IsType(offset int, d *[]byte) bool {\n\tcode, offset, ok := td.readSize1Safe(offset, d)\n\tif !ok {\n\t\treturn false\n\t}\n\n\tswitch code {\n\tcase def.Fixext4:\n\t\tt, _, ok := td.readSize1Safe(offset, d)\n\t\tif !ok || int8(t) != td.Code() {\n\t\t\treturn false\n\t\t}\n\t\t_, _, ok = td.readSize4Safe(offset+def.Byte1, d)\n\t\treturn ok\n\tcase def.Fixext8:\n\t\tt, _, ok := td.readSize1Safe(offset, d)\n\t\tif !ok || int8(t) != td.Code() {\n\t\t\treturn false\n\t\t}\n\t\t_, _, ok = td.readSize8Safe(offset+def.Byte1, d)\n\t\treturn ok\n\tcase def.Ext8:\n\t\tl, offset, ok := td.readSize1Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\tt, _, ok := td.readSize1Safe(offset, d)\n\t\tif !ok || l != 12 || int8(t) != td.Code() {\n\t\t\treturn false\n\t\t}\n\t\t_, _, ok = td.readSize4Safe(offset+def.Byte1, d)\n\t\tif !ok {\n\t\t\treturn false\n\t\t}\n\t\t_, _, ok = td.readSize8Safe(offset+def.Byte1+def.Byte4, d)\n\t\treturn ok\n\t}\n\treturn false\n}\n\nfunc (td *timeDecoder) AsValue(offset int, k reflect.Kind, d *[]byte) (interface{}, int, error) {\n\tcode, offset, ok := td.readSize1Safe(offset, d)\n\tif !ok {\n\t\treturn zero, 0, def.ErrTooShortBytes\n\t}\n\n\tswitch code {\n\tcase def.Fixext4:\n\t\t_, offset, ok = td.readSize1Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tbs, offset, ok := td.readSize4Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tv := time.Unix(int64(binary.BigEndian.Uint32(bs)), 0)\n\t\tif decodeAsLocal {\n\t\t\treturn v, offset, nil\n\t\t}\n\t\treturn v.UTC(), offset, nil\n\n\tcase def.Fixext8:\n\t\t_, offset, ok = td.readSize1Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tbs, offset, ok := td.readSize8Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tdata64 := binary.BigEndian.Uint64(bs)\n\t\tnano := int64(data64 >> 34)\n\t\tif nano > 999999999 {\n\t\t\treturn zero, 0, fmt.Errorf(\"in timestamp 64 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\tv := time.Unix(int64(data64&0x00000003ffffffff), nano)\n\t\tif decodeAsLocal {\n\t\t\treturn v, offset, nil\n\t\t}\n\t\treturn v.UTC(), offset, nil\n\n\tcase def.Ext8:\n\t\t_, offset, ok = td.readSize1Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\t_, offset, ok = td.readSize1Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tnanobs, offset, ok := td.readSize4Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tsecbs, offset, ok := td.readSize8Safe(offset, d)\n\t\tif !ok {\n\t\t\treturn zero, 0, def.ErrTooShortBytes\n\t\t}\n\t\tnano := binary.BigEndian.Uint32(nanobs)\n\t\tif nano > 999999999 {\n\t\t\treturn zero, 0, fmt.Errorf(\"in timestamp 96 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\tsec := binary.BigEndian.Uint64(secbs)\n\t\tv := time.Unix(int64(sec), int64(nano))\n\t\tif decodeAsLocal {\n\t\t\treturn v, offset, nil\n\t\t}\n\t\treturn v.UTC(), offset, nil\n\t}\n\n\treturn zero, 0, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", code, k)\n}\n"
  },
  {
    "path": "time/decode_stream.go",
    "content": "package time\n\nimport (\n\t\"encoding/binary\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nvar StreamDecoder = new(timeStreamDecoder)\n\ntype timeStreamDecoder struct{}\n\nvar _ ext.StreamDecoder = (*timeStreamDecoder)(nil)\n\nfunc (td *timeStreamDecoder) Code() int8 {\n\treturn def.TimeStamp\n}\n\nfunc (td *timeStreamDecoder) IsType(code byte, innerType int8, dataLength int) bool {\n\tswitch code {\n\tcase def.Fixext4, def.Fixext8:\n\t\treturn innerType == td.Code()\n\tcase def.Ext8:\n\t\treturn innerType == td.Code() && dataLength == 12\n\t}\n\treturn false\n}\n\nfunc (td *timeStreamDecoder) ToValue(code byte, data []byte, k reflect.Kind) (interface{}, error) {\n\tswitch code {\n\tcase def.Fixext4:\n\t\tif len(data) < def.Byte4 {\n\t\t\treturn zero, def.ErrTooShortBytes\n\t\t}\n\t\tv := time.Unix(int64(binary.BigEndian.Uint32(data)), 0)\n\t\tif decodeAsLocal {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn v.UTC(), nil\n\n\tcase def.Fixext8:\n\t\tif len(data) < def.Byte8 {\n\t\t\treturn zero, def.ErrTooShortBytes\n\t\t}\n\t\tdata64 := binary.BigEndian.Uint64(data)\n\t\tnano := int64(data64 >> 34)\n\t\tif nano > 999999999 {\n\t\t\treturn zero, fmt.Errorf(\"in timestamp 64 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\tv := time.Unix(int64(data64&0x00000003ffffffff), nano)\n\t\tif decodeAsLocal {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn v.UTC(), nil\n\n\tcase def.Ext8:\n\t\tif len(data) < def.Byte4+def.Byte8 {\n\t\t\treturn zero, def.ErrTooShortBytes\n\t\t}\n\t\tnano := binary.BigEndian.Uint32(data[:4])\n\t\tif nano > 999999999 {\n\t\t\treturn zero, fmt.Errorf(\"in timestamp 96 formats, nanoseconds must not be larger than 999999999 : %d\", nano)\n\t\t}\n\t\tsec := binary.BigEndian.Uint64(data[4:12])\n\t\tv := time.Unix(int64(sec), int64(nano))\n\t\tif decodeAsLocal {\n\t\t\treturn v, nil\n\t\t}\n\t\treturn v.UTC(), nil\n\t}\n\n\treturn zero, fmt.Errorf(\"should not reach this line!! code %x decoding %v\", code, k)\n}\n"
  },
  {
    "path": "time/decode_stream_test.go",
    "content": "package time\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestStreamDecodeCode(t *testing.T) {\n\tdecoder := StreamDecoder\n\tcode := decoder.Code()\n\ttu.Equal(t, code, def.TimeStamp)\n}\n\nfunc TestStreamDecodeIsType(t *testing.T) {\n\tdecoder := StreamDecoder\n\tts := int8(def.TimeStamp)\n\n\ttests := []struct {\n\t\tname       string\n\t\tcode       byte\n\t\tinnerType  int8\n\t\tdataLength int\n\t\texpected   bool\n\t}{\n\t\t{\n\t\t\tname:       \"Fixext4 with TimeStamp\",\n\t\t\tcode:       def.Fixext4,\n\t\t\tinnerType:  ts,\n\t\t\tdataLength: 4,\n\t\t\texpected:   true,\n\t\t},\n\t\t{\n\t\t\tname:       \"Fixext4 with wrong type\",\n\t\t\tcode:       def.Fixext4,\n\t\t\tinnerType:  0x00,\n\t\t\tdataLength: 4,\n\t\t\texpected:   false,\n\t\t},\n\t\t{\n\t\t\tname:       \"Fixext8 with TimeStamp\",\n\t\t\tcode:       def.Fixext8,\n\t\t\tinnerType:  ts,\n\t\t\tdataLength: 8,\n\t\t\texpected:   true,\n\t\t},\n\t\t{\n\t\t\tname:       \"Fixext8 with wrong type\",\n\t\t\tcode:       def.Fixext8,\n\t\t\tinnerType:  0x00,\n\t\t\tdataLength: 8,\n\t\t\texpected:   false,\n\t\t},\n\t\t{\n\t\t\tname:       \"Ext8 with length 12 and TimeStamp\",\n\t\t\tcode:       def.Ext8,\n\t\t\tinnerType:  ts,\n\t\t\tdataLength: 12,\n\t\t\texpected:   true,\n\t\t},\n\t\t{\n\t\t\tname:       \"Ext8 with wrong length\",\n\t\t\tcode:       def.Ext8,\n\t\t\tinnerType:  ts,\n\t\t\tdataLength: 10,\n\t\t\texpected:   false,\n\t\t},\n\t\t{\n\t\t\tname:       \"Ext8 with wrong type\",\n\t\t\tcode:       def.Ext8,\n\t\t\tinnerType:  0x00,\n\t\t\tdataLength: 12,\n\t\t\texpected:   false,\n\t\t},\n\t\t{\n\t\t\tname:       \"Wrong format\",\n\t\t\tcode:       def.Nil,\n\t\t\tinnerType:  ts,\n\t\t\tdataLength: 0,\n\t\t\texpected:   false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := decoder.IsType(tt.code, tt.innerType, tt.dataLength)\n\t\t\ttu.Equal(t, result, tt.expected)\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeToValueFixext4(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttests := []struct {\n\t\tname     string\n\t\tunixTime int64\n\t}{\n\t\t{\n\t\t\tname:     \"Unix epoch\",\n\t\t\tunixTime: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"Small timestamp\",\n\t\t\tunixTime: 1000,\n\t\t},\n\t\t{\n\t\t\tname:     \"Large timestamp\",\n\t\t\tunixTime: 1<<32 - 1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Fixext4 format data (without header)\n\t\t\tdata := make([]byte, 4)\n\t\t\tbinary.BigEndian.PutUint32(data, uint32(tt.unixTime))\n\n\t\t\tvalue, err := decoder.ToValue(def.Fixext4, data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, timeValue.Nanosecond(), 0)\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeToValueFixext8(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttests := []struct {\n\t\tname       string\n\t\tunixTime   int64\n\t\tnanosecond int64\n\t}{\n\t\t{\n\t\t\tname:       \"With small nanoseconds\",\n\t\t\tunixTime:   1000,\n\t\t\tnanosecond: 123456789,\n\t\t},\n\t\t{\n\t\t\tname:       \"With max nanoseconds\",\n\t\t\tunixTime:   67890,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t\t{\n\t\t\tname:       \"Boundary at 2^34-1\",\n\t\t\tunixTime:   (1 << 34) - 1,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Fixext8 format data (without header)\n\t\t\tdata := make([]byte, 8)\n\n\t\t\t// Pack nanoseconds in upper 30 bits and seconds in lower 34 bits\n\t\t\tdata64 := uint64(tt.nanosecond)<<34 | uint64(tt.unixTime)\n\t\t\tbinary.BigEndian.PutUint64(data, data64)\n\n\t\t\tvalue, err := decoder.ToValue(def.Fixext8, data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, int64(timeValue.Nanosecond()), tt.nanosecond)\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeToValueExt8(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttests := []struct {\n\t\tname       string\n\t\tunixTime   int64\n\t\tnanosecond int32\n\t}{\n\t\t{\n\t\t\tname:       \"Large timestamp at 2^34\",\n\t\t\tunixTime:   1 << 34,\n\t\t\tnanosecond: 123456789,\n\t\t},\n\t\t{\n\t\t\tname:       \"Very large timestamp\",\n\t\t\tunixTime:   253402300799,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Ext8 format data (without header)\n\t\t\tdata := make([]byte, 12)\n\t\t\tbinary.BigEndian.PutUint32(data[:4], uint32(tt.nanosecond))\n\t\t\tbinary.BigEndian.PutUint64(data[4:12], uint64(tt.unixTime))\n\n\t\t\tvalue, err := decoder.ToValue(def.Ext8, data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, int64(timeValue.Nanosecond()), int64(tt.nanosecond))\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeToValueErrors(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\tt.Run(\"Fixext8 with invalid nanoseconds\", func(t *testing.T) {\n\t\tdata := make([]byte, 8)\n\n\t\t// Set nanoseconds > 999999999 (invalid)\n\t\tinvalidNano := uint64(1000000000)\n\t\tdata64 := invalidNano<<34 | 1000\n\t\tbinary.BigEndian.PutUint64(data, data64)\n\n\t\t_, err := decoder.ToValue(def.Fixext8, data, reflect.TypeOf(time.Time{}).Kind())\n\t\ttu.ErrorContains(t, err, \"in timestamp 64 formats\")\n\t})\n\n\tt.Run(\"Ext8 with invalid nanoseconds\", func(t *testing.T) {\n\t\tdata := make([]byte, 12)\n\n\t\t// Set nanoseconds > 999999999 (invalid)\n\t\tbinary.BigEndian.PutUint32(data[:4], 1000000000)\n\t\tbinary.BigEndian.PutUint64(data[4:12], 1000)\n\n\t\t_, err := decoder.ToValue(def.Ext8, data, reflect.TypeOf(time.Time{}).Kind())\n\t\ttu.ErrorContains(t, err, \"in timestamp 96 formats\")\n\t})\n\n\tt.Run(\"Invalid format code\", func(t *testing.T) {\n\t\tdata := []byte{0}\n\n\t\t_, err := decoder.ToValue(def.Nil, data, reflect.TypeOf(time.Time{}).Kind())\n\t\ttu.ErrorContains(t, err, \"should not reach\")\n\t})\n}\n\nfunc TestStreamDecodeToValueTooShort(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttestcases := []struct {\n\t\tname string\n\t\tcode byte\n\t\tdata []byte\n\t}{\n\t\t{name: \"Fixext4\", code: def.Fixext4, data: []byte{}},\n\t\t{name: \"Fixext8\", code: def.Fixext8, data: []byte{}},\n\t\t{name: \"Ext8\", code: def.Ext8, data: []byte{}},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t_, err := decoder.ToValue(tc.code, tc.data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.IsError(t, err, def.ErrTooShortBytes)\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeTimezone(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttests := []struct {\n\t\tname       string\n\t\ttime       time.Time\n\t\tformat     byte\n\t\tcreateData func(time.Time) []byte\n\t}{\n\t\t{\n\t\t\tname:   \"Fixext4\",\n\t\t\ttime:   time.Unix(1000, 0),\n\t\t\tformat: def.Fixext4,\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 4)\n\t\t\t\tbinary.BigEndian.PutUint32(data, uint32(testTime.Unix()))\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"Fixext8\",\n\t\t\ttime:   time.Unix(1000, 123456789),\n\t\t\tformat: def.Fixext8,\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 8)\n\t\t\t\tdata64 := uint64(testTime.Nanosecond())<<34 | uint64(testTime.Unix())\n\t\t\t\tbinary.BigEndian.PutUint64(data, data64)\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname:   \"Ext8\",\n\t\t\ttime:   time.Unix(1<<34, 123456789),\n\t\t\tformat: def.Ext8,\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 12)\n\t\t\t\tbinary.BigEndian.PutUint32(data[:4], uint32(testTime.Nanosecond()))\n\t\t\t\tbinary.BigEndian.PutUint64(data[4:12], uint64(testTime.Unix()))\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name+\" - Decode as local (default)\", func(t *testing.T) {\n\t\t\t// Set to local timezone\n\t\t\tSetDecodedAsLocal(true)\n\t\t\tdefer SetDecodedAsLocal(true) // Reset to default\n\n\t\t\tdata := tt.createData(tt.time)\n\t\t\tvalue, err := decoder.ToValue(tt.format, data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\t// Should be in local timezone\n\t\t\ttu.Equal(t, timeValue.Location(), time.Local)\n\t\t})\n\n\t\tt.Run(tt.name+\" - Decode as UTC\", func(t *testing.T) {\n\t\t\t// Set to UTC timezone\n\t\t\tSetDecodedAsLocal(false)\n\t\t\tdefer SetDecodedAsLocal(true) // Reset to default\n\n\t\t\tdata := tt.createData(tt.time)\n\t\t\tvalue, err := decoder.ToValue(tt.format, data, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\t// Should be in UTC timezone\n\t\t\ttu.Equal(t, timeValue.Location(), time.UTC)\n\t\t})\n\t}\n}\n\nfunc TestStreamDecodeRoundTrip(t *testing.T) {\n\tdecoder := StreamDecoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Fixext4 format\",\n\t\t\ttime: time.Unix(1000, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Fixext8 format\",\n\t\t\ttime: time.Unix(67890, 123456789),\n\t\t},\n\t\t{\n\t\t\tname: \"Ext8 format\",\n\t\t\ttime: time.Unix(17179869184, 987654321),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Use encode_stream to encode\n\t\t\tvar encodedData []byte\n\t\t\tsecs := uint64(tt.time.Unix())\n\t\t\tif secs>>34 == 0 {\n\t\t\t\tdata := uint64(tt.time.Nanosecond())<<34 | secs\n\t\t\t\tif data&0xffffffff00000000 == 0 {\n\t\t\t\t\t// Fixext4\n\t\t\t\t\tencodedData = make([]byte, 4)\n\t\t\t\t\tbinary.BigEndian.PutUint32(encodedData, uint32(data))\n\n\t\t\t\t\t// Decode\n\t\t\t\t\tdecodedValue, err := decoder.ToValue(def.Fixext4, encodedData, reflect.TypeOf(time.Time{}).Kind())\n\t\t\t\t\ttu.NoError(t, err)\n\n\t\t\t\t\tdecodedTime, ok := decodedValue.(time.Time)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", decodedValue)\n\t\t\t\t\t}\n\n\t\t\t\t\ttu.Equal(t, decodedTime.Unix(), tt.time.Unix())\n\t\t\t\t\ttu.Equal(t, decodedTime.Nanosecond(), tt.time.Nanosecond())\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Fixext8\n\t\t\t\tencodedData = make([]byte, 8)\n\t\t\t\tbinary.BigEndian.PutUint64(encodedData, data)\n\n\t\t\t\t// Decode\n\t\t\t\tdecodedValue, err := decoder.ToValue(def.Fixext8, encodedData, reflect.TypeOf(time.Time{}).Kind())\n\t\t\t\ttu.NoError(t, err)\n\n\t\t\t\tdecodedTime, ok := decodedValue.(time.Time)\n\t\t\t\tif !ok {\n\t\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", decodedValue)\n\t\t\t\t}\n\n\t\t\t\ttu.Equal(t, decodedTime.Unix(), tt.time.Unix())\n\t\t\t\ttu.Equal(t, decodedTime.Nanosecond(), tt.time.Nanosecond())\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Ext8\n\t\t\tencodedData = make([]byte, 12)\n\t\t\tbinary.BigEndian.PutUint32(encodedData[:4], uint32(tt.time.Nanosecond()))\n\t\t\tbinary.BigEndian.PutUint64(encodedData[4:12], secs)\n\n\t\t\t// Decode\n\t\t\tdecodedValue, err := decoder.ToValue(def.Ext8, encodedData, reflect.TypeOf(time.Time{}).Kind())\n\t\t\ttu.NoError(t, err)\n\n\t\t\tdecodedTime, ok := decodedValue.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", decodedValue)\n\t\t\t}\n\n\t\t\ttu.Equal(t, decodedTime.Unix(), tt.time.Unix())\n\t\t\ttu.Equal(t, decodedTime.Nanosecond(), tt.time.Nanosecond())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "time/decode_test.go",
    "content": "package time\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestDecodeCode(t *testing.T) {\n\tdecoder := Decoder\n\tcode := decoder.Code()\n\ttu.Equal(t, code, def.TimeStamp)\n}\n\nfunc TestDecodeIsType(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname     string\n\t\tdata     []byte\n\t\texpected bool\n\t}{\n\t\t{\n\t\t\tname:     \"Fixext4 with TimeStamp\",\n\t\t\tdata:     []byte{def.Fixext4, byte(ts), 0, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext4 with wrong type\",\n\t\t\tdata:     []byte{def.Fixext4, 0x00, 0, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext8 with TimeStamp\",\n\t\t\tdata:     []byte{def.Fixext8, byte(ts), 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext8 with wrong type\",\n\t\t\tdata:     []byte{def.Fixext8, 0x00, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Ext8 with length 12 and TimeStamp\",\n\t\t\tdata:     []byte{def.Ext8, 12, byte(ts), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\texpected: true,\n\t\t},\n\t\t{\n\t\t\tname:     \"Ext8 with wrong length\",\n\t\t\tdata:     []byte{def.Ext8, 10, byte(ts), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Ext8 with wrong type\",\n\t\t\tdata:     []byte{def.Ext8, 12, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\n\t\t\texpected: false,\n\t\t},\n\t\t{\n\t\t\tname:     \"Wrong format\",\n\t\t\tdata:     []byte{def.Nil},\n\t\t\texpected: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := decoder.IsType(0, &tt.data)\n\t\t\ttu.Equal(t, result, tt.expected)\n\t\t})\n\t}\n}\n\nfunc TestDecodeIsTypeShortInput(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttestcases := []struct {\n\t\tname string\n\t\tdata []byte\n\t}{\n\t\t{name: \"Fixext4 missing type\", data: []byte{def.Fixext4}},\n\t\t{name: \"Fixext8 missing type\", data: []byte{def.Fixext8}},\n\t\t{name: \"Ext8 missing length\", data: []byte{def.Ext8}},\n\t\t{name: \"Ext8 missing type\", data: []byte{def.Ext8, 12}},\n\t\t{name: \"Fixext4 missing payload\", data: []byte{def.Fixext4, byte(ts)}},\n\t\t{name: \"Fixext8 missing payload\", data: []byte{def.Fixext8, byte(ts)}},\n\t\t{name: \"Ext8 missing payload\", data: []byte{def.Ext8, 12, byte(ts)}},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\ttu.Equal(t, decoder.IsType(0, &tc.data), false)\n\t\t})\n\t}\n}\n\nfunc TestDecodeAsValueFixext4(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname     string\n\t\tunixTime int64\n\t}{\n\t\t{\n\t\t\tname:     \"Unix epoch\",\n\t\t\tunixTime: 0,\n\t\t},\n\t\t{\n\t\t\tname:     \"Small timestamp\",\n\t\t\tunixTime: 1000,\n\t\t},\n\t\t{\n\t\t\tname:     \"Large timestamp\",\n\t\t\tunixTime: 1<<32 - 1,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Fixext4 format data\n\t\t\tdata := make([]byte, 6)\n\t\t\tdata[0] = def.Fixext4\n\t\t\tdata[1] = byte(ts)\n\t\t\tbinary.BigEndian.PutUint32(data[2:], uint32(tt.unixTime))\n\n\t\t\tvalue, offset, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, offset, 6)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, timeValue.Nanosecond(), 0)\n\t\t})\n\t}\n}\n\nfunc TestDecodeAsValueFixext8(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname       string\n\t\tunixTime   int64\n\t\tnanosecond int64\n\t}{\n\t\t{\n\t\t\tname:       \"With small nanoseconds\",\n\t\t\tunixTime:   1000,\n\t\t\tnanosecond: 123456789,\n\t\t},\n\t\t{\n\t\t\tname:       \"With max nanoseconds\",\n\t\t\tunixTime:   67890,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t\t{\n\t\t\tname:       \"Boundary at 2^34-1\",\n\t\t\tunixTime:   (1 << 34) - 1,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Fixext8 format data\n\t\t\tdata := make([]byte, 10)\n\t\t\tdata[0] = def.Fixext8\n\t\t\tdata[1] = byte(ts)\n\n\t\t\t// Pack nanoseconds in upper 30 bits and seconds in lower 34 bits\n\t\t\tdata64 := uint64(tt.nanosecond)<<34 | uint64(tt.unixTime)\n\t\t\tbinary.BigEndian.PutUint64(data[2:], data64)\n\n\t\t\tvalue, offset, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, offset, 10)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, int64(timeValue.Nanosecond()), tt.nanosecond)\n\t\t})\n\t}\n}\n\nfunc TestDecodeAsValueExt8(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname       string\n\t\tunixTime   int64\n\t\tnanosecond int32\n\t}{\n\t\t{\n\t\t\tname:       \"Large timestamp at 2^34\",\n\t\t\tunixTime:   1 << 34,\n\t\t\tnanosecond: 123456789,\n\t\t},\n\t\t{\n\t\t\tname:       \"Very large timestamp\",\n\t\t\tunixTime:   253402300799,\n\t\t\tnanosecond: 999999999,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Create Ext8 format data\n\t\t\tdata := make([]byte, 15)\n\t\t\tdata[0] = def.Ext8\n\t\t\tdata[1] = 12 // length\n\t\t\tdata[2] = byte(ts)\n\t\t\tbinary.BigEndian.PutUint32(data[3:], uint32(tt.nanosecond))\n\t\t\tbinary.BigEndian.PutUint64(data[7:], uint64(tt.unixTime))\n\n\t\t\tvalue, offset, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, offset, 15)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\ttu.Equal(t, timeValue.Unix(), tt.unixTime)\n\t\t\ttu.Equal(t, int64(timeValue.Nanosecond()), int64(tt.nanosecond))\n\t\t})\n\t}\n}\n\nfunc TestDecodeAsValueErrors(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\tt.Run(\"Fixext8 with invalid nanoseconds\", func(t *testing.T) {\n\t\tdata := make([]byte, 10)\n\t\tdata[0] = def.Fixext8\n\t\tdata[1] = byte(ts)\n\n\t\t// Set nanoseconds > 999999999 (invalid)\n\t\tinvalidNano := uint64(1000000000)\n\t\tdata64 := invalidNano<<34 | 1000\n\t\tbinary.BigEndian.PutUint64(data[2:], data64)\n\n\t\t_, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\ttu.ErrorContains(t, err, \"in timestamp 64 formats\")\n\t})\n\n\tt.Run(\"Ext8 with invalid nanoseconds\", func(t *testing.T) {\n\t\tdata := make([]byte, 15)\n\t\tdata[0] = def.Ext8\n\t\tdata[1] = 12\n\t\tdata[2] = byte(ts)\n\n\t\t// Set nanoseconds > 999999999 (invalid)\n\t\tbinary.BigEndian.PutUint32(data[3:], 1000000000)\n\t\tbinary.BigEndian.PutUint64(data[7:], 1000)\n\n\t\t_, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\ttu.ErrorContains(t, err, \"in timestamp 96 formats\")\n\t})\n\n\tt.Run(\"Invalid format code\", func(t *testing.T) {\n\t\tdata := []byte{def.Nil}\n\n\t\t_, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\ttu.ErrorContains(t, err, \"should not reach\")\n\t})\n}\n\nfunc TestDecodeAsValueTooShort(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttestcases := []struct {\n\t\tname string\n\t\tdata []byte\n\t}{\n\t\t{name: \"Fixext4 missing type\", data: []byte{def.Fixext4}},\n\t\t{name: \"Fixext4 missing payload\", data: []byte{def.Fixext4, byte(ts)}},\n\t\t{name: \"Fixext8 missing type\", data: []byte{def.Fixext8}},\n\t\t{name: \"Fixext8 missing payload\", data: []byte{def.Fixext8, byte(ts)}},\n\t\t{name: \"Ext8 missing length\", data: []byte{def.Ext8}},\n\t\t{name: \"Ext8 missing type\", data: []byte{def.Ext8, 12}},\n\t\t{name: \"Ext8 missing payload\", data: []byte{def.Ext8, 12, byte(ts)}},\n\t}\n\n\tfor _, tc := range testcases {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\t_, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &tc.data)\n\t\t\ttu.IsError(t, err, def.ErrTooShortBytes)\n\t\t})\n\t}\n}\n\nfunc TestDecodeTimezone(t *testing.T) {\n\tdecoder := Decoder\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname       string\n\t\ttime       time.Time\n\t\tcreateData func(time.Time) []byte\n\t}{\n\t\t{\n\t\t\tname: \"Fixext4\",\n\t\t\ttime: time.Unix(1000, 0),\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 6)\n\t\t\t\tdata[0] = def.Fixext4\n\t\t\t\tdata[1] = byte(ts)\n\t\t\t\tbinary.BigEndian.PutUint32(data[2:], uint32(testTime.Unix()))\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Fixext8\",\n\t\t\ttime: time.Unix(1000, 123456789),\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 10)\n\t\t\t\tdata[0] = def.Fixext8\n\t\t\t\tdata[1] = byte(ts)\n\t\t\t\tdata64 := uint64(testTime.Nanosecond())<<34 | uint64(testTime.Unix())\n\t\t\t\tbinary.BigEndian.PutUint64(data[2:], data64)\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"Ext8\",\n\t\t\ttime: time.Unix(1<<34, 123456789),\n\t\t\tcreateData: func(testTime time.Time) []byte {\n\t\t\t\tdata := make([]byte, 15)\n\t\t\t\tdata[0] = def.Ext8\n\t\t\t\tdata[1] = 12\n\t\t\t\tdata[2] = byte(ts)\n\t\t\t\tbinary.BigEndian.PutUint32(data[3:], uint32(testTime.Nanosecond()))\n\t\t\t\tbinary.BigEndian.PutUint64(data[7:], uint64(testTime.Unix()))\n\t\t\t\treturn data\n\t\t\t},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name+\" - Decode as local (default)\", func(t *testing.T) {\n\t\t\t// Set to local timezone\n\t\t\tSetDecodedAsLocal(true)\n\t\t\tdefer SetDecodedAsLocal(true) // Reset to default\n\n\t\t\tdata := tt.createData(tt.time)\n\t\t\tvalue, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\t// Should be in local timezone\n\t\t\ttu.Equal(t, timeValue.Location(), time.Local)\n\t\t})\n\n\t\tt.Run(tt.name+\" - Decode as UTC\", func(t *testing.T) {\n\t\t\t// Set to UTC timezone\n\t\t\tSetDecodedAsLocal(false)\n\t\t\tdefer SetDecodedAsLocal(true) // Reset to default\n\n\t\t\tdata := tt.createData(tt.time)\n\t\t\tvalue, _, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &data)\n\t\t\ttu.NoError(t, err)\n\n\t\t\ttimeValue, ok := value.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", value)\n\t\t\t}\n\n\t\t\t// Should be in UTC timezone\n\t\t\ttu.Equal(t, timeValue.Location(), time.UTC)\n\t\t})\n\t}\n}\n\nfunc TestDecodeRoundTrip(t *testing.T) {\n\tencoder := Encoder\n\tdecoder := Decoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Fixext4 format\",\n\t\t\ttime: time.Unix(1000, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Fixext8 format\",\n\t\t\ttime: time.Unix(67890, 123456789),\n\t\t},\n\t\t{\n\t\t\tname: \"Ext8 format\",\n\t\t\ttime: time.Unix(17179869184, 987654321),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// Encode\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tbytes := make([]byte, size)\n\t\t\tencoder.WriteToBytes(value, 0, &bytes)\n\n\t\t\t// Decode\n\t\t\tdecodedValue, offset, err := decoder.AsValue(0, reflect.TypeOf(time.Time{}).Kind(), &bytes)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, offset, size)\n\n\t\t\tdecodedTime, ok := decodedValue.(time.Time)\n\t\t\tif !ok {\n\t\t\t\tt.Fatalf(\"Expected time.Time, got %T\", decodedValue)\n\t\t\t}\n\n\t\t\t// Compare Unix time and nanoseconds\n\t\t\ttu.Equal(t, decodedTime.Unix(), tt.time.Unix())\n\t\t\ttu.Equal(t, decodedTime.Nanosecond(), tt.time.Nanosecond())\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "time/encode.go",
    "content": "package time\n\nimport (\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nvar Encoder = new(timeEncoder)\n\ntype timeEncoder struct {\n\text.EncoderCommon\n}\n\nvar typeOf = reflect.TypeOf(time.Time{})\n\nfunc (td *timeEncoder) Code() int8 {\n\treturn def.TimeStamp\n}\n\nfunc (s *timeEncoder) Type() reflect.Type {\n\treturn typeOf\n}\n\nfunc (s *timeEncoder) CalcByteSize(value reflect.Value) (int, error) {\n\tt := value.Interface().(time.Time)\n\tsecs := uint64(t.Unix())\n\tif secs>>34 == 0 {\n\t\tdata := uint64(t.Nanosecond())<<34 | secs\n\t\tif data&0xffffffff00000000 == 0 {\n\t\t\treturn def.Byte1 + def.Byte1 + def.Byte4, nil\n\t\t}\n\t\treturn def.Byte1 + def.Byte1 + def.Byte8, nil\n\t}\n\n\treturn def.Byte1 + def.Byte1 + def.Byte1 + def.Byte4 + def.Byte8, nil\n}\n\nfunc (s *timeEncoder) WriteToBytes(value reflect.Value, offset int, bytes *[]byte) int {\n\tt := value.Interface().(time.Time)\n\n\tsecs := uint64(t.Unix())\n\tif secs>>34 == 0 {\n\t\tdata := uint64(t.Nanosecond())<<34 | secs\n\t\tif data&0xffffffff00000000 == 0 {\n\t\t\toffset = s.SetByte1Int(def.Fixext4, offset, bytes)\n\t\t\toffset = s.SetByte1Int(def.TimeStamp, offset, bytes)\n\t\t\toffset = s.SetByte4Uint64(data, offset, bytes)\n\t\t\treturn offset\n\t\t}\n\n\t\toffset = s.SetByte1Int(def.Fixext8, offset, bytes)\n\t\toffset = s.SetByte1Int(def.TimeStamp, offset, bytes)\n\t\toffset = s.SetByte8Uint64(data, offset, bytes)\n\t\treturn offset\n\t}\n\n\toffset = s.SetByte1Int(def.Ext8, offset, bytes)\n\toffset = s.SetByte1Int(12, offset, bytes)\n\toffset = s.SetByte1Int(def.TimeStamp, offset, bytes)\n\toffset = s.SetByte4Int(t.Nanosecond(), offset, bytes)\n\toffset = s.SetByte8Uint64(secs, offset, bytes)\n\treturn offset\n}\n"
  },
  {
    "path": "time/encode_stream.go",
    "content": "package time\n\nimport (\n\t\"reflect\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n)\n\nvar StreamEncoder = new(timeStreamEncoder)\n\ntype timeStreamEncoder struct{}\n\nvar _ ext.StreamEncoder = (*timeStreamEncoder)(nil)\n\nfunc (timeStreamEncoder) Code() int8 {\n\treturn def.TimeStamp\n}\n\nfunc (timeStreamEncoder) Type() reflect.Type {\n\treturn typeOf\n}\n\nfunc (e timeStreamEncoder) Write(w ext.StreamWriter, value reflect.Value) error {\n\tt := value.Interface().(time.Time)\n\n\tsecs := uint64(t.Unix())\n\tif secs>>34 == 0 {\n\t\tdata := uint64(t.Nanosecond())<<34 | secs\n\t\tif data&0xffffffff00000000 == 0 {\n\t\t\tif err := w.WriteByte1Int(def.Fixext4); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := w.WriteByte1Int(def.TimeStamp); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := w.WriteByte4Uint64(data); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\n\t\tif err := w.WriteByte1Int(def.Fixext8); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := w.WriteByte1Int(def.TimeStamp); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tif err := w.WriteByte8Uint64(data); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn nil\n\t}\n\n\tif err := w.WriteByte1Int(def.Ext8); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(12); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte1Int(def.TimeStamp); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte4Int(t.Nanosecond()); err != nil {\n\t\treturn err\n\t}\n\tif err := w.WriteByte8Uint64(secs); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "time/encode_stream_test.go",
    "content": "package time\n\nimport (\n\t\"bytes\"\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\t\"github.com/shamaton/msgpack/v3/ext\"\n\t\"github.com/shamaton/msgpack/v3/internal/common\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestStreamCode(t *testing.T) {\n\tencoder := StreamEncoder\n\tcode := encoder.Code()\n\ttu.Equal(t, code, def.TimeStamp)\n}\n\nfunc TestStreamType(t *testing.T) {\n\tencoder := StreamEncoder\n\ttyp := encoder.Type()\n\texpected := reflect.TypeOf(time.Time{})\n\ttu.Equal(t, typ, expected)\n}\n\nfunc TestStreamWrite(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\ttime           time.Time\n\t\texpectedLen    int\n\t\texpectedFormat string\n\t}{\n\t\t{\n\t\t\tname:           \"Fixext4 format (32-bit timestamp, no nanoseconds)\",\n\t\t\ttime:           time.Unix(0, 0),\n\t\t\texpectedLen:    6, // 1 (Fixext4) + 1 (TimeStamp) + 4 (data)\n\t\t\texpectedFormat: \"fixext4\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Fixext4 format (small timestamp, no nanoseconds)\",\n\t\t\ttime:           time.Unix(1000, 0),\n\t\t\texpectedLen:    6,\n\t\t\texpectedFormat: \"fixext4\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Fixext8 format (needs 64-bit but secs fits in 34 bits)\",\n\t\t\ttime:           time.Unix(17179869183, 999999999), // (1 << 34) - 1\n\t\t\texpectedLen:    10,                                // 1 (Fixext8) + 1 (TimeStamp) + 8 (data)\n\t\t\texpectedFormat: \"fixext8\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Ext8 format (secs >= 2^34)\",\n\t\t\ttime:           time.Unix(17179869184, 123456789), // 1 << 34\n\t\t\texpectedLen:    15,                                // 1 (Ext8) + 1 (12) + 1 (TimeStamp) + 4 (nsec) + 8 (secs)\n\t\t\texpectedFormat: \"ext8\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Ext8 format (large timestamp)\",\n\t\t\ttime:           time.Unix(253402300799, 999999999), // 9999-12-31 23:59:59\n\t\t\texpectedLen:    15,\n\t\t\texpectedFormat: \"ext8\",\n\t\t},\n\t}\n\n\tencoder := StreamEncoder\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tbuf := &bytes.Buffer{}\n\t\t\tbuffer := common.GetBuffer()\n\t\t\tdefer common.PutBuffer(buffer)\n\t\t\tw := ext.CreateStreamWriter(buf, buffer)\n\n\t\t\terr := encoder.Write(w, value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\t// Flush buffer to writer\n\t\t\terr = buffer.Flush(buf)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tb := buf.Bytes()\n\t\t\ttu.Equal(t, len(b), tt.expectedLen)\n\n\t\t\t// Verify format type\n\t\t\tswitch tt.expectedFormat {\n\t\t\tcase \"fixext4\":\n\t\t\t\ttu.Equal(t, b[0], def.Fixext4)\n\t\t\t\ttu.Equal(t, int8(b[1]), def.TimeStamp)\n\n\t\t\tcase \"fixext8\":\n\t\t\t\ttu.Equal(t, b[0], def.Fixext8)\n\t\t\t\ttu.Equal(t, int8(b[1]), def.TimeStamp)\n\n\t\t\tcase \"ext8\":\n\t\t\t\ttu.Equal(t, b[0], def.Ext8)\n\t\t\t\ttu.Equal(t, b[1], 12)\n\t\t\t\ttu.Equal(t, int8(b[2]), def.TimeStamp)\n\n\t\t\tdefault:\n\t\t\t\tt.Errorf(\"Unknown expected format: %s\", tt.expectedFormat)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStreamWriteEdgeCases(t *testing.T) {\n\tencoder := StreamEncoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Unix epoch\",\n\t\t\ttime: time.Unix(0, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Maximum nanoseconds\",\n\t\t\ttime: time.Unix(1000, 999999999),\n\t\t},\n\t\t{\n\t\t\tname: \"Boundary at 2^34 - 1\",\n\t\t\ttime: time.Unix((1<<34)-1, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Boundary at 2^34\",\n\t\t\ttime: time.Unix(1<<34, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Negative Unix timestamp\",\n\t\t\ttime: time.Unix(-1, 0),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tbuf := &bytes.Buffer{}\n\t\t\tbuffer := common.GetBuffer()\n\t\t\tdefer common.PutBuffer(buffer)\n\t\t\tw := ext.CreateStreamWriter(buf, buffer)\n\n\t\t\terr := encoder.Write(w, value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\t// Flush buffer to writer\n\t\t\terr = buffer.Flush(buf)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tb := buf.Bytes()\n\t\t\t// Verify basic structure is valid\n\t\t\tif len(b) < 2 {\n\t\t\t\tt.Error(\"Byte slice too short\")\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStreamEncodedDataAccuracy(t *testing.T) {\n\tencoder := StreamEncoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Fixext4 - simple\",\n\t\t\ttime: time.Unix(12345, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Fixext8 - with nanoseconds\",\n\t\t\ttime: time.Unix(67890, 123456789),\n\t\t},\n\t\t{\n\t\t\tname: \"Ext8 - large\",\n\t\t\ttime: time.Unix(17179869184, 987654321),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tbuf := &bytes.Buffer{}\n\t\t\tbuffer := common.GetBuffer()\n\t\t\tdefer common.PutBuffer(buffer)\n\t\t\tw := ext.CreateStreamWriter(buf, buffer)\n\n\t\t\terr := encoder.Write(w, value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\t// Flush buffer to writer\n\t\t\terr = buffer.Flush(buf)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tb := buf.Bytes()\n\n\t\t\t// Verify we can extract the correct time back\n\t\t\tswitch b[0] {\n\t\t\tcase def.Fixext4:\n\t\t\t\tdata := binary.BigEndian.Uint32(b[2:6])\n\t\t\t\tsecs := int64(data)\n\t\t\t\ttu.Equal(t, secs, tt.time.Unix())\n\n\t\t\tcase def.Fixext8:\n\t\t\t\tdata := binary.BigEndian.Uint64(b[2:10])\n\t\t\t\tnano := int64(data >> 34)\n\t\t\t\tsecs := int64(data & 0x00000003ffffffff)\n\t\t\t\ttu.Equal(t, secs, tt.time.Unix())\n\t\t\t\ttu.Equal(t, nano, int64(tt.time.Nanosecond()))\n\n\t\t\tcase def.Ext8:\n\t\t\t\tnano := binary.BigEndian.Uint32(b[3:7])\n\t\t\t\tsecs := binary.BigEndian.Uint64(b[7:15])\n\t\t\t\ttu.Equal(t, int64(secs), tt.time.Unix())\n\t\t\t\ttu.Equal(t, int64(nano), int64(tt.time.Nanosecond()))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestStreamWriteWithVariousNanoseconds(t *testing.T) {\n\tencoder := StreamEncoder\n\n\ttests := []struct {\n\t\tname        string\n\t\ttime        time.Time\n\t\texpectFmt   byte\n\t\tdescription string\n\t}{\n\t\t{\n\t\t\tname:        \"Zero nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 0),\n\t\t\texpectFmt:   def.Fixext4,\n\t\t\tdescription: \"Should use Fixext4 when nanoseconds is 0\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Small nanoseconds (1)\",\n\t\t\ttime:        time.Unix(1000, 1),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with nanoseconds\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Mid nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 500000000),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with mid-range nanoseconds\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Max nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 999999999),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with max nanoseconds\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tbuf := &bytes.Buffer{}\n\t\t\tbuffer := common.GetBuffer()\n\t\t\tdefer common.PutBuffer(buffer)\n\t\t\tw := ext.CreateStreamWriter(buf, buffer)\n\n\t\t\terr := encoder.Write(w, value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\t// Flush buffer to writer\n\t\t\terr = buffer.Flush(buf)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tb := buf.Bytes()\n\t\t\ttu.Equal(t, b[0], tt.expectFmt)\n\t\t})\n\t}\n}\n\ntype testErrWriter struct {\n\tErrorBytes []byte\n\tCount      int\n}\n\nfunc (w *testErrWriter) Write(p []byte) (n int, err error) {\n\tif bytes.Equal(w.ErrorBytes, p) {\n\t\treturn 0, errors.New(\"equal bytes error\")\n\t}\n\treturn len(p), nil\n}\n\nfunc TestStreamWriteErrors(t *testing.T) {\n\tencoder := StreamEncoder\n\n\tts := def.TimeStamp\n\n\ttests := []struct {\n\t\tname         string\n\t\ttimeValue    time.Time\n\t\terrorBytes   []byte\n\t\tprepareSize  int\n\t\tprepareBytes []byte\n\t}{\n\t\t// Fixext4 tests\n\t\t{\n\t\t\tname:         \"Fixext4 - Error on writing Fixext4 type byte\",\n\t\t\ttimeValue:    time.Unix(1000, 0),\n\t\t\terrorBytes:   []byte{255},\n\t\t\tprepareSize:  1,\n\t\t\tprepareBytes: []byte{255},\n\t\t},\n\t\t{\n\t\t\tname:        \"Fixext4 - Error on writing TimeStamp type byte\",\n\t\t\ttimeValue:   time.Unix(1000, 0),\n\t\t\terrorBytes:  []byte{def.Fixext4},\n\t\t\tprepareSize: 1,\n\t\t},\n\t\t{\n\t\t\tname:        \"Fixext4 - Error on writing 4 bytes of data\",\n\t\t\ttimeValue:   time.Unix(1000, 0),\n\t\t\terrorBytes:  []byte{def.Fixext4, byte(ts)},\n\t\t\tprepareSize: 2,\n\t\t},\n\t\t// Fixext8 tests\n\t\t{\n\t\t\tname:         \"Fixext8 - Error on writing Fixext8 type byte\",\n\t\t\ttimeValue:    time.Unix(1000, 1),\n\t\t\terrorBytes:   []byte{255},\n\t\t\tprepareSize:  1,\n\t\t\tprepareBytes: []byte{255},\n\t\t},\n\t\t{\n\t\t\tname:        \"Fixext8 - Error on writing TimeStamp type byte\",\n\t\t\ttimeValue:   time.Unix(1000, 1),\n\t\t\terrorBytes:  []byte{def.Fixext8},\n\t\t\tprepareSize: 1,\n\t\t},\n\t\t{\n\t\t\tname:        \"Fixext8 - Error on writing 8 bytes of data\",\n\t\t\ttimeValue:   time.Unix(1000, 1),\n\t\t\terrorBytes:  []byte{def.Fixext8, byte(ts)},\n\t\t\tprepareSize: 2,\n\t\t},\n\t\t// Ext8 tests\n\t\t{\n\t\t\tname:         \"Ext8 - Error on writing Ext8 type byte\",\n\t\t\ttimeValue:    time.Unix(1<<34, 0),\n\t\t\terrorBytes:   []byte{255},\n\t\t\tprepareSize:  1,\n\t\t\tprepareBytes: []byte{255},\n\t\t},\n\t\t{\n\t\t\tname:        \"Ext8 - Error on writing length byte\",\n\t\t\ttimeValue:   time.Unix(1<<34, 0),\n\t\t\terrorBytes:  []byte{def.Ext8},\n\t\t\tprepareSize: 1,\n\t\t},\n\t\t{\n\t\t\tname:        \"Ext8 - Error on writing TimeStamp type byte\",\n\t\t\ttimeValue:   time.Unix(1<<34, 0),\n\t\t\terrorBytes:  []byte{def.Ext8, 12},\n\t\t\tprepareSize: 2,\n\t\t},\n\t\t{\n\t\t\tname:        \"Ext8 - Error on writing 4 bytes of nanoseconds\",\n\t\t\ttimeValue:   time.Unix(1<<34, 0),\n\t\t\terrorBytes:  []byte{def.Ext8, 12, byte(ts)},\n\t\t\tprepareSize: 3,\n\t\t},\n\t\t{\n\t\t\tname:        \"Ext8 - Error on writing 8 bytes of seconds\",\n\t\t\ttimeValue:   time.Unix(1<<34, 123456789),\n\t\t\terrorBytes:  []byte{def.Ext8, 12, byte(ts), 0x07, 0x5b, 0xcd, 0x15},\n\t\t\tprepareSize: 7,\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tbuffer := &common.Buffer{Data: make([]byte, tt.prepareSize)}\n\t\t\terr := buffer.Write(nil, tt.prepareBytes...)\n\t\t\ttu.NoError(t, err)\n\n\t\t\terrWriter := &testErrWriter{ErrorBytes: tt.errorBytes}\n\t\t\tw := ext.CreateStreamWriter(errWriter, buffer)\n\t\t\tvalue := reflect.ValueOf(tt.timeValue)\n\t\t\terr = encoder.Write(w, value)\n\t\t\ttu.Error(t, err)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "time/encode_test.go",
    "content": "package time\n\nimport (\n\t\"encoding/binary\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/shamaton/msgpack/v3/def\"\n\ttu \"github.com/shamaton/msgpack/v3/internal/common/testutil\"\n)\n\nfunc TestCode(t *testing.T) {\n\tencoder := Encoder\n\tcode := encoder.Code()\n\ttu.Equal(t, code, def.TimeStamp)\n}\n\nfunc TestType(t *testing.T) {\n\tencoder := Encoder\n\ttyp := encoder.Type()\n\texpected := reflect.TypeOf(time.Time{})\n\ttu.Equal(t, typ, expected)\n}\n\nfunc TestCalcByteSize(t *testing.T) {\n\tencoder := Encoder\n\n\ttests := []struct {\n\t\tname     string\n\t\ttime     time.Time\n\t\texpected int\n\t}{\n\t\t{\n\t\t\tname:     \"Fixext4 - epoch\",\n\t\t\ttime:     time.Unix(0, 0),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte4, // 6\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext4 - small timestamp\",\n\t\t\ttime:     time.Unix(1000, 0),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte4, // 6\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext8 - with nanoseconds\",\n\t\t\ttime:     time.Unix(1000, 999999999),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte8, // 10\n\t\t},\n\t\t{\n\t\t\tname:     \"Fixext8 - boundary (2^34-1)\",\n\t\t\ttime:     time.Unix((1<<34)-1, 0),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte8, // 10\n\t\t},\n\t\t{\n\t\t\tname:     \"Ext8 - large timestamp (2^34)\",\n\t\t\ttime:     time.Unix(1<<34, 0),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte1 + def.Byte4 + def.Byte8, // 15\n\t\t},\n\t\t{\n\t\t\tname:     \"Ext8 - large timestamp with nanoseconds\",\n\t\t\ttime:     time.Unix(1<<34, 123456789),\n\t\t\texpected: def.Byte1 + def.Byte1 + def.Byte1 + def.Byte4 + def.Byte8, // 15\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, size, tt.expected)\n\t\t})\n\t}\n}\n\nfunc TestEncodedDataAccuracy(t *testing.T) {\n\tencoder := Encoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Fixext4 - simple\",\n\t\t\ttime: time.Unix(12345, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Fixext8 - with nanoseconds\",\n\t\t\ttime: time.Unix(67890, 123456789),\n\t\t},\n\t\t{\n\t\t\tname: \"Ext8 - large\",\n\t\t\ttime: time.Unix(17179869184, 987654321),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tbytes := make([]byte, size)\n\t\t\tencoder.WriteToBytes(value, 0, &bytes)\n\n\t\t\t// Verify we can extract the correct time back\n\t\t\tswitch bytes[0] {\n\t\t\tcase def.Fixext4:\n\t\t\t\tdata := binary.BigEndian.Uint32(bytes[2:6])\n\t\t\t\tsecs := int64(data)\n\t\t\t\ttu.Equal(t, secs, tt.time.Unix())\n\n\t\t\tcase def.Fixext8:\n\t\t\t\tdata := binary.BigEndian.Uint64(bytes[2:10])\n\t\t\t\tnano := int64(data >> 34)\n\t\t\t\tsecs := int64(data & 0x00000003ffffffff)\n\t\t\t\ttu.Equal(t, secs, tt.time.Unix())\n\t\t\t\ttu.Equal(t, nano, int64(tt.time.Nanosecond()))\n\n\t\t\tcase def.Ext8:\n\t\t\t\tnano := binary.BigEndian.Uint32(bytes[3:7])\n\t\t\t\tsecs := binary.BigEndian.Uint64(bytes[7:15])\n\t\t\t\ttu.Equal(t, int64(secs), tt.time.Unix())\n\t\t\t\ttu.Equal(t, int64(nano), int64(tt.time.Nanosecond()))\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWriteToBytes(t *testing.T) {\n\ttests := []struct {\n\t\tname           string\n\t\ttime           time.Time\n\t\texpectedLen    int\n\t\texpectedFormat string\n\t}{\n\t\t{\n\t\t\tname:           \"Fixext4 format (32-bit timestamp, no nanoseconds)\",\n\t\t\ttime:           time.Unix(0, 0),\n\t\t\texpectedLen:    6, // 1 (Fixext4) + 1 (TimeStamp) + 4 (data)\n\t\t\texpectedFormat: \"fixext4\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Fixext4 format (small timestamp, no nanoseconds)\",\n\t\t\ttime:           time.Unix(1000, 0),\n\t\t\texpectedLen:    6,\n\t\t\texpectedFormat: \"fixext4\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Fixext8 format (needs 64-bit but secs fits in 34 bits)\",\n\t\t\ttime:           time.Unix(17179869183, 999999999), // (1 << 34) - 1\n\t\t\texpectedLen:    10,                                // 1 (Fixext8) + 1 (TimeStamp) + 8 (data)\n\t\t\texpectedFormat: \"fixext8\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Ext8 format (secs >= 2^34)\",\n\t\t\ttime:           time.Unix(17179869184, 123456789), // 1 << 34\n\t\t\texpectedLen:    15,                                // 1 (Ext8) + 1 (12) + 1 (TimeStamp) + 4 (nsec) + 8 (secs)\n\t\t\texpectedFormat: \"ext8\",\n\t\t},\n\t\t{\n\t\t\tname:           \"Ext8 format (large timestamp)\",\n\t\t\ttime:           time.Unix(253402300799, 999999999), // 9999-12-31 23:59:59\n\t\t\texpectedLen:    15,\n\t\t\texpectedFormat: \"ext8\",\n\t\t},\n\t}\n\n\tencoder := Encoder\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\n\t\t\t// Calculate expected byte size\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\t\t\ttu.Equal(t, size, tt.expectedLen)\n\n\t\t\t// Create byte slice\n\t\t\tbytes := make([]byte, size)\n\n\t\t\t// Write to bytes\n\t\t\toffset := encoder.WriteToBytes(value, 0, &bytes)\n\t\t\ttu.Equal(t, offset, tt.expectedLen)\n\n\t\t\t// Verify format type\n\t\t\tswitch tt.expectedFormat {\n\t\t\tcase \"fixext4\":\n\t\t\t\ttu.Equal(t, bytes[0], def.Fixext4)\n\t\t\t\ttu.Equal(t, int8(bytes[1]), def.TimeStamp)\n\n\t\t\tcase \"fixext8\":\n\t\t\t\ttu.Equal(t, bytes[0], def.Fixext8)\n\t\t\t\ttu.Equal(t, int8(bytes[1]), def.TimeStamp)\n\n\t\t\tcase \"ext8\":\n\t\t\t\ttu.Equal(t, bytes[0], def.Ext8)\n\t\t\t\ttu.Equal(t, bytes[1], 12)\n\t\t\t\ttu.Equal(t, int8(bytes[2]), def.TimeStamp)\n\n\t\t\tdefault:\n\t\t\t\tt.Errorf(\"Unknown expected format: %s\", tt.expectedFormat)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWriteToBytesOffset(t *testing.T) {\n\tencoder := Encoder\n\ttestTime := time.Unix(1000000000, 123456789)\n\tvalue := reflect.ValueOf(testTime)\n\n\tsize, err := encoder.CalcByteSize(value)\n\ttu.NoError(t, err)\n\n\t// Test with non-zero offset\n\toffset := 10\n\tbytes := make([]byte, offset+size)\n\n\tnewOffset := encoder.WriteToBytes(value, offset, &bytes)\n\ttu.Equal(t, newOffset, offset+size)\n\n\t// Verify the data is written at correct position\n\tif bytes[offset] != def.Fixext4 && bytes[offset] != def.Fixext8 && bytes[offset] != def.Ext8 {\n\t\tt.Errorf(\"Data not written at correct offset\")\n\t}\n}\n\nfunc TestWriteToBytesEdgeCases(t *testing.T) {\n\tencoder := Encoder\n\n\ttests := []struct {\n\t\tname string\n\t\ttime time.Time\n\t}{\n\t\t{\n\t\t\tname: \"Unix epoch\",\n\t\t\ttime: time.Unix(0, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Maximum nanoseconds\",\n\t\t\ttime: time.Unix(1000, 999999999),\n\t\t},\n\t\t{\n\t\t\tname: \"Boundary at 2^34 - 1\",\n\t\t\ttime: time.Unix((1<<34)-1, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Boundary at 2^34\",\n\t\t\ttime: time.Unix(1<<34, 0),\n\t\t},\n\t\t{\n\t\t\tname: \"Negative Unix timestamp\",\n\t\t\ttime: time.Unix(-1, 0),\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tbytes := make([]byte, size)\n\t\t\toffset := encoder.WriteToBytes(value, 0, &bytes)\n\t\t\ttu.Equal(t, offset, size)\n\n\t\t\t// Verify basic structure is valid\n\t\t\tif len(bytes) < 2 {\n\t\t\t\tt.Error(\"Byte slice too short\")\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestWriteToBytesWithVariousNanoseconds(t *testing.T) {\n\tencoder := Encoder\n\n\ttests := []struct {\n\t\tname        string\n\t\ttime        time.Time\n\t\texpectFmt   byte\n\t\tdescription string\n\t}{\n\t\t{\n\t\t\tname:        \"Zero nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 0),\n\t\t\texpectFmt:   def.Fixext4,\n\t\t\tdescription: \"Should use Fixext4 when nanoseconds is 0\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Small nanoseconds (1)\",\n\t\t\ttime:        time.Unix(1000, 1),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with nanoseconds\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Mid nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 500000000),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with mid-range nanoseconds\",\n\t\t},\n\t\t{\n\t\t\tname:        \"Max nanoseconds\",\n\t\t\ttime:        time.Unix(1000, 999999999),\n\t\t\texpectFmt:   def.Fixext8,\n\t\t\tdescription: \"Should use Fixext8 with max nanoseconds\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tvalue := reflect.ValueOf(tt.time)\n\t\t\tsize, err := encoder.CalcByteSize(value)\n\t\t\ttu.NoError(t, err)\n\n\t\t\tbytes := make([]byte, size)\n\t\t\tencoder.WriteToBytes(value, 0, &bytes)\n\n\t\t\ttu.Equal(t, bytes[0], tt.expectFmt)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "time/time.go",
    "content": "package time\n\nvar decodeAsLocal = false\n\n// SetDecodedAsLocal sets the decoded time to local time.\nfunc SetDecodedAsLocal(b bool) {\n\tdecodeAsLocal = b\n}\n"
  },
  {
    "path": "unmarshal_ext_test.go",
    "content": "package msgpack_test\n\nimport (\n\t\"errors\"\n\t\"testing\"\n\n\t\"github.com/shamaton/msgpack/v3\"\n\t\"github.com/shamaton/msgpack/v3/def\"\n)\n\nfunc TestUnmarshalTruncatedTimestampExtReturnsTooShort(t *testing.T) {\n\tts := def.TimeStamp\n\n\ttestcases := []struct {\n\t\tname string\n\t\tdata []byte\n\t}{\n\t\t{name: \"fixext4\", data: []byte{def.Fixext4, byte(ts)}},\n\t\t{name: \"fixext8\", data: []byte{def.Fixext8, byte(ts)}},\n\t}\n\n\tmethods := []struct {\n\t\tname string\n\t\tfn   func([]byte, interface{}) error\n\t}{\n\t\t{name: \"Unmarshal\", fn: msgpack.Unmarshal},\n\t\t{name: \"UnmarshalAsArray\", fn: msgpack.UnmarshalAsArray},\n\t\t{name: \"UnmarshalAsMap\", fn: msgpack.UnmarshalAsMap},\n\t}\n\n\tfor _, method := range methods {\n\t\tfor _, tc := range testcases {\n\t\t\tt.Run(method.name+\"/\"+tc.name, func(t *testing.T) {\n\t\t\t\tvar v interface{}\n\t\t\t\terr := method.fn(tc.data, &v)\n\t\t\t\tif !errors.Is(err, def.ErrTooShortBytes) {\n\t\t\t\t\tt.Fatalf(\"expected %v, got %v\", def.ErrTooShortBytes, err)\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t}\n}\n"
  }
]