decode_gogo.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
  2. // http://github.com/gogo/protobuf/gogoproto
  3. //
  4. // Redistribution and use in source and binary forms, with or without
  5. // modification, are permitted provided that the following conditions are
  6. // met:
  7. //
  8. // * Redistributions of source code must retain the above copyright
  9. // notice, this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above
  11. // copyright notice, this list of conditions and the following disclaimer
  12. // in the documentation and/or other materials provided with the
  13. // distribution.
  14. //
  15. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  16. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  17. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  18. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  19. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  20. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  21. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  22. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  23. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  25. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. package proto
  27. import (
  28. "reflect"
  29. )
  30. // Decode a reference to a struct pointer.
  31. func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
  32. raw, e := o.DecodeRawBytes(false)
  33. if e != nil {
  34. return e
  35. }
  36. // If the object can unmarshal itself, let it.
  37. if p.isUnmarshaler {
  38. panic("not supported, since this is a pointer receiver")
  39. }
  40. obuf := o.buf
  41. oi := o.index
  42. o.buf = raw
  43. o.index = 0
  44. bas := structPointer_FieldPointer(base, p.field)
  45. err = o.unmarshalType(p.stype, p.sprop, false, bas)
  46. o.buf = obuf
  47. o.index = oi
  48. return err
  49. }
  50. // Decode a slice of references to struct pointers ([]struct).
  51. func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error {
  52. newBas := appendStructPointer(base, p.field, p.sstype)
  53. if is_group {
  54. panic("not supported, maybe in future, if requested.")
  55. }
  56. raw, err := o.DecodeRawBytes(false)
  57. if err != nil {
  58. return err
  59. }
  60. // If the object can unmarshal itself, let it.
  61. if p.isUnmarshaler {
  62. panic("not supported, since this is not a pointer receiver.")
  63. }
  64. obuf := o.buf
  65. oi := o.index
  66. o.buf = raw
  67. o.index = 0
  68. err = o.unmarshalType(p.stype, p.sprop, is_group, newBas)
  69. o.buf = obuf
  70. o.index = oi
  71. return err
  72. }
  73. // Decode a slice of references to struct pointers.
  74. func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error {
  75. return o.dec_slice_ref_struct(p, false, base)
  76. }
  77. func setPtrCustomType(base structPointer, f field, v interface{}) {
  78. if v == nil {
  79. return
  80. }
  81. structPointer_SetStructPointer(base, f, structPointer(reflect.ValueOf(v).Pointer()))
  82. }
  83. func setCustomType(base structPointer, f field, value interface{}) {
  84. if value == nil {
  85. return
  86. }
  87. v := reflect.ValueOf(value).Elem()
  88. t := reflect.TypeOf(value).Elem()
  89. kind := t.Kind()
  90. switch kind {
  91. case reflect.Slice:
  92. slice := reflect.MakeSlice(t, v.Len(), v.Cap())
  93. reflect.Copy(slice, v)
  94. oldHeader := structPointer_GetSliceHeader(base, f)
  95. oldHeader.Data = slice.Pointer()
  96. oldHeader.Len = v.Len()
  97. oldHeader.Cap = v.Cap()
  98. default:
  99. size := reflect.TypeOf(value).Elem().Size()
  100. structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), int(size))
  101. }
  102. }
  103. func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error {
  104. b, err := o.DecodeRawBytes(true)
  105. if err != nil {
  106. return err
  107. }
  108. i := reflect.New(p.ctype.Elem()).Interface()
  109. custom := (i).(Unmarshaler)
  110. if err := custom.Unmarshal(b); err != nil {
  111. return err
  112. }
  113. setPtrCustomType(base, p.field, custom)
  114. return nil
  115. }
  116. func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error {
  117. b, err := o.DecodeRawBytes(true)
  118. if err != nil {
  119. return err
  120. }
  121. i := reflect.New(p.ctype).Interface()
  122. custom := (i).(Unmarshaler)
  123. if err := custom.Unmarshal(b); err != nil {
  124. return err
  125. }
  126. if custom != nil {
  127. setCustomType(base, p.field, custom)
  128. }
  129. return nil
  130. }
  131. // Decode a slice of bytes ([]byte) into a slice of custom types.
  132. func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error {
  133. b, err := o.DecodeRawBytes(true)
  134. if err != nil {
  135. return err
  136. }
  137. i := reflect.New(p.ctype.Elem()).Interface()
  138. custom := (i).(Unmarshaler)
  139. if err := custom.Unmarshal(b); err != nil {
  140. return err
  141. }
  142. newBas := appendStructPointer(base, p.field, p.ctype)
  143. setCustomType(newBas, 0, custom)
  144. return nil
  145. }