You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.3 KiB

10 years ago
11 years ago
11 years ago
  1. package binary
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "io"
  6. "reflect"
  7. . "github.com/tendermint/tendermint/common"
  8. )
  9. // TODO document and maybe make it configurable.
  10. const MaxBinaryReadSize = 21 * 1024 * 1024
  11. var ErrBinaryReadSizeOverflow = errors.New("Error: binary read size overflow")
  12. var ErrBinaryReadSizeUnderflow = errors.New("Error: binary read size underflow")
  13. func ReadBinary(o interface{}, r io.Reader, n *int64, err *error) interface{} {
  14. rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
  15. if rv.Kind() == reflect.Ptr {
  16. if rv.IsNil() {
  17. // This allows ReadBinaryObject() to return a nil pointer,
  18. // if the value read is nil.
  19. rvPtr := reflect.New(rt)
  20. ReadBinaryPtr(rvPtr.Interface(), r, n, err)
  21. return rvPtr.Elem().Interface()
  22. } else {
  23. readReflectBinary(rv, rt, Options{}, r, n, err)
  24. return o
  25. }
  26. } else {
  27. ptrRv := reflect.New(rt)
  28. readReflectBinary(ptrRv.Elem(), rt, Options{}, r, n, err)
  29. return ptrRv.Elem().Interface()
  30. }
  31. }
  32. func ReadBinaryPtr(o interface{}, r io.Reader, n *int64, err *error) interface{} {
  33. rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
  34. if rv.Kind() == reflect.Ptr {
  35. readReflectBinary(rv.Elem(), rt.Elem(), Options{}, r, n, err)
  36. } else {
  37. PanicSanity("ReadBinaryPtr expects o to be a pointer")
  38. }
  39. return o
  40. }
  41. func WriteBinary(o interface{}, w io.Writer, n *int64, err *error) {
  42. rv := reflect.ValueOf(o)
  43. rt := reflect.TypeOf(o)
  44. writeReflectBinary(rv, rt, Options{}, w, n, err)
  45. }
  46. func ReadJSON(o interface{}, bytes []byte, err *error) interface{} {
  47. var object interface{}
  48. *err = json.Unmarshal(bytes, &object)
  49. if *err != nil {
  50. return o
  51. }
  52. return ReadJSONObject(o, object, err)
  53. }
  54. func ReadJSONPtr(o interface{}, bytes []byte, err *error) interface{} {
  55. var object interface{}
  56. *err = json.Unmarshal(bytes, &object)
  57. if *err != nil {
  58. return o
  59. }
  60. return ReadJSONObjectPtr(o, object, err)
  61. }
  62. func ReadJSONObject(o interface{}, object interface{}, err *error) interface{} {
  63. rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
  64. if rv.Kind() == reflect.Ptr {
  65. if rv.IsNil() {
  66. // This allows ReadJSONObject() to return a nil pointer
  67. // if the value read is nil.
  68. rvPtr := reflect.New(rt)
  69. ReadJSONObjectPtr(rvPtr.Interface(), object, err)
  70. return rvPtr.Elem().Interface()
  71. } else {
  72. readReflectJSON(rv, rt, object, err)
  73. return o
  74. }
  75. } else {
  76. ptrRv := reflect.New(rt)
  77. readReflectJSON(ptrRv.Elem(), rt, object, err)
  78. return ptrRv.Elem().Interface()
  79. }
  80. }
  81. func ReadJSONObjectPtr(o interface{}, object interface{}, err *error) interface{} {
  82. rv, rt := reflect.ValueOf(o), reflect.TypeOf(o)
  83. if rv.Kind() == reflect.Ptr {
  84. readReflectJSON(rv.Elem(), rt.Elem(), object, err)
  85. } else {
  86. PanicSanity("ReadJSON(Object)Ptr expects o to be a pointer")
  87. }
  88. return o
  89. }
  90. func WriteJSON(o interface{}, w io.Writer, n *int64, err *error) {
  91. rv := reflect.ValueOf(o)
  92. rt := reflect.TypeOf(o)
  93. if rv.Kind() == reflect.Ptr {
  94. rv, rt = rv.Elem(), rt.Elem()
  95. }
  96. writeReflectJSON(rv, rt, w, n, err)
  97. }
  98. // Write all of bz to w
  99. // Increment n and set err accordingly.
  100. func WriteTo(bz []byte, w io.Writer, n *int64, err *error) {
  101. if *err != nil {
  102. return
  103. }
  104. n_, err_ := w.Write(bz)
  105. *n += int64(n_)
  106. *err = err_
  107. }
  108. // Read len(buf) from r
  109. // Increment n and set err accordingly.
  110. func ReadFull(buf []byte, r io.Reader, n *int64, err *error) {
  111. if *err != nil {
  112. return
  113. }
  114. n_, err_ := io.ReadFull(r, buf)
  115. *n += int64(n_)
  116. *err = err_
  117. }