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.

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