decgen.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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. // +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 := make([]byte, n)
  108. if _, err := state.b.Read(data); err != nil {
  109. errorf("error decoding string: %s", err)
  110. }
  111. slice[i] = string(data)`,
  112. },
  113. {
  114. "uint",
  115. "Uint",
  116. `x := state.decodeUint()
  117. /*TODO if math.MaxUint32 < x {
  118. error_(ovfl)
  119. }*/
  120. slice[i] = uint(x)`,
  121. },
  122. {
  123. "uint16",
  124. "Uint16",
  125. `x := state.decodeUint()
  126. if math.MaxUint16 < x {
  127. error_(ovfl)
  128. }
  129. slice[i] = uint16(x)`,
  130. },
  131. {
  132. "uint32",
  133. "Uint32",
  134. `x := state.decodeUint()
  135. if math.MaxUint32 < x {
  136. error_(ovfl)
  137. }
  138. slice[i] = uint32(x)`,
  139. },
  140. {
  141. "uint64",
  142. "Uint64",
  143. `slice[i] = state.decodeUint()`,
  144. },
  145. {
  146. "uintptr",
  147. "Uintptr",
  148. `x := state.decodeUint()
  149. if uint64(^uintptr(0)) < x {
  150. error_(ovfl)
  151. }
  152. slice[i] = uintptr(x)`,
  153. },
  154. // uint8 Handled separately.
  155. }
  156. func main() {
  157. log.SetFlags(0)
  158. log.SetPrefix("decgen: ")
  159. flag.Parse()
  160. if flag.NArg() != 0 {
  161. log.Fatal("usage: decgen [--output filename]")
  162. }
  163. var b bytes.Buffer
  164. fmt.Fprintf(&b, "// Created by decgen --output %s; DO NOT EDIT\n", *output)
  165. fmt.Fprint(&b, header)
  166. printMaps(&b, "Array")
  167. fmt.Fprint(&b, "\n")
  168. printMaps(&b, "Slice")
  169. for _, t := range types {
  170. fmt.Fprintf(&b, arrayHelper, t.lower, t.upper)
  171. fmt.Fprintf(&b, sliceHelper, t.lower, t.upper, t.decoder)
  172. }
  173. source, err := format.Source(b.Bytes())
  174. if err != nil {
  175. log.Fatal("source format error:", err)
  176. }
  177. fd, err := os.Create(*output)
  178. _, err = fd.Write(source)
  179. if err != nil {
  180. log.Fatal(err)
  181. }
  182. }
  183. func printMaps(b *bytes.Buffer, upperClass string) {
  184. fmt.Fprintf(b, "var dec%sHelper = map[reflect.Kind]decHelper{\n", upperClass)
  185. for _, t := range types {
  186. fmt.Fprintf(b, "reflect.%s: dec%s%s,\n", t.upper, t.upper, upperClass)
  187. }
  188. fmt.Fprintf(b, "}\n")
  189. }
  190. const header = `
  191. // Copyright 2014 The Go Authors. All rights reserved.
  192. // Use of this source code is governed by a BSD-style
  193. // license that can be found in the LICENSE file.
  194. package gob
  195. import (
  196. "math"
  197. "reflect"
  198. )
  199. `
  200. const arrayHelper = `
  201. func dec%[2]sArray(state *decoderState, v reflect.Value, length int, ovfl error) bool {
  202. // Can only slice if it is addressable.
  203. if !v.CanAddr() {
  204. return false
  205. }
  206. return dec%[2]sSlice(state, v.Slice(0, v.Len()), length, ovfl)
  207. }
  208. `
  209. const sliceHelper = `
  210. func dec%[2]sSlice(state *decoderState, v reflect.Value, length int, ovfl error) bool {
  211. slice, ok := v.Interface().([]%[1]s)
  212. if !ok {
  213. // It is kind %[1]s but not type %[1]s. TODO: We can handle this unsafely.
  214. return false
  215. }
  216. for i := 0; i < length; i++ {
  217. if state.b.Len() == 0 {
  218. errorf("decoding %[1]s array or slice: length exceeds input size (%%d elements)", length)
  219. }
  220. %[3]s
  221. }
  222. return true
  223. }
  224. `