Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit a4c7a6e

Browse files
committed
Copy function update for better struct and map support
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
1 parent d8a900f commit a4c7a6e

2 files changed

Lines changed: 64 additions & 8 deletions

File tree

inmem.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -310,11 +310,16 @@ func (w *pipeSender) copyValue(v interface{}) (interface{}, error) {
310310
return w.copyReceiver(val)
311311
case map[string]interface{}:
312312
return w.copyChannelMessage(val)
313-
case struct{}:
314-
return w.copyStructure(v)
315-
case *struct{}:
316-
return w.copyStructure(v)
313+
case map[interface{}]interface{}:
314+
return w.copyChannelInterfaceMessage(val)
317315
default:
316+
if rv := reflect.ValueOf(v); rv.Kind() == reflect.Ptr {
317+
if rv.Elem().Kind() == reflect.Struct {
318+
return w.copyStructValue(rv.Elem())
319+
}
320+
} else if rv.Kind() == reflect.Struct {
321+
return w.copyStructValue(rv)
322+
}
318323
}
319324
return v, nil
320325
}
@@ -397,6 +402,22 @@ func (w *pipeSender) copyChannelMessage(m map[string]interface{}) (interface{},
397402
return mCopy, nil
398403
}
399404

405+
func (w *pipeSender) copyChannelInterfaceMessage(m map[interface{}]interface{}) (interface{}, error) {
406+
mCopy := make(map[string]interface{})
407+
for k, v := range m {
408+
vCopy, vErr := w.copyValue(v)
409+
if vErr != nil {
410+
return nil, vErr
411+
}
412+
keyStr, ok := k.(string)
413+
if !ok {
414+
return nil, errors.New("invalid non string key")
415+
}
416+
mCopy[keyStr] = vCopy
417+
}
418+
419+
return mCopy, nil
420+
}
400421
func (w *pipeSender) copyStructure(m interface{}) (interface{}, error) {
401422
v := reflect.ValueOf(m)
402423
if v.Kind() == reflect.Ptr {
@@ -405,6 +426,10 @@ func (w *pipeSender) copyStructure(m interface{}) (interface{}, error) {
405426
if v.Kind() != reflect.Struct {
406427
return nil, errors.New("invalid non struct type")
407428
}
429+
return w.copyStructValue(v)
430+
}
431+
432+
func (w *pipeSender) copyStructValue(v reflect.Value) (interface{}, error) {
408433
mCopy := make(map[string]interface{})
409434
t := v.Type()
410435
for i := 0; i < v.NumField(); i++ {

spdy/copy.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ func (c *channel) copyValue(v interface{}) (interface{}, error) {
3232
}
3333
return c.copySender(val)
3434
}
35+
case *channelWrapper:
36+
if val.direction == inbound {
37+
return c.copyReceiver(val)
38+
}
39+
return c.copySender(val)
3540
case *net.TCPConn:
3641
// Do nothing until socket support is added
3742
case *net.UDPConn:
@@ -48,11 +53,16 @@ func (c *channel) copyValue(v interface{}) (interface{}, error) {
4853
return c.copyReceiver(val)
4954
case map[string]interface{}:
5055
return c.copyChannelMessage(val)
51-
case struct{}:
52-
return c.copyStructure(v)
53-
case *struct{}:
54-
return c.copyStructure(v)
56+
case map[interface{}]interface{}:
57+
return c.copyChannelInterfaceMessage(val)
5558
default:
59+
if rv := reflect.ValueOf(v); rv.Kind() == reflect.Ptr {
60+
if rv.Elem().Kind() == reflect.Struct {
61+
return c.copyStructValue(rv.Elem())
62+
}
63+
} else if rv.Kind() == reflect.Struct {
64+
return c.copyStructValue(rv)
65+
}
5666
}
5767
return v, nil
5868
}
@@ -135,6 +145,23 @@ func (c *channel) copyChannelMessage(m map[string]interface{}) (interface{}, err
135145
return mCopy, nil
136146
}
137147

148+
func (c *channel) copyChannelInterfaceMessage(m map[interface{}]interface{}) (interface{}, error) {
149+
mCopy := make(map[string]interface{})
150+
for k, v := range m {
151+
vCopy, vErr := c.copyValue(v)
152+
if vErr != nil {
153+
return nil, vErr
154+
}
155+
keyStr, ok := k.(string)
156+
if !ok {
157+
return nil, errors.New("invalid non string key")
158+
}
159+
mCopy[keyStr] = vCopy
160+
}
161+
162+
return mCopy, nil
163+
}
164+
138165
func (c *channel) copyStructure(m interface{}) (interface{}, error) {
139166
v := reflect.ValueOf(m)
140167
if v.Kind() == reflect.Ptr {
@@ -143,6 +170,10 @@ func (c *channel) copyStructure(m interface{}) (interface{}, error) {
143170
if v.Kind() != reflect.Struct {
144171
return nil, errors.New("invalid non struct type")
145172
}
173+
return c.copyStructValue(v)
174+
}
175+
176+
func (c *channel) copyStructValue(v reflect.Value) (interface{}, error) {
146177
mCopy := make(map[string]interface{})
147178
t := v.Type()
148179
for i := 0; i < v.NumField(); i++ {

0 commit comments

Comments
 (0)