decgen.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:build ignore
  5. // encgen writes the helper functions for encoding. Intended to be
  6. // used with go generate; see the invocation in encode.go.
  7. // TODO: We could do more by being unsafe. Add a -unsafe flag?
  8. package main
  9. import (
  10. "bytes"
  11. "flag"
  12. "fmt"
  13. "go/format"
  14. "log"
  15. "os"
  16. )
  17. var output = flag.String("output", "dec_helpers.go", "file name to write")
  18. type Type struct {
  19. lower string
  20. upper string
  21. decoder string
  22. }
  23. var types = []Type{
  24. {
  25. "bool",
  26. "Bool",
  27. `slice[i] = state.decodeUint() != 0`,
  28. },
  29. {
  30. "complex64",
  31. "Complex64",
  32. `real := float32FromBits(state.decodeUint(), ovfl)
  33. imag := float32FromBits(state.decodeUint(), ovfl)
  34. slice[i] = complex(float32(real), float32(imag))`,
  35. },
  36. {
  37. "complex128",
  38. "Complex128",
  39. `real := float64FromBits(state.decodeUint())
  40. imag := float64FromBits(state.decodeUint())
  41. slice[i] = complex(real, imag)`,
  42. },
  43. {
  44. "float32",
  45. "Float32",
  46. `slice[i] = float32(float32FromBits(state.decodeUint(), ovfl))`,
  47. },
  48. {
  49. "float64",
  50. "Float64",
  51. `slice[i] = float64FromBits(state.decodeUint())`,
  52. },
  53. {
  54. "int",
  55. "Int",
  56. `x := state.decodeInt()
  57. // MinInt and MaxInt
  58. if x < ^int64(^uint(0)>>1) || int64(^uint(0)>>1) < x {
  59. error_(ovfl)
  60. }
  61. slice[i] = int(x)`,
  62. },
  63. {
  64. "int16",
  65. "Int16",
  66. `x := state.decodeInt()
  67. if x < math.MinInt16 || math.MaxInt16 < x {
  68. error_(ovfl)
  69. }
  70. slice[i] = int16(x)`,
  71. },
  72. {
  73. "int32",
  74. "Int32",
  75. `x := state.decodeInt()
  76. if x < math.MinInt32 || math.MaxInt32 < x {
  77. error_(ovfl)
  78. }
  79. slice[i] = int32(x)`,
  80. },
  81. {
  82. "int64",
  83. "Int64",
  84. `slice[i] = state.decodeInt()`,
  85. },
  86. {
  87. "int8",
  88. "Int8",
  89. `x := state.decodeInt()
  90. if x < math.MinInt8 || math.MaxInt8 < x {
  91. error_(ovfl)
  92. }
  93. slice[i] = int8(x)`,
  94. },
  95. {
  96. "string",
  97. "String",
  98. `u := state.decodeUint()
  99. n := int(u)
  100. if n < 0 || uint64(n) != u || n > state.b.Len() {
  101. errorf("length of string exceeds input size (%d bytes)", u)
  102. }
  103. if n > state.b.Len() {
  104. errorf("string data too long for buffer: %d", n)
  105. }
  106. // Read the data.
  107. data := state.b.Bytes()
  108. if len(data) < n {
  109. errorf("invalid string length %d: exceeds input size %d", n, len(data))
  110. }
  111. slice[i] = string(data[:n])
  112. state.b.Drop(n)`,
  113. },
  114. {
  115. "uint",
  116. "Uint",
  117. `x := state.decodeUint()
  118. /*TODO if math.MaxUint32 < x {
  119. error_(ovfl)
  120. }*/
  121. slice[i] = uint(x)`,
  122. },
  123. {
  124. "uint16",
  125. "Uint16",
  126. `x := state.decodeUint()
  127. if math.MaxUint16 < x {
  128. error_(ovfl)
  129. }
  130. slice[i] = uint16(x)`,
  131. },
  132. {
  133. "uint32",
  134. "Uint32",
  135. `x := state.decodeUint()
  136. if math.MaxUint32 < x {
  137. error_(ovfl)
  138. }
  139. slice[i] = uint32(x)`,
  140. },
  141. {
  142. "uint64",
  143. "Uint64",
  144. `slice[i] = state.decodeUint()`,
  145. },
  146. {
  147. "uintptr",
  148. "Uintptr",
  149. `x := state.decodeUint()
  150. if uint64(^uintptr(0)) < x {
  151. error_(ovfl)
  152. }
  153. slice[i] = uintptr(x)`,
  154. },
  155. // uint8 Handled separately.
  156. }
  157. func main() {
  158. log.SetFlags(0)
  159. log.SetPrefix("decgen: ")
  160. flag.Parse()
  161. if flag.NArg() != 0 {
  162. log.Fatal("usage: decgen [--output filename]")
  163. }
  164. var b bytes.Buffer
  165. fmt.Fprintf(&b, "// Code generated by go run decgen.go -output %s; DO NOT EDIT.\n", *output)
  166. fmt.Fprint(&b, header)
  167. printMaps(&b, "Array")
  168. fmt.Fprint(&b, "\n")
  169. printMaps(&b, "Slice")
  170. for _, t := range types {
  171. fmt.Fprintf(&b, arrayHelper, t.lower, t.upper)
  172. fmt.Fprintf(&b, sliceHelper, t.lower, t.upper, t.decoder)
  173. }
  174. source, err := format.Source(b.Bytes())
  175. if err != nil {
  176. log.Fatal("source format error:", err)
  177. }
  178. fd, err := os.Create(*output)
  179. if err != nil {
  180. log.Fatal(err)
  181. }
  182. if _, err := fd.Write(source); err != nil {
  183. log.Fatal(err)
  184. }
  185. }
  186. func printMaps(b *bytes.Buffer, upperClass string) {
  187. fmt.Fprintf(b, "var dec%sHelper = map[reflect.Kind]decHelper{\n", upperClass)
  188. for _, t := range types {
  189. fmt.Fprintf(b, "reflect.%s: dec%s%s,\n", t.upper, t.upper, upperClass)
  190. }
  191. fmt.Fprintf(b, "}\n")
  192. }
  193. const header = `
  194. // Copyright 2014 The Go Authors. All rights reserved.
  195. // Use of this source code is governed by a BSD-style
  196. // license that can be found in the LICENSE file.
  197. package gob
  198. import (
  199. "math"
  200. "reflect"
  201. )
  202. `
  203. const arrayHelper = `
  204. func dec%[2]sArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
  205. // Can only slice if it is addressable.
  206. if !v.CanAddr() {
  207. return false
  208. }
  209. return dec%[2]sSlice(state, v.Slice(0, v.Len()), length, ovfl)
  210. }
  211. `
  212. const sliceHelper = `
  213. func dec%[2]sSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
  214. slice, ok := v.Interface().([]%[1]s)
  215. if !ok {
  216. // It is kind %[1]s but not type %[1]s. TODO: We can handle this unsafely.
  217. return false
  218. }
  219. for i := 0; i < length; i++ {
  220. if state.b.Len() == 0 {
  221. errorf("decoding %[1]s array or slice: length exceeds input size (%%d elements)", length)
  222. }
  223. %[3]s
  224. }
  225. return true
  226. }
  227. `