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