noop.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license found in the LICENSE file.
  3. package codec
  4. import (
  5. "math/rand"
  6. "time"
  7. )
  8. // NoopHandle returns a no-op handle. It basically does nothing.
  9. // It is only useful for benchmarking, as it gives an idea of the
  10. // overhead from the codec framework.
  11. // LIBRARY USERS: *** DO NOT USE ***
  12. func NoopHandle(slen int) *noopHandle {
  13. h := noopHandle{}
  14. h.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
  15. h.B = make([][]byte, slen)
  16. h.S = make([]string, slen)
  17. for i := 0; i < len(h.S); i++ {
  18. b := make([]byte, i+1)
  19. for j := 0; j < len(b); j++ {
  20. b[j] = 'a' + byte(i)
  21. }
  22. h.B[i] = b
  23. h.S[i] = string(b)
  24. }
  25. return &h
  26. }
  27. // noopHandle does nothing.
  28. // It is used to simulate the overhead of the codec framework.
  29. type noopHandle struct {
  30. BasicHandle
  31. binaryEncodingType
  32. noopDrv // noopDrv is unexported here, so we can get a copy of it when needed.
  33. }
  34. type noopDrv struct {
  35. i int
  36. S []string
  37. B [][]byte
  38. mk bool // are we about to read a map key?
  39. ct valueType // last request for IsContainerType.
  40. cb bool // last response for IsContainerType.
  41. rand *rand.Rand
  42. }
  43. func (h *noopDrv) r(v int) int { return h.rand.Intn(v) }
  44. func (h *noopDrv) m(v int) int { h.i++; return h.i % v }
  45. func (h *noopDrv) newEncDriver(_ *Encoder) encDriver { return h }
  46. func (h *noopDrv) newDecDriver(_ *Decoder) decDriver { return h }
  47. // --- encDriver
  48. func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {}
  49. func (h *noopDrv) EncodeNil() {}
  50. func (h *noopDrv) EncodeInt(i int64) {}
  51. func (h *noopDrv) EncodeUint(i uint64) {}
  52. func (h *noopDrv) EncodeBool(b bool) {}
  53. func (h *noopDrv) EncodeFloat32(f float32) {}
  54. func (h *noopDrv) EncodeFloat64(f float64) {}
  55. func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder) {}
  56. func (h *noopDrv) EncodeArrayStart(length int) {}
  57. func (h *noopDrv) EncodeArrayEnd() {}
  58. func (h *noopDrv) EncodeArrayEntrySeparator() {}
  59. func (h *noopDrv) EncodeMapStart(length int) {}
  60. func (h *noopDrv) EncodeMapEnd() {}
  61. func (h *noopDrv) EncodeMapEntrySeparator() {}
  62. func (h *noopDrv) EncodeMapKVSeparator() {}
  63. func (h *noopDrv) EncodeString(c charEncoding, v string) {}
  64. func (h *noopDrv) EncodeSymbol(v string) {}
  65. func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
  66. func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
  67. // ---- decDriver
  68. func (h *noopDrv) initReadNext() {}
  69. func (h *noopDrv) CheckBreak() bool { return false }
  70. func (h *noopDrv) IsBuiltinType(rt uintptr) bool { return false }
  71. func (h *noopDrv) DecodeBuiltin(rt uintptr, v interface{}) {}
  72. func (h *noopDrv) DecodeInt(bitsize uint8) (i int64) { return int64(h.m(15)) }
  73. func (h *noopDrv) DecodeUint(bitsize uint8) (ui uint64) { return uint64(h.m(35)) }
  74. func (h *noopDrv) DecodeFloat(chkOverflow32 bool) (f float64) { return float64(h.m(95)) }
  75. func (h *noopDrv) DecodeBool() (b bool) { return h.m(2) == 0 }
  76. func (h *noopDrv) DecodeString() (s string) { return h.S[h.m(8)] }
  77. // func (h *noopDrv) DecodeStringAsBytes(bs []byte) []byte { return h.DecodeBytes(bs) }
  78. func (h *noopDrv) DecodeBytes(bs []byte, isstring, zerocopy bool) []byte { return h.B[h.m(len(h.B))] }
  79. func (h *noopDrv) ReadMapEnd() { h.mk = false }
  80. func (h *noopDrv) ReadArrayEnd() {}
  81. func (h *noopDrv) ReadArrayEntrySeparator() {}
  82. func (h *noopDrv) ReadMapEntrySeparator() { h.mk = true }
  83. func (h *noopDrv) ReadMapKVSeparator() { h.mk = false }
  84. // toggle map/slice
  85. func (h *noopDrv) ReadMapStart() int { h.mk = true; return h.m(10) }
  86. func (h *noopDrv) ReadArrayStart() int { return h.m(10) }
  87. func (h *noopDrv) IsContainerType(vt valueType) bool {
  88. // return h.m(2) == 0
  89. // handle kStruct
  90. if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap {
  91. h.cb = !h.cb
  92. h.ct = vt
  93. return h.cb
  94. }
  95. // go in a loop and check it.
  96. h.ct = vt
  97. h.cb = h.m(7) == 0
  98. return h.cb
  99. }
  100. func (h *noopDrv) TryDecodeAsNil() bool {
  101. if h.mk {
  102. return false
  103. } else {
  104. return h.m(8) == 0
  105. }
  106. }
  107. func (h *noopDrv) DecodeExt(rv interface{}, xtag uint64, ext Ext) uint64 {
  108. return 0
  109. }
  110. func (h *noopDrv) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) {
  111. // use h.r (random) not h.m() because h.m() could cause the same value to be given.
  112. var sk int
  113. if h.mk {
  114. // if mapkey, do not support values of nil OR bytes, array, map or rawext
  115. sk = h.r(7) + 1
  116. } else {
  117. sk = h.r(12)
  118. }
  119. switch sk {
  120. case 0:
  121. vt = valueTypeNil
  122. case 1:
  123. vt, v = valueTypeBool, false
  124. case 2:
  125. vt, v = valueTypeBool, true
  126. case 3:
  127. vt, v = valueTypeInt, h.DecodeInt(64)
  128. case 4:
  129. vt, v = valueTypeUint, h.DecodeUint(64)
  130. case 5:
  131. vt, v = valueTypeFloat, h.DecodeFloat(true)
  132. case 6:
  133. vt, v = valueTypeFloat, h.DecodeFloat(false)
  134. case 7:
  135. vt, v = valueTypeString, h.DecodeString()
  136. case 8:
  137. vt, v = valueTypeBytes, h.B[h.m(len(h.B))]
  138. case 9:
  139. vt, decodeFurther = valueTypeArray, true
  140. case 10:
  141. vt, decodeFurther = valueTypeMap, true
  142. default:
  143. vt, v = valueTypeExt, &RawExt{Tag: h.DecodeUint(64), Data: h.B[h.m(len(h.B))]}
  144. }
  145. h.ct = vt
  146. return
  147. }