├── .gx └── lastpubver ├── .hgignore ├── go ├── Makefile ├── doc.go ├── cbor_test.go └── cbor.go ├── package.json ├── LICENSE ├── notes.txt └── README.md /.gx/lastpubver: -------------------------------------------------------------------------------- 1 | 0.2.3: QmcRKRQjNc2JZPHApR32fbkZVd6WXG2Ch9Kcy7sPxuAJgd 2 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | syntax: glob 2 | *.o 3 | *.d 4 | *.pyc 5 | *~ 6 | build 7 | *.egg-info 8 | Attic 9 | *.so 10 | test-vectors 11 | *,cover 12 | py/dist 13 | -------------------------------------------------------------------------------- /go/Makefile: -------------------------------------------------------------------------------- 1 | #PATH:=${HOME}/psrc/golang/go/bin:${PATH} 2 | #PATH += ${HOME}/psrc/golang/go/bin 3 | GOROOT=${HOME}/psrc/golang/go 4 | GOPATH=${HOME}/psrc/gopath 5 | 6 | GO=${GOROOT}/bin/go 7 | 8 | all: 9 | ${GO} build 10 | 11 | test: 12 | ${GO} test 13 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "whyrusleeping", 3 | "bugs": { 4 | "url": "https://github.com/whyrusleeping/cbor" 5 | }, 6 | "gx": { 7 | "dvcsimport": "github.com/whyrusleeping/cbor" 8 | }, 9 | "gxVersion": "0.10.0", 10 | "language": "go", 11 | "license": "", 12 | "name": "cbor", 13 | "releaseCmd": "git commit -a -m \"gx publish $VERSION\"", 14 | "version": "0.2.3" 15 | } 16 | 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2014-2015 Brian Olson 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | This project: 2 | http://code.google.com/p/cbor/ 3 | 4 | The standard: 5 | http://tools.ietf.org/html/rfc7049 6 | 7 | a Go implementation in progress 8 | https://github.com/cespare/cbor 9 | 10 | another python implementation, currently not as complete 11 | https://github.com/svartalf/python-cbor 12 | 13 | http://cbor.io/ 14 | 15 | https://github.com/cbor/test-vectors/ 16 | 17 | git clone https://github.com/cbor/test-vectors/ 18 | 19 | go install code.google.com/p/cbor/go 20 | 21 | godoc code.google.com/p/cbor/go 22 | 23 | TODO: 24 | compare go impl to 25 | https://github.com/ugorji/go 26 | go get github.com/ugorji/go/codec 27 | -------------------------------------------------------------------------------- /go/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | CBOR is IETF RFC 7049, the "Concise Binary Object Representation" 3 | http://tools.ietf.org/html/rfc7049 4 | 5 | In can be thought of as "binary JSON" but is a superset and somewhat richer representation than JSON. 6 | 7 | Other implementations and more information can also be found at: 8 | http://cbor.io/ 9 | 10 | Serialization and deserialization of structs uses the same tag format as the encoding/json package. If different json and cbor serialization names are needed, a tag `cbor:"fieldName"` can be specified. Example: 11 | 12 | type DemoStruct struct { 13 | FieldNeedsDifferentName string `json:"serialization_name"` 14 | FieldNeedsJsonVsCborName int `json:"json_name" cbor:"cbor_name"` 15 | } 16 | 17 | This might generate json: 18 | {"serialization_name":"foo", "json_name":2} 19 | 20 | And CBOR equivalent to: 21 | {"serialization_name":"foo", "cbor_name":2} 22 | 23 | */ 24 | package cbor 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Concise Binary Object Representation (CBOR) is a superset of JSON's schema that's faster and more compact. 2 | 3 | * http://tools.ietf.org/html/rfc7049 4 | * http://cbor.io/ 5 | 6 | This repository contains implementations for Python and Go. 7 | 8 | ## Python ## 9 | This Python implementation provides loads()/dumps() like the json standard library. 10 | 11 | Compare to Python 2.7.5's standard library implementation of json: 12 | 13 | ``` 14 | #! 15 | 16 | serialized 50000 objects into 1163097 cbor bytes in 0.05 seconds (1036613.48/s) and 1767001 json bytes in 0.22 seconds (224772.48/s) 17 | compress to 999179 bytes cbor.gz and 1124500 bytes json.gz 18 | load 50000 objects from cbor in 0.07 secs (763708.80/sec) and json in 0.32 (155348.97/sec) 19 | ``` 20 | 21 | There is also a pure-python implementation which gets about 1/3 the speed of json's C augmented speed. 22 | 23 | Tested in Python 2.7.5, 2,7.6, 3.3.3, and 3.4.0 24 | 25 | Available on pypi: 26 | 27 | pip install cbor 28 | 29 | ## Go ## 30 | The Go implementation is newer. It attempts to do serialization to/from struct types using reflection, but doesn't do 100% of cases like that right. It _should_ do everything fine serializing `map[string]interface{}` and `[]interface{}` and other basic types. It passes the test of decoding 100% of CBOR common appendix test strings. -------------------------------------------------------------------------------- /go/cbor_test.go: -------------------------------------------------------------------------------- 1 | package cbor 2 | 3 | import "bytes" 4 | import "encoding/base64" 5 | import "encoding/hex" 6 | import "encoding/json" 7 | import "fmt" 8 | import "log" 9 | import "math" 10 | import "math/big" 11 | import "os" 12 | import "reflect" 13 | import "strings" 14 | import "testing" 15 | 16 | type testVector struct { 17 | Cbor string 18 | Hex string 19 | Roundtrip bool 20 | Decoded interface{} 21 | Diagnostic string 22 | } 23 | 24 | var errpath string = "../test-vectors/appendix_a.json" 25 | 26 | func readVectors(t *testing.T) ([]testVector, error) { 27 | fin, err := os.Open(errpath) 28 | if err != nil { 29 | t.Error("could not open test vectors at: ", errpath) 30 | return nil, err 31 | } 32 | jd := json.NewDecoder(fin) 33 | jd.UseNumber() 34 | they := new([]testVector) 35 | err = jd.Decode(they) 36 | return *they, err 37 | } 38 | 39 | 40 | func jeq(jsonv, cborv interface{}, t *testing.T) bool { 41 | switch i := cborv.(type) { 42 | case uint64: 43 | switch jv := jsonv.(type) { 44 | case int: 45 | return (jv >= 0) && (uint64(jv) == i) 46 | case uint64: 47 | return i == jv 48 | case float64: 49 | return math.Abs(float64(i) - jv) < math.Max(math.Abs(jv / 1000000000.0), 1.0/1000000000.0) 50 | case json.Number: 51 | return jv.String() == fmt.Sprintf("%d", i) 52 | default: 53 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 54 | return false 55 | } 56 | case big.Int: 57 | switch jv := jsonv.(type) { 58 | case json.Number: 59 | return jv.String() == i.String() 60 | default: 61 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 62 | return false 63 | } 64 | case int64: 65 | switch jv := jsonv.(type) { 66 | case int: 67 | return int64(jv) == i 68 | case json.Number: 69 | return jv.String() == fmt.Sprintf("%d", i) 70 | default: 71 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 72 | return false 73 | } 74 | case float32: 75 | switch jv := jsonv.(type) { 76 | case json.Number: 77 | //return jv.String() == fmt.Sprintf("%f", i) 78 | fv, err := jv.Float64() 79 | if err != nil { 80 | t.Errorf("error getting json float: %s", err) 81 | return false; 82 | } 83 | return fv == float64(i) 84 | default: 85 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 86 | return false 87 | } 88 | case float64: 89 | switch jv := jsonv.(type) { 90 | case json.Number: 91 | //return jv.String() == fmt.Sprintf("%f", i) 92 | fv, err := jv.Float64() 93 | if err != nil { 94 | t.Errorf("error getting json float: %s", err) 95 | return false; 96 | } 97 | return fv == i 98 | default: 99 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 100 | return false 101 | } 102 | case bool: 103 | switch jv := jsonv.(type) { 104 | case bool: 105 | return jv == i 106 | default: 107 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 108 | return false 109 | } 110 | case string: 111 | switch jv := jsonv.(type) { 112 | case string: 113 | return jv == i 114 | default: 115 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 116 | return false 117 | } 118 | case []interface{}: 119 | switch jv := jsonv.(type) { 120 | case []interface{}: 121 | if len(i) != len(jv) { 122 | return false 123 | } 124 | for cai, cav := range(i) { 125 | if !jeq(jv[cai], cav, t) { 126 | t.Errorf("array mismatch at [%d]: json=%#v cbor=%#v", cai, jv[cai], cav) 127 | return false 128 | } 129 | /* 130 | if fmt.Sprintf("%v", cav) != fmt.Sprintf("%v", jv[cai]) { 131 | return false 132 | } 133 | */ 134 | } 135 | return true 136 | default: 137 | if reflect.DeepEqual(cborv, jsonv) { 138 | return true 139 | } 140 | t.Errorf("wat types cbor %T json %T", cborv, jsonv); 141 | return false 142 | } 143 | case nil: 144 | switch jv := jsonv.(type) { 145 | case nil: 146 | return true; 147 | default: 148 | t.Errorf("wat types cbor %T json %T", cborv, jv); 149 | return false 150 | } 151 | case map[interface{}]interface{}: 152 | switch jv := jsonv.(type) { 153 | case map[string]interface{}: 154 | for jmk, jmv := range(jv) { 155 | cmv, ok := i[jmk] 156 | if !ok { 157 | t.Errorf("json key %v missing from cbor", jmk) 158 | return false 159 | } 160 | if !jeq(jmv, cmv, t) { 161 | t.Errorf("map key=%#v values: json=%#v cbor=%#v", jmk, jmv, cmv) 162 | return false 163 | } 164 | /* 165 | if !reflect.DeepEqual(cmv, jmv) { 166 | t.Errorf("map key=%#v values: json=%#v cbor=%#v", jmk, jmv, cmv) 167 | return false 168 | } 169 | */ 170 | } 171 | return true 172 | default: 173 | t.Errorf("wat types cbor %T json %T", cborv, jv); 174 | return false 175 | } 176 | case []byte: 177 | switch jv := jsonv.(type) { 178 | case []byte: 179 | return bytes.Equal(i, jv) 180 | default: 181 | t.Errorf("wat types cbor %T json %T", cborv, jv); 182 | return false 183 | } 184 | default: 185 | eq := reflect.DeepEqual(jsonv, cborv) 186 | if ! eq { 187 | log.Printf("unexpected cbor type %T = %#v", cborv, cborv) 188 | t.Errorf("unexpected cbor type %T = %#v", cborv, cborv) 189 | } 190 | return eq 191 | //return fmt.Sprintf("%v", jsonv) == fmt.Sprintf("%v", cborv) 192 | //return jsonv == cborv 193 | } 194 | } 195 | 196 | 197 | func TestDecodeVectors(t *testing.T) { 198 | //t.Parallel() 199 | 200 | t.Log("test standard decode vectors") 201 | they, err := readVectors(t) 202 | if err != nil { 203 | t.Fatal("could not load test vectors:", err) 204 | return 205 | } 206 | t.Logf("got %d test vectors", len(they)) 207 | if len(they) <= 0 { 208 | t.Fatal("got no test vectors") 209 | return 210 | } 211 | for i, testv := range(they) { 212 | if testv.Decoded != nil && len(testv.Cbor) > 0 { 213 | //log.Printf("hex %s", testv.Hex) 214 | t.Logf("hex %s", testv.Hex) 215 | bin, err := base64.StdEncoding.DecodeString(testv.Cbor) 216 | if err != nil { 217 | t.Logf("test[%d] %#v", i, testv) 218 | t.Logf("decoding [%d] %#v ...\n", i, testv.Cbor) 219 | t.Fatal("could not decode test vector b64") 220 | return 221 | } 222 | ring := NewDecoder(bytes.NewReader(bin)) 223 | var cborObject interface{} 224 | err = ring.Decode(&cborObject) 225 | if err != nil { 226 | t.Logf("test[%d] %#v", i, testv) 227 | t.Logf("decoding [%d] %#v ...\n", i, testv.Cbor) 228 | t.Fatalf("error decoding cbor: %v", err) 229 | return 230 | } 231 | if !jeq(testv.Decoded, cborObject, t) { 232 | //t.Logf("test[%d] %#v", i, testv) 233 | t.Logf("decoding [%d] %#v ...\n", i, testv.Cbor) 234 | t.Errorf("json %T %#v != cbor %T %#v", testv.Decoded, testv.Decoded, cborObject, cborObject) 235 | t.Logf("------") 236 | } 237 | } 238 | } 239 | } 240 | 241 | 242 | type RefTestOb struct { 243 | AString string 244 | BInt int 245 | CUint uint64 246 | DFloat float64 247 | EIntArray []int 248 | FStrIntMap map[string]int 249 | GBool bool 250 | } 251 | 252 | type privateTestOb struct { 253 | privateInt int 254 | PubInt int 255 | PubSkip int `cbor:"-"` 256 | } 257 | 258 | 259 | func checkObOne(ob RefTestOb, t *testing.T) bool { 260 | ok := true 261 | if ob.AString != "astring val" { 262 | t.Errorf("AString wanted \"astring val\" but got %#v", ob.AString) 263 | ok = false 264 | } 265 | if ob.BInt != -33 { 266 | t.Errorf("BInt wanted -33 but got %#v", ob.BInt) 267 | ok = false 268 | } 269 | if ob.CUint != 42 { 270 | t.Errorf("CUint wanted 42 but got %#v", ob.CUint) 271 | ok = false 272 | } 273 | if ob.DFloat != 0.25 { 274 | t.Errorf("DFloat wanted 02.5 but got %#v", ob.DFloat) 275 | ok = false 276 | } 277 | return ok 278 | } 279 | 280 | 281 | const ( 282 | reflexObOneJson = "{\"astring\": \"astring val\", \"bint\": -33, \"cuint\": 42, \"dfloat\": 0.25, \"eintarray\": [1,2,3], \"fstrintmap\":{\"a\":13, \"b\":14}, \"gbool\": false}" 283 | reflexObOneCborB64 = "p2dhc3RyaW5na2FzdHJpbmcgdmFsamZzdHJpbnRtYXCiYWENYWIOZWdib29s9GRiaW50OCBpZWludGFycmF5gwECA2VjdWludBgqZmRmbG9hdPs/0AAAAAAAAA==" 284 | ) 285 | 286 | var referenceObOne RefTestOb = RefTestOb{ 287 | "astring val", -33, 42, 0.25, []int{1,2,3}, 288 | map[string]int{"a":13, "b": 14}, false} 289 | 290 | /* 291 | #python 292 | import json 293 | import cbor 294 | import base64 295 | # copy in the above json string literal here: 296 | jsonstr = 297 | print base64.b64encode(cbor.dumps(json.loads(jsonstr))) 298 | */ 299 | 300 | func TestDecodeReflectivelyOne(t *testing.T) { 301 | //t.Parallel() 302 | t.Log("test decode reflectively one") 303 | 304 | var err error 305 | 306 | jd := json.NewDecoder(strings.NewReader(reflexObOneJson)) 307 | jd.UseNumber() 308 | they := RefTestOb{} 309 | err = jd.Decode(&they) 310 | if err != nil { 311 | t.Fatal("could not decode json", err) 312 | return 313 | } 314 | 315 | t.Log("check json") 316 | if !checkObOne(they, t) { 317 | return 318 | } 319 | 320 | bin, err := base64.StdEncoding.DecodeString(reflexObOneCborB64) 321 | if err != nil { 322 | t.Fatal("error decoding cbor b64", err) 323 | return 324 | } 325 | ring := NewDecoder(bytes.NewReader(bin)) 326 | cob := RefTestOb{} 327 | err = ring.Decode(&cob) 328 | if err != nil { 329 | t.Fatal("error decoding cbor", err) 330 | return 331 | } 332 | t.Log("check cbor") 333 | if !checkObOne(they, t) { 334 | return 335 | } 336 | } 337 | 338 | func TestEncodeWithPrivate(t *testing.T) { 339 | //t.Parallel() 340 | t.Log("test encode with private") 341 | 342 | var err error 343 | ob := privateTestOb{1,2,3} 344 | 345 | writeTarget := &bytes.Buffer{} 346 | writeTarget.Grow(20000) 347 | err = Encode(writeTarget, ob) 348 | if err != nil { 349 | t.Errorf("failed on encode: %s", err) 350 | return 351 | } 352 | 353 | { 354 | destmap := make(map[string]interface{}) 355 | scratch := writeTarget.Bytes() 356 | dec := NewDecoder(bytes.NewReader(scratch)) 357 | err = dec.Decode(&destmap) 358 | if err != nil { 359 | t.Errorf("failed on decode: %s", err) 360 | return 361 | } 362 | pi, ok := destmap["privateInt"] 363 | if ok { 364 | t.Errorf("destmap shouldn't have privateInt %v: %#v", pi, destmap) 365 | } 366 | pubskip, ok := destmap["PubSkip"] 367 | if ok { 368 | t.Errorf("destmap shouldn't have PubSkip %v: %#v", pubskip, destmap) 369 | } 370 | } 371 | 372 | xo := privateTestOb{-1,-1,-1} 373 | scratch := writeTarget.Bytes() 374 | dec := NewDecoder(bytes.NewReader(scratch)) 375 | err = dec.Decode(&xo) 376 | if err != nil { 377 | t.Errorf("failed on decode: %s", err) 378 | return 379 | } 380 | if xo.privateInt != -1 { 381 | t.Errorf("privateInt is %d, wanted -1", xo.privateInt) 382 | } 383 | if xo.PubSkip != -1 { 384 | t.Errorf("PubSkip is %d, wanted -1", xo.PubSkip) 385 | } 386 | } 387 | 388 | func objectSerializedObject(t *testing.T, ob interface{}) { 389 | out := reflect.Indirect(reflect.New(reflect.TypeOf(ob))).Interface() 390 | //t.Logf("oso ob T %T %#v, out T %T %#v", ob, ob, out, out) 391 | objectSerializedTargetObject(t, ob, &out) 392 | if !jeq(ob, out, t) { 393 | // 394 | t.Errorf("%#v != %#v", ob, out) 395 | } 396 | } 397 | func objectSerializedTargetObject(t *testing.T, ob interface{}, out interface{}) { 398 | t.Logf("oso ob T %T %#v", ob, ob) 399 | t.Logf(" out T %T %#v", out, out) 400 | //scratch := make([]byte, 0) 401 | //writeTarget := bytes.NewBuffer(scratch) 402 | writeTarget := &bytes.Buffer{} 403 | writeTarget.Grow(20000) 404 | err := Encode(writeTarget, ob) 405 | if err != nil { 406 | t.Errorf("failed on encode: %s", err) 407 | return 408 | } 409 | 410 | scratch := writeTarget.Bytes() 411 | dec := NewDecoder(bytes.NewReader(scratch)) 412 | err = dec.Decode(out) 413 | 414 | t.Logf("oso ob T %T %#v", ob, ob) 415 | t.Logf(" out T %T %#v", out, out) 416 | 417 | t.Log(hex.EncodeToString(scratch)) 418 | if err != nil { 419 | t.Errorf("failed on decode: %s", err) 420 | return 421 | } 422 | } 423 | 424 | func TestOSO(t *testing.T) { 425 | t.Log("test OSO") 426 | objectSerializedObject(t, 0) 427 | objectSerializedObject(t, 1) 428 | objectSerializedObject(t, 2) 429 | objectSerializedObject(t, -1) 430 | objectSerializedObject(t, true) 431 | objectSerializedObject(t, false) 432 | // TODO: some of these don't quite work yet 433 | //objectSerializedObject(t, nil) 434 | objectSerializedObject(t, []interface{}{}) 435 | //objectSerializedObject(t, []int{}) 436 | //objectSerializedObject(t, []int{1,2,3}) 437 | objectSerializedObject(t, "hello") 438 | objectSerializedObject(t, []byte{1,3,2}) 439 | //objectSerializedObject(t, RefTestOb{"hi", -1000, 137, 0.5, nil, nil, true}) 440 | // objectSerializedObject(t, ) 441 | } 442 | 443 | 444 | func TestRefStruct(t *testing.T) { 445 | t.Log("test hard") 446 | trto := RefTestOb{} 447 | objectSerializedTargetObject(t, referenceObOne, &trto) 448 | checkObOne(trto, t) 449 | } 450 | 451 | 452 | func TestArrays(t *testing.T) { 453 | t.Log("test arrays") 454 | 455 | // okay, sooo, slices 456 | ia := []int{1,2,3} 457 | tia := []int{} 458 | objectSerializedTargetObject(t, ia, &tia) 459 | if ! reflect.DeepEqual(ia, tia) { 460 | t.Errorf("int array %#v != %#v", ia, tia) 461 | } 462 | 463 | // actual arrays 464 | xa := [3]int{4,5,6} 465 | txa := [3]int{} 466 | objectSerializedTargetObject(t, xa, &txa) 467 | if ! reflect.DeepEqual(xa, txa) { 468 | t.Errorf("int array %#v != %#v", xa, txa) 469 | } 470 | 471 | oa := [3]interface{}{"hi", 2, -3.14} 472 | toa := [3]interface{}{} 473 | objectSerializedTargetObject(t, oa, &toa) 474 | if toa[0] != "hi" { 475 | t.Errorf("[3]interface{} [0] wanted \"hi\" got %#v", toa[0]) 476 | } 477 | if toa[1] != uint64(2) { 478 | t.Errorf("[3]interface{} [0] wanted 2 got %#v", toa[1]) 479 | } 480 | if toa[2] != -3.14 { 481 | t.Errorf("[3]interface{} [0] wanted -3.14 got %#v", toa[2]) 482 | } 483 | } 484 | 485 | type TaggedStruct struct { 486 | One string `json:"m_one_s"` 487 | Two int `json:"bunnies,omitempty"` 488 | Three float64 `json:"htree_json" cbor:"three_cbor"` 489 | } 490 | 491 | func PracticalInt64(xi interface{}) (int64, bool) { 492 | switch i := xi.(type) { 493 | //case int, int8, int16, int32, int64, uint8, uint16, uint32: 494 | //oi, ok := i.(int64) 495 | //return oi, ok 496 | case int: 497 | return int64(i), true 498 | case int64: 499 | return int64(i), true 500 | case uint64: 501 | if i < 0x7fffffffffffffff { 502 | return int64(i), true 503 | } 504 | return 0, false 505 | } 506 | return 0, false 507 | } 508 | 509 | func ms(d map[string]interface{}, k string, t *testing.T) (string, bool) { 510 | if d == nil { 511 | t.Error("nil map") 512 | return "", false 513 | } 514 | ob, ok := d[k] 515 | if !ok { 516 | t.Errorf("map missing key %v", k) 517 | return "", false 518 | } 519 | xs, ok := ob.(string) 520 | return xs, ok 521 | } 522 | // I wish go had templates! 523 | func mi(d map[string]interface{}, k string, t *testing.T) (int64, bool) { 524 | if d == nil { 525 | t.Error("nil map") 526 | return 0, false 527 | } 528 | ob, ok := d[k] 529 | if !ok { 530 | t.Errorf("map missing key %v", k) 531 | return 0, false 532 | } 533 | //xs, ok := ob.(int) 534 | xs, ok := PracticalInt64(ob) 535 | return xs, ok 536 | } 537 | func mf64(d map[string]interface{}, k string, t *testing.T) (float64, bool) { 538 | if d == nil { 539 | t.Error("nil map") 540 | return 0, false 541 | } 542 | ob, ok := d[k] 543 | if !ok { 544 | t.Errorf("map missing key %v", k) 545 | return 0, false 546 | } 547 | xs, ok := ob.(float64) 548 | return xs, ok 549 | } 550 | 551 | func TestStructTags(t *testing.T) { 552 | t.Log("StructTags") 553 | 554 | ob := TaggedStruct{"hello", 42, 6.28} 555 | 556 | blob, err := Dumps(ob) 557 | if err != nil { 558 | t.Error(err) 559 | } 560 | 561 | mapo := make(map[string]interface{}) 562 | err = Loads(blob, &mapo) 563 | if err != nil { 564 | t.Error(err) 565 | } 566 | xs, ok := ms(mapo, "m_one_s", t) 567 | if (!ok) || (xs != "hello") { 568 | t.Errorf("failed to get m_one_s from %#v", mapo) 569 | } 570 | xi, ok := mi(mapo, "bunnies", t) 571 | if (!ok) || (xi != 42) { 572 | t.Errorf("failed to get bunnies from %#v", mapo) 573 | } 574 | xf, ok := mf64(mapo, "three_cbor", t) 575 | if (!ok) || (xf != 6.28) { 576 | t.Errorf("failed to get three_cbor from %#v", mapo) 577 | } 578 | 579 | ob2 := TaggedStruct{} 580 | err = Loads(blob, &ob2) 581 | if err != nil { 582 | t.Error(err) 583 | } 584 | if ob != ob2 { 585 | t.Errorf("a!=b %#v != %#v", ob, ob2) 586 | } 587 | } 588 | 589 | const ( 590 | incSizeStrB64 = "eDVhYWE=" 591 | incSizeBytesB64 = "WDVhYWE=" 592 | incSizeArrayB64 = "mDUBAQE=" 593 | ) 594 | 595 | func TestIncorrectSize(t *testing.T) { 596 | bin, _ := base64.StdEncoding.DecodeString(incSizeStrB64) 597 | dec := NewDecoder(bytes.NewReader(bin)) 598 | 599 | var outStr string 600 | err := dec.Decode(&outStr) 601 | if err.Error() != "unexpected EOF" { 602 | t.Fatal("unexpected error decoding cbor b64", err) 603 | return 604 | } 605 | 606 | bin, _ = base64.StdEncoding.DecodeString(incSizeBytesB64) 607 | dec = NewDecoder(bytes.NewReader(bin)) 608 | 609 | var outBytes []byte 610 | err = dec.Decode(&outBytes) 611 | if err.Error() != "unexpected EOF" { 612 | t.Fatal("unexpected error decoding cbor b64", err) 613 | return 614 | } 615 | 616 | bin, _ = base64.StdEncoding.DecodeString(incSizeArrayB64) 617 | dec = NewDecoder(bytes.NewReader(bin)) 618 | 619 | err = dec.Decode(&outBytes) 620 | if err.Error() != "EOF" { 621 | t.Fatal("unexpected error decoding cbor b64", err) 622 | return 623 | } 624 | } 625 | -------------------------------------------------------------------------------- /go/cbor.go: -------------------------------------------------------------------------------- 1 | // Should be roughly like encoding/gob 2 | // encoding/json has an inferior interface that only works on whole messages to/from whole blobs at once. Reader/Writer based interfaces are better. 3 | 4 | package cbor 5 | 6 | import ( 7 | "bytes" 8 | "errors" 9 | "fmt" 10 | "io" 11 | "log" 12 | "math" 13 | "math/big" 14 | "reflect" 15 | "sort" 16 | "strings" 17 | ) 18 | 19 | var typeMask byte = 0xE0 20 | var infoBits byte = 0x1F 21 | 22 | const ( 23 | MajorTypeUint byte = 0 24 | MajorTypeNegInt byte = iota 25 | MajorTypeBytes 26 | MajorTypeText 27 | MajorTypeArray 28 | MajorTypeMap 29 | MajorTypeTag 30 | MajorTypeSimple 31 | MajorTypeFloat byte = MajorTypeSimple 32 | ) 33 | 34 | const ( 35 | SimpleValueFalse byte = 20 36 | SimpleValueTrue byte = iota 37 | SimpleValueNull 38 | SimpleValueUndefined 39 | ) 40 | 41 | const ( 42 | OpcodeBreak byte = 0x1F 43 | ) 44 | 45 | /* type values */ 46 | var cborUint byte = 0x00 47 | var cborNegint byte = 0x20 48 | var cborBytes byte = 0x40 49 | var cborText byte = 0x60 50 | var cborArray byte = 0x80 51 | var cborMap byte = 0xA0 52 | var cborTag byte = 0xC0 53 | var cbor7 byte = 0xE0 54 | 55 | /* cbor7 values */ 56 | const ( 57 | cborFalse byte = 20 58 | cborTrue byte = 21 59 | cborNull byte = 22 60 | ) 61 | 62 | /* info bits */ 63 | var int8Follows byte = 24 64 | var int16Follows byte = 25 65 | var int32Follows byte = 26 66 | var int64Follows byte = 27 67 | var varFollows byte = 31 68 | 69 | /* tag values */ 70 | var tagBignum uint64 = 2 71 | var tagNegBignum uint64 = 3 72 | var tagDecimal uint64 = 4 73 | var tagBigfloat uint64 = 5 74 | 75 | /* batch sizes */ 76 | var byteBatch = 1 << 20 77 | var arrayBatch = 1 << 14 //16k 78 | 79 | // TODO: honor encoding.BinaryMarshaler interface and encapsulate blob returned from that. 80 | 81 | // Load one object into v 82 | func Loads(blob []byte, v interface{}) error { 83 | dec := NewDecoder(bytes.NewReader(blob)) 84 | return dec.Decode(v) 85 | } 86 | 87 | type TagDecoder interface { 88 | // Handle things which match this. 89 | // 90 | // Setup like this: 91 | // var dec Decoder 92 | // var myTagDec TagDecoder 93 | // dec.TagDecoders[myTagDec.GetTag()] = myTagDec 94 | GetTag() uint64 95 | 96 | // Sub-object will be decoded onto the returned object. 97 | DecodeTarget() interface{} 98 | 99 | // Run after decode onto DecodeTarget has happened. 100 | // The return value from this is returned in place of the 101 | // raw decoded object. 102 | PostDecode(interface{}) (interface{}, error) 103 | } 104 | 105 | type Decoder struct { 106 | reader io.Reader 107 | 108 | // tag byte 109 | tag []byte 110 | 111 | // many values fit within the next 8 bytes 112 | b8 []byte 113 | 114 | // Extra processing for CBOR TAG objects. 115 | TagDecoders map[uint64]TagDecoder 116 | } 117 | 118 | func NewDecoder(r io.Reader) *Decoder { 119 | return &Decoder{ 120 | reader: r, 121 | tag: make([]byte, 1), 122 | b8: make([]byte, 8), 123 | TagDecoders: make(map[uint64]TagDecoder), 124 | } 125 | } 126 | func (dec *Decoder) Decode(v interface{}) error { 127 | rv := reflect.ValueOf(v) 128 | 129 | return dec.DecodeAny(newReflectValue(rv)) 130 | } 131 | 132 | type DecodeValue interface { 133 | // Before decoding, check if there is no error 134 | Prepare() error 135 | 136 | // Got binary string 137 | SetBytes(buf []byte) error 138 | 139 | // Got a number (different formats) 140 | SetBignum(x *big.Int) error 141 | SetUint(u uint64) error 142 | SetInt(i int64) error 143 | SetFloat32(f float32) error 144 | SetFloat64(d float64) error 145 | 146 | // Got null 147 | SetNil() error 148 | 149 | // Got boolean 150 | SetBool(b bool) error 151 | 152 | // Got text string 153 | SetString(s string) error 154 | 155 | // Got a Map (beginning) 156 | CreateMap() (DecodeValueMap, error) 157 | 158 | // Got an array (beginning) 159 | CreateArray(makeLength int) (DecodeValueArray, error) 160 | 161 | // Got a tag 162 | CreateTag(aux uint64, decoder TagDecoder) (DecodeValue, interface{}, error) 163 | 164 | // Got the tag value (maybe transformed by TagDecoder.PostDecode) 165 | SetTag(aux uint64, v DecodeValue, decoder TagDecoder, i interface{}) error 166 | } 167 | 168 | type DecodeValueMap interface { 169 | // Got a map key 170 | CreateMapKey() (DecodeValue, error) 171 | 172 | // Got a map value 173 | CreateMapValue(key DecodeValue) (DecodeValue, error) 174 | 175 | // Got a key / value pair 176 | SetMap(key, val DecodeValue) error 177 | 178 | // The map is at the end 179 | EndMap() error 180 | } 181 | 182 | type DecodeValueArray interface { 183 | // Got an array item 184 | GetArrayValue(index uint64) (DecodeValue, error) 185 | 186 | // After the array item is decoded 187 | AppendArray(value DecodeValue) error 188 | 189 | // The array is at the end 190 | EndArray() error 191 | } 192 | 193 | type reflectValue struct { 194 | v reflect.Value 195 | } 196 | 197 | type MemoryValue struct { 198 | reflectValue 199 | Value interface{} 200 | } 201 | 202 | func NewMemoryValue(value interface{}) *MemoryValue { 203 | res := &MemoryValue{ 204 | reflectValue{reflect.ValueOf(nil)}, 205 | value, 206 | } 207 | res.v = reflect.ValueOf(&res.Value) 208 | return res 209 | } 210 | 211 | func (mv *MemoryValue) ReflectValue() reflect.Value { 212 | return mv.v 213 | } 214 | 215 | func newReflectValue(rv reflect.Value) *reflectValue { 216 | return &reflectValue{rv} 217 | } 218 | 219 | func (r *reflectValue) Prepare() error { 220 | rv := r.v 221 | if (!rv.CanSet()) && (rv.Kind() != reflect.Ptr || rv.IsNil()) { 222 | return &InvalidUnmarshalError{rv.Type()} 223 | } 224 | return nil 225 | } 226 | 227 | func (dec *Decoder) DecodeAny(v DecodeValue) error { 228 | var err error 229 | 230 | _, err = io.ReadFull(dec.reader, dec.tag) 231 | if err != nil { 232 | return err 233 | } 234 | 235 | if err := v.Prepare(); err != nil { 236 | return err 237 | } 238 | 239 | return dec.innerDecodeC(v, dec.tag[0]) 240 | } 241 | 242 | func (dec *Decoder) handleInfoBits(cborInfo byte) (uint64, error) { 243 | var aux uint64 244 | 245 | if cborInfo <= 23 { 246 | aux = uint64(cborInfo) 247 | return aux, nil 248 | } else if cborInfo == int8Follows { 249 | didread, err := io.ReadFull(dec.reader, dec.b8[:1]) 250 | if didread == 1 { 251 | aux = uint64(dec.b8[0]) 252 | } 253 | return aux, err 254 | } else if cborInfo == int16Follows { 255 | didread, err := io.ReadFull(dec.reader, dec.b8[:2]) 256 | if didread == 2 { 257 | aux = (uint64(dec.b8[0]) << 8) | uint64(dec.b8[1]) 258 | } 259 | return aux, err 260 | } else if cborInfo == int32Follows { 261 | didread, err := io.ReadFull(dec.reader, dec.b8[:4]) 262 | if didread == 4 { 263 | aux = (uint64(dec.b8[0]) << 24) | 264 | (uint64(dec.b8[1]) << 16) | 265 | (uint64(dec.b8[2]) << 8) | 266 | uint64(dec.b8[3]) 267 | } 268 | return aux, err 269 | } else if cborInfo == int64Follows { 270 | didread, err := io.ReadFull(dec.reader, dec.b8) 271 | if didread == 8 { 272 | var shift uint = 56 273 | i := 0 274 | aux = uint64(dec.b8[i]) << shift 275 | for i < 7 { 276 | i += 1 277 | shift -= 8 278 | aux |= uint64(dec.b8[i]) << shift 279 | } 280 | } 281 | return aux, err 282 | } 283 | return 0, nil 284 | } 285 | 286 | func (dec *Decoder) innerDecodeC(rv DecodeValue, c byte) error { 287 | cborType := c & typeMask 288 | cborInfo := c & infoBits 289 | 290 | aux, err := dec.handleInfoBits(cborInfo) 291 | if err != nil { 292 | log.Printf("error in handleInfoBits: %v", err) 293 | return err 294 | } 295 | //log.Printf("cborType %x cborInfo %d aux %x", cborType, cborInfo, aux) 296 | 297 | if cborType == cborUint { 298 | return rv.SetUint(aux) 299 | } else if cborType == cborNegint { 300 | if aux > 0x7fffffffffffffff { 301 | //return errors.New(fmt.Sprintf("cannot represent -%d", aux)) 302 | bigU := &big.Int{} 303 | bigU.SetUint64(aux) 304 | minusOne := big.NewInt(-1) 305 | bn := &big.Int{} 306 | bn.Sub(minusOne, bigU) 307 | //log.Printf("built big negint: %v", bn) 308 | return rv.SetBignum(bn) 309 | } 310 | return rv.SetInt(-1 - int64(aux)) 311 | } else if cborType == cborBytes { 312 | //log.Printf("cborType %x bytes cborInfo %d aux %x", cborType, cborInfo, aux) 313 | if cborInfo == varFollows { 314 | parts := make([][]byte, 0, 1) 315 | allsize := 0 316 | subc := []byte{0} 317 | for true { 318 | _, err = io.ReadFull(dec.reader, subc) 319 | if err != nil { 320 | log.Printf("error reading next byte for bar bytes") 321 | return err 322 | } 323 | if subc[0] == 0xff { 324 | // done 325 | var out []byte = nil 326 | if len(parts) == 0 { 327 | out = make([]byte, 0) 328 | } else { 329 | pos := 0 330 | out = make([]byte, allsize) 331 | for _, p := range parts { 332 | pos += copy(out[pos:], p) 333 | } 334 | } 335 | return rv.SetBytes(out) 336 | } else { 337 | var subb []byte = nil 338 | if (subc[0] & typeMask) != cborBytes { 339 | return fmt.Errorf("sub of var bytes is type %x, wanted %x", subc[0], cborBytes) 340 | } 341 | err = dec.innerDecodeC(newReflectValue(reflect.ValueOf(&subb)), subc[0]) 342 | if err != nil { 343 | log.Printf("error decoding sub bytes") 344 | return err 345 | } 346 | allsize += len(subb) 347 | parts = append(parts, subb) 348 | } 349 | } 350 | } else { 351 | val, err := dec.readBytes(aux) 352 | if err != nil { 353 | return err 354 | } 355 | return rv.SetBytes(val) 356 | } 357 | } else if cborType == cborText { 358 | return dec.decodeText(rv, cborInfo, aux) 359 | } else if cborType == cborArray { 360 | return dec.decodeArray(rv, cborInfo, aux) 361 | } else if cborType == cborMap { 362 | return dec.decodeMap(rv, cborInfo, aux) 363 | } else if cborType == cborTag { 364 | /*var innerOb interface{}*/ 365 | ic := []byte{0} 366 | _, err = io.ReadFull(dec.reader, ic) 367 | if err != nil { 368 | return err 369 | } 370 | if aux == tagBignum { 371 | bn, err := dec.decodeBignum(ic[0]) 372 | if err != nil { 373 | return err 374 | } 375 | return rv.SetBignum(bn) 376 | } else if aux == tagNegBignum { 377 | bn, err := dec.decodeBignum(ic[0]) 378 | if err != nil { 379 | return err 380 | } 381 | minusOne := big.NewInt(-1) 382 | bnOut := &big.Int{} 383 | bnOut.Sub(minusOne, bn) 384 | return rv.SetBignum(bnOut) 385 | } else if aux == tagDecimal { 386 | log.Printf("TODO: directly read bytes into decimal") 387 | } else if aux == tagBigfloat { 388 | log.Printf("TODO: directly read bytes into bigfloat") 389 | } else { 390 | decoder := dec.TagDecoders[aux] 391 | var target interface{} 392 | var trv DecodeValue 393 | var err error 394 | 395 | trv, target, err = rv.CreateTag(aux, decoder) 396 | if err != nil { 397 | return err 398 | } 399 | 400 | err = dec.innerDecodeC(trv, ic[0]) 401 | if err != nil { 402 | return err 403 | } 404 | 405 | return rv.SetTag(aux, trv, decoder, target) 406 | } 407 | return nil 408 | } else if cborType == cbor7 { 409 | if cborInfo == int16Follows { 410 | exp := (aux >> 10) & 0x01f 411 | mant := aux & 0x03ff 412 | var val float64 413 | if exp == 0 { 414 | val = math.Ldexp(float64(mant), -24) 415 | } else if exp != 31 { 416 | val = math.Ldexp(float64(mant+1024), int(exp-25)) 417 | } else if mant == 0 { 418 | val = math.Inf(1) 419 | } else { 420 | val = math.NaN() 421 | } 422 | if (aux & 0x08000) != 0 { 423 | val = -val 424 | } 425 | return rv.SetFloat64(val) 426 | } else if cborInfo == int32Follows { 427 | f := math.Float32frombits(uint32(aux)) 428 | return rv.SetFloat32(f) 429 | } else if cborInfo == int64Follows { 430 | d := math.Float64frombits(aux) 431 | return rv.SetFloat64(d) 432 | } else if cborInfo == cborFalse { 433 | return rv.SetBool(false) 434 | } else if cborInfo == cborTrue { 435 | return rv.SetBool(true) 436 | } else if cborInfo == cborNull { 437 | return rv.SetNil() 438 | } 439 | } 440 | 441 | return err 442 | } 443 | 444 | func (dec *Decoder) decodeText(rv DecodeValue, cborInfo byte, aux uint64) error { 445 | var err error 446 | if cborInfo == varFollows { 447 | parts := make([]string, 0, 1) 448 | subc := []byte{0} 449 | for true { 450 | _, err = io.ReadFull(dec.reader, subc) 451 | if err != nil { 452 | log.Printf("error reading next byte for var text") 453 | return err 454 | } 455 | if subc[0] == 0xff { 456 | // done 457 | joined := strings.Join(parts, "") 458 | return rv.SetString(joined) 459 | } else { 460 | var subtext interface{} 461 | err = dec.innerDecodeC(newReflectValue(reflect.ValueOf(&subtext)), subc[0]) 462 | if err != nil { 463 | log.Printf("error decoding subtext") 464 | return err 465 | } 466 | st, ok := subtext.(string) 467 | if ok { 468 | parts = append(parts, st) 469 | } else { 470 | return fmt.Errorf("var text sub element not text but %T", subtext) 471 | } 472 | } 473 | } 474 | } else { 475 | raw, err := dec.readBytes(aux) 476 | if err != nil { 477 | return err 478 | } 479 | xs := string(raw) 480 | return rv.SetString(xs) 481 | } 482 | return errors.New("internal error in decodeText, shouldn't get here") 483 | } 484 | 485 | func (dec *Decoder) readBytes(n uint64) ([]byte, error) { 486 | buf := new(bytes.Buffer) 487 | r, err := buf.ReadFrom(&io.LimitedReader{R: dec.reader, N: int64(n)}) 488 | if err != nil { 489 | return nil, err 490 | } 491 | 492 | if r != int64(n) { 493 | return nil, io.ErrUnexpectedEOF 494 | } 495 | return buf.Bytes(), nil 496 | } 497 | 498 | type mapAssignable interface { 499 | ReflectValueForKey(key interface{}) (*reflect.Value, bool) 500 | SetReflectValueForKey(key interface{}, value reflect.Value) error 501 | } 502 | 503 | type mapReflectValue struct { 504 | reflect.Value 505 | } 506 | 507 | func (irv *mapReflectValue) ReflectValueForKey(key interface{}) (*reflect.Value, bool) { 508 | //var x interface{} 509 | //rv := reflect.ValueOf(&x) 510 | rv := reflect.New(irv.Type().Elem()) 511 | return &rv, true 512 | } 513 | func (irv *mapReflectValue) SetReflectValueForKey(key interface{}, value reflect.Value) error { 514 | //log.Printf("k T %T v%#v, v T %s v %#v", key, key, value.Type().String(), value.Interface()) 515 | krv := reflect.Indirect(reflect.ValueOf(key)) 516 | vrv := reflect.Indirect(value) 517 | //log.Printf("irv T %s v %#v", irv.Type().String(), irv.Interface()) 518 | //log.Printf("k T %s v %#v, v T %s v %#v", krv.Type().String(), krv.Interface(), vrv.Type().String(), vrv.Interface()) 519 | if krv.Kind() == reflect.Interface { 520 | krv = krv.Elem() 521 | //log.Printf("ke T %s v %#v", krv.Type().String(), krv.Interface()) 522 | } 523 | if (krv.Kind() == reflect.Slice) || (krv.Kind() == reflect.Array) { 524 | //log.Printf("key is slice or array") 525 | if krv.Type().Elem().Kind() == reflect.Uint8 { 526 | //log.Printf("key is []uint8") 527 | ks := string(krv.Bytes()) 528 | krv = reflect.ValueOf(ks) 529 | } 530 | } 531 | irv.SetMapIndex(krv, vrv) 532 | 533 | return nil 534 | } 535 | 536 | type structAssigner struct { 537 | Srv reflect.Value 538 | 539 | //keyType reflect.Type 540 | } 541 | 542 | func (sa *structAssigner) ReflectValueForKey(key interface{}) (*reflect.Value, bool) { 543 | var skey string 544 | switch tkey := key.(type) { 545 | case string: 546 | skey = tkey 547 | case *string: 548 | skey = *tkey 549 | default: 550 | log.Printf("rvfk key is not string, got %T", key) 551 | return nil, false 552 | } 553 | 554 | ft := sa.Srv.Type() 555 | numFields := ft.NumField() 556 | for i := 0; i < numFields; i++ { 557 | sf := ft.Field(i) 558 | fieldname, ok := fieldname(sf) 559 | if !ok { 560 | continue 561 | } 562 | if (fieldname == skey) || strings.EqualFold(fieldname, skey) { 563 | fieldVal := sa.Srv.FieldByName(sf.Name) 564 | if !fieldVal.CanSet() { 565 | log.Printf("cannot set field %s for key %s", sf.Name, skey) 566 | return nil, false 567 | } 568 | return &fieldVal, true 569 | } 570 | } 571 | return nil, false 572 | } 573 | func (sa *structAssigner) SetReflectValueForKey(key interface{}, value reflect.Value) error { 574 | return nil 575 | } 576 | 577 | func (dec *Decoder) setMapKV(dvm DecodeValueMap, krv DecodeValue) error { 578 | var err error 579 | val, err := dvm.CreateMapValue(krv) 580 | if err != nil { 581 | var throwaway interface{} 582 | err = dec.Decode(&throwaway) 583 | if err != nil { 584 | return err 585 | } 586 | return nil 587 | } 588 | err = dec.DecodeAny(val) 589 | if err != nil { 590 | log.Printf("error decoding map val: T %T v %#v", val, val) 591 | return err 592 | } 593 | err = dvm.SetMap(krv, val) 594 | if err != nil { 595 | log.Printf("error setting value") 596 | return err 597 | } 598 | 599 | return nil 600 | } 601 | 602 | func (r *reflectValue) CreateMap() (DecodeValueMap, error) { 603 | rv := r.v 604 | var drv reflect.Value 605 | if rv.Kind() == reflect.Ptr { 606 | drv = reflect.Indirect(rv) 607 | } else { 608 | drv = rv 609 | } 610 | //log.Print("decode map into d ", drv.Type().String()) 611 | 612 | // inner reflect value 613 | var irv reflect.Value 614 | var ma mapAssignable 615 | 616 | var keyType reflect.Type 617 | 618 | switch drv.Kind() { 619 | case reflect.Interface: 620 | //log.Print("decode map into interface ", drv.Type().String()) 621 | // TODO: maybe I should make this map[string]interface{} 622 | nob := make(map[interface{}]interface{}) 623 | irv = reflect.ValueOf(nob) 624 | ma = &mapReflectValue{irv} 625 | keyType = irv.Type().Key() 626 | case reflect.Struct: 627 | //log.Print("decode map into struct ", drv.Type().String()) 628 | ma = &structAssigner{drv} 629 | keyType = reflect.TypeOf("") 630 | case reflect.Map: 631 | //log.Print("decode map into map ", drv.Type().String()) 632 | if drv.IsNil() { 633 | if drv.CanSet() { 634 | drv.Set(reflect.MakeMap(drv.Type())) 635 | } else { 636 | return nil, fmt.Errorf("target map is nil and not settable") 637 | } 638 | } 639 | keyType = drv.Type().Key() 640 | ma = &mapReflectValue{drv} 641 | default: 642 | return nil, fmt.Errorf("can't read map into %s", rv.Type().String()) 643 | } 644 | 645 | return &reflectValueMap{drv, irv, ma, keyType}, nil 646 | } 647 | 648 | type reflectValueMap struct { 649 | drv reflect.Value 650 | irv reflect.Value 651 | ma mapAssignable 652 | keyType reflect.Type 653 | } 654 | 655 | func (r *reflectValueMap) CreateMapKey() (DecodeValue, error) { 656 | return newReflectValue(reflect.New(r.keyType)), nil 657 | } 658 | 659 | func (r *reflectValueMap) CreateMapValue(key DecodeValue) (DecodeValue, error) { 660 | var err error 661 | v, ok := r.ma.ReflectValueForKey(key.(*reflectValue).v.Interface()) 662 | if !ok { 663 | err = fmt.Errorf("Could not reflect value for key") 664 | } 665 | return newReflectValue(*v), err 666 | } 667 | 668 | func (r *reflectValueMap) SetMap(key, val DecodeValue) error { 669 | return r.ma.SetReflectValueForKey(key.(*reflectValue).v.Interface(), val.(*reflectValue).v) 670 | } 671 | 672 | func (r *reflectValueMap) EndMap() error { 673 | if r.drv.Kind() == reflect.Interface { 674 | r.drv.Set(r.irv) 675 | } 676 | return nil 677 | } 678 | 679 | func (dec *Decoder) decodeMap(rv DecodeValue, cborInfo byte, aux uint64) error { 680 | //log.Print("decode map into ", rv.Type().String()) 681 | // dereferenced reflect value 682 | var dvm DecodeValueMap 683 | var err error 684 | 685 | dvm, err = rv.CreateMap() 686 | if err != nil { 687 | return err 688 | } 689 | 690 | if cborInfo == varFollows { 691 | subc := []byte{0} 692 | for true { 693 | _, err = io.ReadFull(dec.reader, subc) 694 | if err != nil { 695 | log.Printf("error reading next byte for var text") 696 | return err 697 | } 698 | if subc[0] == 0xff { 699 | // Done 700 | break 701 | } else { 702 | //var key interface{} 703 | krv, err := dvm.CreateMapKey() 704 | if err != nil { 705 | return err 706 | } 707 | //var val interface{} 708 | err = dec.innerDecodeC(krv, subc[0]) 709 | if err != nil { 710 | log.Printf("error decoding map key V, %s", err) 711 | return err 712 | } 713 | 714 | err = dec.setMapKV(dvm, krv) 715 | if err != nil { 716 | return err 717 | } 718 | } 719 | } 720 | } else { 721 | var i uint64 722 | for i = 0; i < aux; i++ { 723 | //var key interface{} 724 | krv, err := dvm.CreateMapKey() 725 | if err != nil { 726 | return err 727 | } 728 | //var val interface{} 729 | //err = dec.Decode(&key) 730 | err = dec.DecodeAny(krv) 731 | if err != nil { 732 | log.Printf("error decoding map key #, %s", err) 733 | return err 734 | } 735 | err = dec.setMapKV(dvm, krv) 736 | if err != nil { 737 | return err 738 | } 739 | } 740 | } 741 | 742 | return dvm.EndMap() 743 | } 744 | 745 | func (r *reflectValue) CreateArray(makeLength int) (DecodeValueArray, error) { 746 | var rv reflect.Value = r.v 747 | 748 | if rv.Kind() == reflect.Ptr { 749 | rv = reflect.Indirect(rv) 750 | } 751 | 752 | // inner reflect value 753 | var irv reflect.Value 754 | var elemType reflect.Type 755 | 756 | switch rv.Kind() { 757 | case reflect.Interface: 758 | // make a slice 759 | nob := make([]interface{}, 0, makeLength) 760 | irv = reflect.ValueOf(nob) 761 | elemType = irv.Type().Elem() 762 | case reflect.Slice: 763 | // we have a slice 764 | irv = rv 765 | elemType = irv.Type().Elem() 766 | case reflect.Array: 767 | // no irv, no elemType 768 | default: 769 | return nil, fmt.Errorf("can't read array into %s", rv.Type().String()) 770 | } 771 | 772 | return &reflectValueArray{rv, makeLength, irv, elemType, 0}, nil 773 | } 774 | 775 | type reflectValueArray struct { 776 | rv reflect.Value 777 | makeLength int 778 | irv reflect.Value 779 | elemType reflect.Type 780 | arrayPos int 781 | } 782 | 783 | func (r *reflectValueArray) GetArrayValue(index uint64) (DecodeValue, error) { 784 | if r.rv.Kind() == reflect.Array { 785 | return &reflectValue{r.rv.Index(r.arrayPos)}, nil 786 | } else { 787 | return &reflectValue{reflect.New(r.elemType)}, nil 788 | } 789 | } 790 | 791 | func (r *reflectValueArray) AppendArray(subrv DecodeValue) error { 792 | if r.rv.Kind() == reflect.Array { 793 | r.arrayPos++ 794 | } else { 795 | r.irv = reflect.Append(r.irv, reflect.Indirect(subrv.(*reflectValue).v)) 796 | } 797 | return nil 798 | } 799 | 800 | func (r *reflectValueArray) EndArray() error { 801 | if r.rv.Kind() != reflect.Array { 802 | r.rv.Set(r.irv) 803 | } 804 | return nil 805 | } 806 | 807 | func (dec *Decoder) decodeArray(rv DecodeValue, cborInfo byte, aux uint64) error { 808 | 809 | var err error 810 | var dva DecodeValueArray 811 | 812 | var makeLength int = 0 813 | if cborInfo == varFollows { 814 | // no special capacity to allocate the slice to 815 | } else { 816 | makeLength = int(aux) 817 | } 818 | 819 | dva, err = rv.CreateArray(int(min(uint64(makeLength), uint64(arrayBatch)))) 820 | if err != nil { 821 | return err 822 | } 823 | 824 | if cborInfo == varFollows { 825 | //log.Printf("var array") 826 | subc := []byte{0} 827 | var idx uint64 = 0 828 | for true { 829 | _, err = io.ReadFull(dec.reader, subc) 830 | if err != nil { 831 | log.Printf("error reading next byte for var text") 832 | return err 833 | } 834 | if subc[0] == 0xff { 835 | // Done 836 | break 837 | } 838 | subrv, err := dva.GetArrayValue(idx) 839 | if err != nil { 840 | return err 841 | } 842 | err = dec.innerDecodeC(subrv, subc[0]) 843 | if err != nil { 844 | log.Printf("error decoding array subob") 845 | return err 846 | } 847 | err = dva.AppendArray(subrv) 848 | if err != nil { 849 | return err 850 | } 851 | idx++ 852 | } 853 | } else { 854 | var i uint64 855 | for i = 0; i < aux; i++ { 856 | subrv, err := dva.GetArrayValue(i) 857 | if err != nil { 858 | return err 859 | } 860 | err = dec.DecodeAny(subrv) 861 | if err != nil { 862 | log.Printf("error decoding array subob") 863 | return err 864 | } 865 | err = dva.AppendArray(subrv) 866 | if err != nil { 867 | return err 868 | } 869 | } 870 | } 871 | 872 | return dva.EndArray() 873 | } 874 | 875 | func (dec *Decoder) decodeBignum(c byte) (*big.Int, error) { 876 | cborType := c & typeMask 877 | cborInfo := c & infoBits 878 | 879 | aux, err := dec.handleInfoBits(cborInfo) 880 | if err != nil { 881 | log.Printf("error in bignum handleInfoBits: %v", err) 882 | return nil, err 883 | } 884 | //log.Printf("bignum cborType %x cborInfo %d aux %x", cborType, cborInfo, aux) 885 | 886 | if cborType != cborBytes { 887 | return nil, fmt.Errorf("attempting to decode bignum but sub object is not bytes but type %x", cborType) 888 | } 889 | 890 | rawbytes, err := dec.readBytes(aux) 891 | if err != nil { 892 | return nil, err 893 | } 894 | 895 | bn := big.NewInt(0) 896 | littleBig := &big.Int{} 897 | d := &big.Int{} 898 | for _, bv := range rawbytes { 899 | d.Lsh(bn, 8) 900 | littleBig.SetUint64(uint64(bv)) 901 | bn.Or(d, littleBig) 902 | } 903 | 904 | return bn, nil 905 | } 906 | 907 | func (r *reflectValue) SetBignum(x *big.Int) error { 908 | rv := r.v 909 | switch rv.Kind() { 910 | case reflect.Ptr: 911 | return newReflectValue(reflect.Indirect(rv)).SetBignum(x) 912 | case reflect.Interface: 913 | rv.Set(reflect.ValueOf(*x)) 914 | return nil 915 | case reflect.Int32: 916 | if x.BitLen() < 32 { 917 | rv.SetInt(x.Int64()) 918 | return nil 919 | } else { 920 | return fmt.Errorf("int too big for int32 target") 921 | } 922 | case reflect.Int, reflect.Int64: 923 | if x.BitLen() < 64 { 924 | rv.SetInt(x.Int64()) 925 | return nil 926 | } else { 927 | return fmt.Errorf("int too big for int64 target") 928 | } 929 | default: 930 | return fmt.Errorf("cannot assign bignum into Kind=%s Type=%s %#v", rv.Kind().String(), rv.Type().String(), rv) 931 | } 932 | } 933 | 934 | func (r *reflectValue) SetBytes(buf []byte) error { 935 | rv := r.v 936 | switch rv.Kind() { 937 | case reflect.Ptr: 938 | return newReflectValue(reflect.Indirect(rv)).SetBytes(buf) 939 | case reflect.Interface: 940 | rv.Set(reflect.ValueOf(buf)) 941 | return nil 942 | case reflect.Slice: 943 | if rv.Type().Elem().Kind() == reflect.Uint8 { 944 | rv.SetBytes(buf) 945 | return nil 946 | } else { 947 | return fmt.Errorf("cannot write []byte to k=%s %s", rv.Kind().String(), rv.Type().String()) 948 | } 949 | case reflect.String: 950 | rv.Set(reflect.ValueOf(string(buf))) 951 | return nil 952 | default: 953 | return fmt.Errorf("cannot assign []byte into Kind=%s Type=%s %#v", rv.Kind().String(), "" /*rv.Type().String()*/, rv) 954 | } 955 | } 956 | 957 | func (r *reflectValue) SetUint(u uint64) error { 958 | rv := r.v 959 | switch rv.Kind() { 960 | case reflect.Ptr: 961 | if rv.IsNil() { 962 | if rv.CanSet() { 963 | rv.Set(reflect.New(rv.Type().Elem())) 964 | // fall through to set indirect below 965 | } else { 966 | return fmt.Errorf("trying to put uint into unsettable nil ptr") 967 | } 968 | } 969 | return newReflectValue(reflect.Indirect(rv)).SetUint(u) 970 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 971 | if rv.OverflowUint(u) { 972 | return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String()) 973 | } 974 | rv.SetUint(u) 975 | return nil 976 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 977 | if (u == 0xffffffffffffffff) || rv.OverflowInt(int64(u)) { 978 | return fmt.Errorf("value %d does not fit into target of type %s", u, rv.Kind().String()) 979 | } 980 | rv.SetInt(int64(u)) 981 | return nil 982 | case reflect.Interface: 983 | rv.Set(reflect.ValueOf(u)) 984 | return nil 985 | default: 986 | return fmt.Errorf("cannot assign uint into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv) 987 | } 988 | } 989 | func (r *reflectValue) SetInt(i int64) error { 990 | rv := r.v 991 | switch rv.Kind() { 992 | case reflect.Ptr: 993 | return newReflectValue(reflect.Indirect(rv)).SetInt(i) 994 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 995 | if rv.OverflowInt(i) { 996 | return fmt.Errorf("value %d does not fit into target of type %s", i, rv.Kind().String()) 997 | } 998 | rv.SetInt(i) 999 | return nil 1000 | case reflect.Interface: 1001 | rv.Set(reflect.ValueOf(i)) 1002 | return nil 1003 | default: 1004 | return fmt.Errorf("cannot assign int into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv) 1005 | } 1006 | } 1007 | func (r *reflectValue) SetFloat32(f float32) error { 1008 | rv := r.v 1009 | switch rv.Kind() { 1010 | case reflect.Ptr: 1011 | return newReflectValue(reflect.Indirect(rv)).SetFloat32(f) 1012 | case reflect.Float32, reflect.Float64: 1013 | rv.SetFloat(float64(f)) 1014 | return nil 1015 | case reflect.Interface: 1016 | rv.Set(reflect.ValueOf(f)) 1017 | return nil 1018 | default: 1019 | return fmt.Errorf("cannot assign float32 into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv) 1020 | } 1021 | } 1022 | func (r *reflectValue) SetFloat64(d float64) error { 1023 | rv := r.v 1024 | switch rv.Kind() { 1025 | case reflect.Ptr: 1026 | return newReflectValue(reflect.Indirect(rv)).SetFloat64(d) 1027 | case reflect.Float32, reflect.Float64: 1028 | rv.SetFloat(d) 1029 | return nil 1030 | case reflect.Interface: 1031 | rv.Set(reflect.ValueOf(d)) 1032 | return nil 1033 | default: 1034 | return fmt.Errorf("cannot assign float64 into Kind=%s Type=%#v %#v", rv.Kind().String(), rv.Type(), rv) 1035 | } 1036 | } 1037 | func (r *reflectValue) SetNil() error { 1038 | rv := r.v 1039 | switch rv.Kind() { 1040 | case reflect.Ptr: 1041 | //return setNil(reflect.Indirect(rv)) 1042 | rv.Elem().Set(reflect.Zero(rv.Elem().Type())) 1043 | case reflect.Interface: 1044 | if rv.IsNil() { 1045 | // already nil, okay! 1046 | return nil 1047 | } 1048 | rv.Set(reflect.Zero(rv.Type())) 1049 | default: 1050 | log.Printf("setNil wat %s", rv.Type()) 1051 | rv.Set(reflect.Zero(rv.Type())) 1052 | } 1053 | return nil 1054 | } 1055 | 1056 | func (r *reflectValue) SetBool(b bool) error { 1057 | rv := r.v 1058 | reflect.Indirect(rv).Set(reflect.ValueOf(b)) 1059 | return nil 1060 | } 1061 | 1062 | func (r *reflectValue) SetString(xs string) error { 1063 | rv := r.v 1064 | // handle either concrete string or string* to nil 1065 | deref := reflect.Indirect(rv) 1066 | if !deref.CanSet() { 1067 | rv.Set(reflect.ValueOf(&xs)) 1068 | } else { 1069 | deref.Set(reflect.ValueOf(xs)) 1070 | } 1071 | //reflect.Indirect(rv).Set(reflect.ValueOf(joined)) 1072 | return nil 1073 | } 1074 | 1075 | func (r *reflectValue) CreateTag(aux uint64, decoder TagDecoder) (DecodeValue, interface{}, error) { 1076 | if decoder != nil { 1077 | target := decoder.DecodeTarget() 1078 | return newReflectValue(reflect.ValueOf(target)), target, nil 1079 | } else { 1080 | target := &CBORTag{} 1081 | target.Tag = aux 1082 | return newReflectValue(reflect.ValueOf(&target.WrappedObject)), target, nil 1083 | } 1084 | } 1085 | 1086 | func (r *reflectValue) SetTag(code uint64, val DecodeValue, decoder TagDecoder, target interface{}) error { 1087 | rv := r.v 1088 | var err error 1089 | if decoder != nil { 1090 | target, err = decoder.PostDecode(target) 1091 | if err != nil { 1092 | return err 1093 | } 1094 | } 1095 | reflect.Indirect(rv).Set(reflect.ValueOf(target)) 1096 | return nil 1097 | } 1098 | 1099 | // copied from encoding/json/decode.go 1100 | // An InvalidUnmarshalError describes an invalid argument passed to Unmarshal. 1101 | // (The argument to Unmarshal must be a non-nil pointer.) 1102 | type InvalidUnmarshalError struct { 1103 | Type reflect.Type 1104 | } 1105 | 1106 | func (e *InvalidUnmarshalError) Error() string { 1107 | if e.Type == nil { 1108 | return "json: Unmarshal(nil)" 1109 | } 1110 | 1111 | if e.Type.Kind() != reflect.Ptr { 1112 | return "json: Unmarshal(non-pointer " + e.Type.String() + ")" 1113 | } 1114 | return "json: Unmarshal(nil " + e.Type.String() + ")" 1115 | } 1116 | 1117 | type CBORTag struct { 1118 | Tag uint64 1119 | WrappedObject interface{} 1120 | } 1121 | 1122 | func (t *CBORTag) ToCBOR(w io.Writer, enc *Encoder) error { 1123 | _, err := w.Write(EncodeInt(MajorTypeTag, t.Tag, nil)) 1124 | if err != nil { 1125 | return err 1126 | } 1127 | 1128 | return enc.Encode(t.WrappedObject) 1129 | } 1130 | 1131 | type Encoder struct { 1132 | out io.Writer 1133 | filter func(v interface{}) interface{} 1134 | 1135 | scratch []byte 1136 | } 1137 | 1138 | // parse StructField.Tag.Get("json" or "cbor") 1139 | func fieldTagName(xinfo string) (string, bool) { 1140 | if len(xinfo) != 0 { 1141 | // e.g. `json:"field_name,omitempty"`, or same for cbor 1142 | // TODO: honor 'omitempty' option 1143 | jiparts := strings.Split(xinfo, ",") 1144 | if len(jiparts) > 0 { 1145 | fieldName := jiparts[0] 1146 | if len(fieldName) > 0 { 1147 | return fieldName, true 1148 | } 1149 | } 1150 | } 1151 | return "", false 1152 | } 1153 | 1154 | // Return fieldname, bool; if bool is false, don't use this field 1155 | func fieldname(fieldinfo reflect.StructField) (string, bool) { 1156 | if fieldinfo.PkgPath != "" { 1157 | // has path to private package. don't export 1158 | return "", false 1159 | } 1160 | fieldname, ok := fieldTagName(fieldinfo.Tag.Get("cbor")) 1161 | if !ok { 1162 | fieldname, ok = fieldTagName(fieldinfo.Tag.Get("json")) 1163 | } 1164 | if ok { 1165 | if fieldname == "" { 1166 | return fieldinfo.Name, true 1167 | } 1168 | if fieldname == "-" { 1169 | return "", false 1170 | } 1171 | return fieldname, true 1172 | } 1173 | return fieldinfo.Name, true 1174 | } 1175 | 1176 | // Write out an object to an io.Writer 1177 | func Encode(out io.Writer, ob interface{}) error { 1178 | return NewEncoder(out).Encode(ob) 1179 | } 1180 | 1181 | // Write out an object to a new byte slice 1182 | func Dumps(ob interface{}) ([]byte, error) { 1183 | writeTarget := &bytes.Buffer{} 1184 | writeTarget.Grow(20000) 1185 | err := Encode(writeTarget, ob) 1186 | if err != nil { 1187 | return nil, err 1188 | } 1189 | return writeTarget.Bytes(), nil 1190 | } 1191 | 1192 | type MarshallValue interface { 1193 | // Convert the value to CBOR. Specific CBOR data (such as tags) can be written 1194 | // on the io.Writer and more complex datatype can be written using the 1195 | // Encoder. 1196 | // 1197 | // To Write a Tag value, a possible implementation would be: 1198 | // 1199 | // w.Write(cbor.EncodeTag(6, tag_value)) 1200 | // enc.Encode(tagged_value) 1201 | // 1202 | ToCBOR(w io.Writer, enc *Encoder) error 1203 | } 1204 | 1205 | type SimpleMarshallValue interface { 1206 | // Convert the value to CBOR. The object is responsible to convert to CBOR 1207 | // in the correct format. 1208 | ToCBOR(w io.Writer) error 1209 | } 1210 | 1211 | type CBORValue []byte 1212 | 1213 | func (v CBORValue) ToCBOR(w io.Writer) error { 1214 | _, err := w.Write(v) 1215 | return err 1216 | } 1217 | 1218 | // Return new Encoder object for writing to supplied io.Writer. 1219 | // 1220 | // TODO: set options on Encoder object. 1221 | func NewEncoder(out io.Writer) *Encoder { 1222 | return &Encoder{out, nil, make([]byte, 9)} 1223 | } 1224 | 1225 | func (enc *Encoder) SetFilter(filter func(v interface{}) interface{}) { 1226 | enc.filter = filter 1227 | } 1228 | 1229 | func (enc *Encoder) Encode(ob interface{}) error { 1230 | if enc.filter != nil { 1231 | ob = enc.filter(ob) 1232 | } 1233 | 1234 | if v, ok := ob.(MarshallValue); ok { 1235 | return v.ToCBOR(enc.out, enc) 1236 | } else if v, ok := ob.(SimpleMarshallValue); ok { 1237 | return v.ToCBOR(enc.out) 1238 | } 1239 | 1240 | switch x := ob.(type) { 1241 | case int: 1242 | return enc.writeInt(int64(x)) 1243 | case int8: 1244 | return enc.writeInt(int64(x)) 1245 | case int16: 1246 | return enc.writeInt(int64(x)) 1247 | case int32: 1248 | return enc.writeInt(int64(x)) 1249 | case int64: 1250 | return enc.writeInt(x) 1251 | case uint: 1252 | return enc.tagAuxOut(cborUint, uint64(x)) 1253 | case uint8: /* aka byte */ 1254 | return enc.tagAuxOut(cborUint, uint64(x)) 1255 | case uint16: 1256 | return enc.tagAuxOut(cborUint, uint64(x)) 1257 | case uint32: 1258 | return enc.tagAuxOut(cborUint, uint64(x)) 1259 | case uint64: 1260 | return enc.tagAuxOut(cborUint, x) 1261 | case float32: 1262 | return enc.writeFloat(float64(x)) 1263 | case float64: 1264 | return enc.writeFloat(x) 1265 | case string: 1266 | return enc.writeText(x) 1267 | case []byte: 1268 | return enc.writeBytes(x) 1269 | case bool: 1270 | return enc.writeBool(x) 1271 | case nil: 1272 | return enc.tagAuxOut(cbor7, uint64(cborNull)) 1273 | case big.Int: 1274 | return fmt.Errorf("TODO: encode big.Int") 1275 | } 1276 | 1277 | // If none of the simple types work, try reflection 1278 | return enc.writeReflection(reflect.ValueOf(ob)) 1279 | } 1280 | 1281 | func (enc *Encoder) writeReflection(rv reflect.Value) error { 1282 | if enc.filter != nil { 1283 | rv = reflect.ValueOf(enc.filter(rv.Interface())) 1284 | } 1285 | 1286 | if !rv.IsValid() { 1287 | return enc.tagAuxOut(cbor7, uint64(cborNull)) 1288 | } 1289 | 1290 | if v, ok := rv.Interface().(MarshallValue); ok { 1291 | return v.ToCBOR(enc.out, enc) 1292 | } else if v, ok := rv.Interface().(SimpleMarshallValue); ok { 1293 | return v.ToCBOR(enc.out) 1294 | } 1295 | 1296 | var err error 1297 | switch rv.Kind() { 1298 | case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 1299 | return enc.writeInt(rv.Int()) 1300 | case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 1301 | return enc.tagAuxOut(cborUint, rv.Uint()) 1302 | case reflect.Float32, reflect.Float64: 1303 | return enc.writeFloat(rv.Float()) 1304 | case reflect.Bool: 1305 | return enc.writeBool(rv.Bool()) 1306 | case reflect.String: 1307 | return enc.writeText(rv.String()) 1308 | case reflect.Slice, reflect.Array: 1309 | elemType := rv.Type().Elem() 1310 | if elemType.Kind() == reflect.Uint8 { 1311 | // special case, write out []byte 1312 | return enc.writeBytes(rv.Bytes()) 1313 | } 1314 | alen := rv.Len() 1315 | err = enc.tagAuxOut(cborArray, uint64(alen)) 1316 | for i := 0; i < alen; i++ { 1317 | err = enc.writeReflection(rv.Index(i)) 1318 | if err != nil { 1319 | log.Printf("error at array elem %d", i) 1320 | return err 1321 | } 1322 | } 1323 | return nil 1324 | case reflect.Map: 1325 | err = enc.tagAuxOut(cborMap, uint64(rv.Len())) 1326 | if err != nil { 1327 | return err 1328 | } 1329 | 1330 | dup := func(b []byte) []byte { 1331 | out := make([]byte, len(b)) 1332 | copy(out, b) 1333 | return out 1334 | } 1335 | 1336 | keys := rv.MapKeys() 1337 | buf := new(bytes.Buffer) 1338 | encKeys := make([]cborKeyEntry, 0, len(keys)) 1339 | for _, krv := range keys { 1340 | tempEnc := NewEncoder(buf) 1341 | err := tempEnc.writeReflection(krv) 1342 | if err != nil { 1343 | log.Println("error encoding map key", err) 1344 | return err 1345 | } 1346 | kval := dup(buf.Bytes()) 1347 | encKeys = append(encKeys, cborKeyEntry{ 1348 | val: kval, 1349 | key: krv, 1350 | }) 1351 | buf.Reset() 1352 | } 1353 | 1354 | sort.Sort(cborKeySorter(encKeys)) 1355 | 1356 | for _, ek := range encKeys { 1357 | vrv := rv.MapIndex(ek.key) 1358 | 1359 | _, err := enc.out.Write(ek.val) 1360 | if err != nil { 1361 | log.Printf("error writing map key") 1362 | return err 1363 | } 1364 | err = enc.writeReflection(vrv) 1365 | if err != nil { 1366 | log.Printf("error encoding map val") 1367 | return err 1368 | } 1369 | } 1370 | 1371 | return nil 1372 | case reflect.Struct: 1373 | // TODO: check for big.Int ? 1374 | numfields := rv.NumField() 1375 | structType := rv.Type() 1376 | usableFields := 0 1377 | for i := 0; i < numfields; i++ { 1378 | fieldinfo := structType.Field(i) 1379 | _, ok := fieldname(fieldinfo) 1380 | if !ok { 1381 | continue 1382 | } 1383 | usableFields++ 1384 | } 1385 | err = enc.tagAuxOut(cborMap, uint64(usableFields)) 1386 | if err != nil { 1387 | return err 1388 | } 1389 | for i := 0; i < numfields; i++ { 1390 | fieldinfo := structType.Field(i) 1391 | fieldname, ok := fieldname(fieldinfo) 1392 | if !ok { 1393 | continue 1394 | } 1395 | err = enc.writeText(fieldname) 1396 | if err != nil { 1397 | return err 1398 | } 1399 | err = enc.writeReflection(rv.Field(i)) 1400 | if err != nil { 1401 | return err 1402 | } 1403 | } 1404 | return nil 1405 | case reflect.Interface: 1406 | //return fmt.Errorf("TODO: serialize interface{} k=%s T=%s", rv.Kind().String(), rv.Type().String()) 1407 | return enc.Encode(rv.Interface()) 1408 | case reflect.Ptr: 1409 | if rv.IsNil() { 1410 | return enc.tagAuxOut(cbor7, uint64(cborNull)) 1411 | } 1412 | return enc.writeReflection(reflect.Indirect(rv)) 1413 | } 1414 | 1415 | return fmt.Errorf("don't know how to CBOR serialize k=%s t=%s", rv.Kind().String(), rv.Type().String()) 1416 | } 1417 | 1418 | type cborKeySorter []cborKeyEntry 1419 | type cborKeyEntry struct { 1420 | val []byte 1421 | key reflect.Value 1422 | } 1423 | 1424 | func (cks cborKeySorter) Len() int { return len(cks) } 1425 | func (cks cborKeySorter) Swap(i, j int) { 1426 | cks[i], cks[j] = cks[j], cks[i] 1427 | } 1428 | 1429 | func (cks cborKeySorter) Less(i, j int) bool { 1430 | a := keyBytesFromEncoded(cks[i].val) 1431 | b := keyBytesFromEncoded(cks[j].val) 1432 | switch { 1433 | case len(a) < len(b): 1434 | return true 1435 | case len(a) > len(b): 1436 | return false 1437 | default: 1438 | if bytes.Compare(a, b) < 0 { 1439 | return true 1440 | } 1441 | return false 1442 | } 1443 | } 1444 | 1445 | func keyBytesFromEncoded(data []byte) []byte { 1446 | cborInfo := data[0] & infoBits 1447 | 1448 | if cborInfo <= 23 { 1449 | return data[1:] 1450 | } else if cborInfo == int8Follows { 1451 | return data[2:] 1452 | } else if cborInfo == int16Follows { 1453 | return data[3:] 1454 | } else if cborInfo == int32Follows { 1455 | return data[5:] 1456 | } else if cborInfo == int64Follows { 1457 | return data[9:] 1458 | } 1459 | panic("shouldnt actually hit this") 1460 | } 1461 | 1462 | func (enc *Encoder) writeInt(x int64) error { 1463 | if x < 0 { 1464 | return enc.tagAuxOut(cborNegint, uint64(-1-x)) 1465 | } 1466 | return enc.tagAuxOut(cborUint, uint64(x)) 1467 | } 1468 | 1469 | func (enc *Encoder) tagAuxOut(tag byte, x uint64) error { 1470 | var err error 1471 | if x <= 23 { 1472 | // tiny literal 1473 | enc.scratch[0] = tag | byte(x) 1474 | _, err = enc.out.Write(enc.scratch[:1]) 1475 | } else if x < 0x0ff { 1476 | enc.scratch[0] = tag | int8Follows 1477 | enc.scratch[1] = byte(x & 0x0ff) 1478 | _, err = enc.out.Write(enc.scratch[:2]) 1479 | } else if x < 0x0ffff { 1480 | enc.scratch[0] = tag | int16Follows 1481 | enc.scratch[1] = byte((x >> 8) & 0x0ff) 1482 | enc.scratch[2] = byte(x & 0x0ff) 1483 | _, err = enc.out.Write(enc.scratch[:3]) 1484 | } else if x < 0x0ffffffff { 1485 | enc.scratch[0] = tag | int32Follows 1486 | enc.scratch[1] = byte((x >> 24) & 0x0ff) 1487 | enc.scratch[2] = byte((x >> 16) & 0x0ff) 1488 | enc.scratch[3] = byte((x >> 8) & 0x0ff) 1489 | enc.scratch[4] = byte(x & 0x0ff) 1490 | _, err = enc.out.Write(enc.scratch[:5]) 1491 | } else { 1492 | err = enc.tagAux64(tag, x) 1493 | } 1494 | return err 1495 | } 1496 | func (enc *Encoder) tagAux64(tag byte, x uint64) error { 1497 | enc.scratch[0] = tag | int64Follows 1498 | enc.scratch[1] = byte((x >> 56) & 0x0ff) 1499 | enc.scratch[2] = byte((x >> 48) & 0x0ff) 1500 | enc.scratch[3] = byte((x >> 40) & 0x0ff) 1501 | enc.scratch[4] = byte((x >> 32) & 0x0ff) 1502 | enc.scratch[5] = byte((x >> 24) & 0x0ff) 1503 | enc.scratch[6] = byte((x >> 16) & 0x0ff) 1504 | enc.scratch[7] = byte((x >> 8) & 0x0ff) 1505 | enc.scratch[8] = byte(x & 0x0ff) 1506 | _, err := enc.out.Write(enc.scratch[:9]) 1507 | return err 1508 | } 1509 | 1510 | // Encode a CBOR integer unit. The first argument is the major type, the second 1511 | // argument is the integer value. The result is a byte array from 1 to 9 bytes 1512 | // depending on the size of the integer value. 1513 | // 1514 | // The major type (tag argument) must be an integer between 0 and 7 else this 1515 | // function panics 1516 | // 1517 | // If the third parameter is non nil, the slice is reused to construct the 1518 | // result to avoid a memory allocation. It should be a slice with a sufficient 1519 | // capacity. 1520 | func EncodeInt(tag byte, v uint64, buf []byte) []byte { 1521 | switch { 1522 | case v <= 23: 1523 | // tiny literal 1524 | return EncodeOpcode(tag, byte(v), buf) 1525 | case 23 < v && v < 0x0ff: 1526 | return EncodeInt8(tag, uint8(v), buf) 1527 | case 0xff <= v && v < 0x0ffff: 1528 | return EncodeInt16(tag, uint16(v), buf) 1529 | case 0xffff <= v && v < 0x0ffffffff: 1530 | return EncodeInt32(tag, uint32(v), buf) 1531 | default: 1532 | return EncodeInt64(tag, v, buf) 1533 | } 1534 | } 1535 | 1536 | func EncodeOpcode(tag byte, opcode byte, buf []byte) []byte { 1537 | if tag > 7 { 1538 | panic("Wrong tag value") 1539 | } 1540 | return append(buf[0:0], 1541 | (tag<<5)|opcode, 1542 | ) 1543 | } 1544 | 1545 | func EncodeInt8(tag byte, v uint8, buf []byte) []byte { 1546 | if tag > 7 { 1547 | panic("Wrong tag value") 1548 | } 1549 | return append(buf[0:0], 1550 | (tag<<5)|int8Follows, 1551 | byte(v&0xff), 1552 | ) 1553 | } 1554 | 1555 | func EncodeInt16(tag byte, v uint16, buf []byte) []byte { 1556 | if tag > 7 { 1557 | panic("Wrong tag value") 1558 | } 1559 | return append(buf[0:0], 1560 | (tag<<5)|int16Follows, 1561 | byte((v>>8)&0xff), 1562 | byte(v&0xff), 1563 | ) 1564 | } 1565 | 1566 | func EncodeInt32(tag byte, v uint32, buf []byte) []byte { 1567 | if tag > 7 { 1568 | panic("Wrong tag value") 1569 | } 1570 | return append(buf[0:0], 1571 | (tag<<5)|int32Follows, 1572 | byte((v>>24)&0xff), 1573 | byte((v>>16)&0xff), 1574 | byte((v>>8)&0xff), 1575 | byte(v&0xff), 1576 | ) 1577 | } 1578 | 1579 | func EncodeInt64(tag byte, v uint64, buf []byte) []byte { 1580 | if tag > 7 { 1581 | panic("Wrong tag value") 1582 | } 1583 | return append(buf[0:0], 1584 | (tag<<5)|int64Follows, 1585 | byte((v>>56)&0xff), 1586 | byte((v>>48)&0xff), 1587 | byte((v>>40)&0xff), 1588 | byte((v>>32)&0xff), 1589 | byte((v>>24)&0xff), 1590 | byte((v>>16)&0xff), 1591 | byte((v>>8)&0xff), 1592 | byte(v&0xff), 1593 | ) 1594 | } 1595 | 1596 | func (enc *Encoder) writeText(x string) error { 1597 | enc.tagAuxOut(cborText, uint64(len(x))) 1598 | _, err := io.WriteString(enc.out, x) 1599 | return err 1600 | } 1601 | 1602 | func (enc *Encoder) writeBytes(x []byte) error { 1603 | enc.tagAuxOut(cborBytes, uint64(len(x))) 1604 | _, err := enc.out.Write(x) 1605 | return err 1606 | } 1607 | 1608 | func (enc *Encoder) writeFloat(x float64) error { 1609 | return enc.tagAux64(cbor7, math.Float64bits(x)) 1610 | } 1611 | 1612 | func (enc *Encoder) writeBool(x bool) error { 1613 | if x { 1614 | return enc.tagAuxOut(cbor7, uint64(cborTrue)) 1615 | } else { 1616 | return enc.tagAuxOut(cbor7, uint64(cborFalse)) 1617 | } 1618 | } 1619 | 1620 | func min(x, y uint64) uint64 { 1621 | if x < y { 1622 | return x 1623 | } 1624 | return y 1625 | } 1626 | --------------------------------------------------------------------------------