1// Copyright (c) 2012, 2013 Ugorji Nwoke. All rights reserved. 2// Use of this source code is governed by a BSD-style license found in the LICENSE file. 3 4package codec 5 6import "math" 7 8const ( 9 _ uint8 = iota 10 simpleVdNil = 1 11 simpleVdFalse = 2 12 simpleVdTrue = 3 13 simpleVdFloat32 = 4 14 simpleVdFloat64 = 5 15 16 // each lasts for 4 (ie n, n+1, n+2, n+3) 17 simpleVdPosInt = 8 18 simpleVdNegInt = 12 19 20 // containers: each lasts for 4 (ie n, n+1, n+2, ... n+7) 21 simpleVdString = 216 22 simpleVdByteArray = 224 23 simpleVdArray = 232 24 simpleVdMap = 240 25 simpleVdExt = 248 26) 27 28type simpleEncDriver struct { 29 h *SimpleHandle 30 w encWriter 31 //b [8]byte 32} 33 34func (e *simpleEncDriver) isBuiltinType(rt uintptr) bool { 35 return false 36} 37 38func (e *simpleEncDriver) encodeBuiltin(rt uintptr, v interface{}) { 39} 40 41func (e *simpleEncDriver) encodeNil() { 42 e.w.writen1(simpleVdNil) 43} 44 45func (e *simpleEncDriver) encodeBool(b bool) { 46 if b { 47 e.w.writen1(simpleVdTrue) 48 } else { 49 e.w.writen1(simpleVdFalse) 50 } 51} 52 53func (e *simpleEncDriver) encodeFloat32(f float32) { 54 e.w.writen1(simpleVdFloat32) 55 e.w.writeUint32(math.Float32bits(f)) 56} 57 58func (e *simpleEncDriver) encodeFloat64(f float64) { 59 e.w.writen1(simpleVdFloat64) 60 e.w.writeUint64(math.Float64bits(f)) 61} 62 63func (e *simpleEncDriver) encodeInt(v int64) { 64 if v < 0 { 65 e.encUint(uint64(-v), simpleVdNegInt) 66 } else { 67 e.encUint(uint64(v), simpleVdPosInt) 68 } 69} 70 71func (e *simpleEncDriver) encodeUint(v uint64) { 72 e.encUint(v, simpleVdPosInt) 73} 74 75func (e *simpleEncDriver) encUint(v uint64, bd uint8) { 76 switch { 77 case v <= math.MaxUint8: 78 e.w.writen2(bd, uint8(v)) 79 case v <= math.MaxUint16: 80 e.w.writen1(bd + 1) 81 e.w.writeUint16(uint16(v)) 82 case v <= math.MaxUint32: 83 e.w.writen1(bd + 2) 84 e.w.writeUint32(uint32(v)) 85 case v <= math.MaxUint64: 86 e.w.writen1(bd + 3) 87 e.w.writeUint64(v) 88 } 89} 90 91func (e *simpleEncDriver) encLen(bd byte, length int) { 92 switch { 93 case length == 0: 94 e.w.writen1(bd) 95 case length <= math.MaxUint8: 96 e.w.writen1(bd + 1) 97 e.w.writen1(uint8(length)) 98 case length <= math.MaxUint16: 99 e.w.writen1(bd + 2) 100 e.w.writeUint16(uint16(length)) 101 case int64(length) <= math.MaxUint32: 102 e.w.writen1(bd + 3) 103 e.w.writeUint32(uint32(length)) 104 default: 105 e.w.writen1(bd + 4) 106 e.w.writeUint64(uint64(length)) 107 } 108} 109 110func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) { 111 e.encLen(simpleVdExt, length) 112 e.w.writen1(xtag) 113} 114 115func (e *simpleEncDriver) encodeArrayPreamble(length int) { 116 e.encLen(simpleVdArray, length) 117} 118 119func (e *simpleEncDriver) encodeMapPreamble(length int) { 120 e.encLen(simpleVdMap, length) 121} 122 123func (e *simpleEncDriver) encodeString(c charEncoding, v string) { 124 e.encLen(simpleVdString, len(v)) 125 e.w.writestr(v) 126} 127 128func (e *simpleEncDriver) encodeSymbol(v string) { 129 e.encodeString(c_UTF8, v) 130} 131 132func (e *simpleEncDriver) encodeStringBytes(c charEncoding, v []byte) { 133 e.encLen(simpleVdByteArray, len(v)) 134 e.w.writeb(v) 135} 136 137//------------------------------------ 138 139type simpleDecDriver struct { 140 h *SimpleHandle 141 r decReader 142 bdRead bool 143 bdType valueType 144 bd byte 145 //b [8]byte 146} 147 148func (d *simpleDecDriver) initReadNext() { 149 if d.bdRead { 150 return 151 } 152 d.bd = d.r.readn1() 153 d.bdRead = true 154 d.bdType = valueTypeUnset 155} 156 157func (d *simpleDecDriver) currentEncodedType() valueType { 158 if d.bdType == valueTypeUnset { 159 switch d.bd { 160 case simpleVdNil: 161 d.bdType = valueTypeNil 162 case simpleVdTrue, simpleVdFalse: 163 d.bdType = valueTypeBool 164 case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3: 165 d.bdType = valueTypeUint 166 case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3: 167 d.bdType = valueTypeInt 168 case simpleVdFloat32, simpleVdFloat64: 169 d.bdType = valueTypeFloat 170 case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: 171 d.bdType = valueTypeString 172 case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 173 d.bdType = valueTypeBytes 174 case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: 175 d.bdType = valueTypeExt 176 case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4: 177 d.bdType = valueTypeArray 178 case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: 179 d.bdType = valueTypeMap 180 default: 181 decErr("currentEncodedType: Unrecognized d.vd: 0x%x", d.bd) 182 } 183 } 184 return d.bdType 185} 186 187func (d *simpleDecDriver) tryDecodeAsNil() bool { 188 if d.bd == simpleVdNil { 189 d.bdRead = false 190 return true 191 } 192 return false 193} 194 195func (d *simpleDecDriver) isBuiltinType(rt uintptr) bool { 196 return false 197} 198 199func (d *simpleDecDriver) decodeBuiltin(rt uintptr, v interface{}) { 200} 201 202func (d *simpleDecDriver) decIntAny() (ui uint64, i int64, neg bool) { 203 switch d.bd { 204 case simpleVdPosInt: 205 ui = uint64(d.r.readn1()) 206 i = int64(ui) 207 case simpleVdPosInt + 1: 208 ui = uint64(d.r.readUint16()) 209 i = int64(ui) 210 case simpleVdPosInt + 2: 211 ui = uint64(d.r.readUint32()) 212 i = int64(ui) 213 case simpleVdPosInt + 3: 214 ui = uint64(d.r.readUint64()) 215 i = int64(ui) 216 case simpleVdNegInt: 217 ui = uint64(d.r.readn1()) 218 i = -(int64(ui)) 219 neg = true 220 case simpleVdNegInt + 1: 221 ui = uint64(d.r.readUint16()) 222 i = -(int64(ui)) 223 neg = true 224 case simpleVdNegInt + 2: 225 ui = uint64(d.r.readUint32()) 226 i = -(int64(ui)) 227 neg = true 228 case simpleVdNegInt + 3: 229 ui = uint64(d.r.readUint64()) 230 i = -(int64(ui)) 231 neg = true 232 default: 233 decErr("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd) 234 } 235 // don't do this check, because callers may only want the unsigned value. 236 // if ui > math.MaxInt64 { 237 // decErr("decIntAny: Integer out of range for signed int64: %v", ui) 238 // } 239 return 240} 241 242func (d *simpleDecDriver) decodeInt(bitsize uint8) (i int64) { 243 _, i, _ = d.decIntAny() 244 checkOverflow(0, i, bitsize) 245 d.bdRead = false 246 return 247} 248 249func (d *simpleDecDriver) decodeUint(bitsize uint8) (ui uint64) { 250 ui, i, neg := d.decIntAny() 251 if neg { 252 decErr("Assigning negative signed value: %v, to unsigned type", i) 253 } 254 checkOverflow(ui, 0, bitsize) 255 d.bdRead = false 256 return 257} 258 259func (d *simpleDecDriver) decodeFloat(chkOverflow32 bool) (f float64) { 260 switch d.bd { 261 case simpleVdFloat32: 262 f = float64(math.Float32frombits(d.r.readUint32())) 263 case simpleVdFloat64: 264 f = math.Float64frombits(d.r.readUint64()) 265 default: 266 if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 { 267 _, i, _ := d.decIntAny() 268 f = float64(i) 269 } else { 270 decErr("Float only valid from float32/64: Invalid descriptor: %v", d.bd) 271 } 272 } 273 checkOverflowFloat32(f, chkOverflow32) 274 d.bdRead = false 275 return 276} 277 278// bool can be decoded from bool only (single byte). 279func (d *simpleDecDriver) decodeBool() (b bool) { 280 switch d.bd { 281 case simpleVdTrue: 282 b = true 283 case simpleVdFalse: 284 default: 285 decErr("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd) 286 } 287 d.bdRead = false 288 return 289} 290 291func (d *simpleDecDriver) readMapLen() (length int) { 292 d.bdRead = false 293 return d.decLen() 294} 295 296func (d *simpleDecDriver) readArrayLen() (length int) { 297 d.bdRead = false 298 return d.decLen() 299} 300 301func (d *simpleDecDriver) decLen() int { 302 switch d.bd % 8 { 303 case 0: 304 return 0 305 case 1: 306 return int(d.r.readn1()) 307 case 2: 308 return int(d.r.readUint16()) 309 case 3: 310 ui := uint64(d.r.readUint32()) 311 checkOverflow(ui, 0, intBitsize) 312 return int(ui) 313 case 4: 314 ui := d.r.readUint64() 315 checkOverflow(ui, 0, intBitsize) 316 return int(ui) 317 } 318 decErr("decLen: Cannot read length: bd%8 must be in range 0..4. Got: %d", d.bd%8) 319 return -1 320} 321 322func (d *simpleDecDriver) decodeString() (s string) { 323 s = string(d.r.readn(d.decLen())) 324 d.bdRead = false 325 return 326} 327 328func (d *simpleDecDriver) decodeBytes(bs []byte) (bsOut []byte, changed bool) { 329 if clen := d.decLen(); clen > 0 { 330 // if no contents in stream, don't update the passed byteslice 331 if len(bs) != clen { 332 if len(bs) > clen { 333 bs = bs[:clen] 334 } else { 335 bs = make([]byte, clen) 336 } 337 bsOut = bs 338 changed = true 339 } 340 d.r.readb(bs) 341 } 342 d.bdRead = false 343 return 344} 345 346func (d *simpleDecDriver) decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte) { 347 switch d.bd { 348 case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: 349 l := d.decLen() 350 xtag = d.r.readn1() 351 if verifyTag && xtag != tag { 352 decErr("Wrong extension tag. Got %b. Expecting: %v", xtag, tag) 353 } 354 xbs = d.r.readn(l) 355 case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 356 xbs, _ = d.decodeBytes(nil) 357 default: 358 decErr("Invalid d.vd for extensions (Expecting extensions or byte array). Got: 0x%x", d.bd) 359 } 360 d.bdRead = false 361 return 362} 363 364func (d *simpleDecDriver) decodeNaked() (v interface{}, vt valueType, decodeFurther bool) { 365 d.initReadNext() 366 367 switch d.bd { 368 case simpleVdNil: 369 vt = valueTypeNil 370 case simpleVdFalse: 371 vt = valueTypeBool 372 v = false 373 case simpleVdTrue: 374 vt = valueTypeBool 375 v = true 376 case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3: 377 vt = valueTypeUint 378 ui, _, _ := d.decIntAny() 379 v = ui 380 case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3: 381 vt = valueTypeInt 382 _, i, _ := d.decIntAny() 383 v = i 384 case simpleVdFloat32: 385 vt = valueTypeFloat 386 v = d.decodeFloat(true) 387 case simpleVdFloat64: 388 vt = valueTypeFloat 389 v = d.decodeFloat(false) 390 case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: 391 vt = valueTypeString 392 v = d.decodeString() 393 case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: 394 vt = valueTypeBytes 395 v, _ = d.decodeBytes(nil) 396 case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: 397 vt = valueTypeExt 398 l := d.decLen() 399 var re RawExt 400 re.Tag = d.r.readn1() 401 re.Data = d.r.readn(l) 402 v = &re 403 vt = valueTypeExt 404 case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4: 405 vt = valueTypeArray 406 decodeFurther = true 407 case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: 408 vt = valueTypeMap 409 decodeFurther = true 410 default: 411 decErr("decodeNaked: Unrecognized d.vd: 0x%x", d.bd) 412 } 413 414 if !decodeFurther { 415 d.bdRead = false 416 } 417 return 418} 419 420//------------------------------------ 421 422// SimpleHandle is a Handle for a very simple encoding format. 423// 424// simple is a simplistic codec similar to binc, but not as compact. 425// - Encoding of a value is always preceeded by the descriptor byte (bd) 426// - True, false, nil are encoded fully in 1 byte (the descriptor) 427// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte). 428// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers. 429// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte) 430// - Lenght of containers (strings, bytes, array, map, extensions) 431// are encoded in 0, 1, 2, 4 or 8 bytes. 432// Zero-length containers have no length encoded. 433// For others, the number of bytes is given by pow(2, bd%3) 434// - maps are encoded as [bd] [length] [[key][value]]... 435// - arrays are encoded as [bd] [length] [value]... 436// - extensions are encoded as [bd] [length] [tag] [byte]... 437// - strings/bytearrays are encoded as [bd] [length] [byte]... 438// 439// The full spec will be published soon. 440type SimpleHandle struct { 441 BasicHandle 442} 443 444func (h *SimpleHandle) newEncDriver(w encWriter) encDriver { 445 return &simpleEncDriver{w: w, h: h} 446} 447 448func (h *SimpleHandle) newDecDriver(r decReader) decDriver { 449 return &simpleDecDriver{r: r, h: h} 450} 451 452func (_ *SimpleHandle) writeExt() bool { 453 return true 454} 455 456func (h *SimpleHandle) getBasicHandle() *BasicHandle { 457 return &h.BasicHandle 458} 459 460var _ decDriver = (*simpleDecDriver)(nil) 461var _ encDriver = (*simpleEncDriver)(nil) 462