aboutsummaryrefslogtreecommitdiffstats
path: root/cshared/std_cshared.go
blob: ca93993941721afdd771ba2d98ffb54f1f60ea0c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
// +build ignore
package main

import (
	"C"
	"reflect"
	"strings"
)

//export c_std_map_get_str_str
func c_std_map_get_str_str(m uint64, key string) *C.char {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return nil
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	}
	if mapval.Kind() != reflect.Map {
		return nil
	}
	val := mapval.MapIndex(reflect.ValueOf(key))
	if !val.IsValid() || SafeIsNil(val) {
		return nil
	}
	if (val.Kind() == reflect.Slice || val.Kind() == reflect.Array) &&
	    val.Type().Elem().Kind() == reflect.Uint8 {
		arr := make([]byte, val.Len(), val.Len())
		reflect.Copy(reflect.ValueOf(arr), val)
		return CBytes(arr)
	}
	return C.CString(val.String())
}

//export c_std_map_get_str_obj
func c_std_map_get_str_obj(m uint64, key string) uint64 {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return IH
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	}
	if mapval.Kind() != reflect.Map {
		return IH
	}
	val := mapval.MapIndex(reflect.ValueOf(key))
	if !val.IsValid() || SafeIsNil(val) {
		return IH
	}
	val_handle := RegisterObject(val.Interface())
	return uint64(val_handle)
}

//export c_std_map_get_obj_obj
func c_std_map_get_obj_obj(m uint64, key uint64) uint64 {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return IH
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	}
	if mapval.Kind() != reflect.Map {
		return IH
	}
	obj, ok = GetObject(Handle(key))
	if !ok {
		return IH
	}
	val := mapval.MapIndex(reflect.ValueOf(obj))
	if !val.IsValid() || SafeIsNil(val) {
		return IH
	}
	val_handle := RegisterObject(val.Interface())
	return uint64(val_handle)
}

//export c_std_map_keys_str
func c_std_map_keys_str(m uint64) *C.char {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return nil
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	}
	if mapval.Kind() != reflect.Map {
		return nil
	}
	keys := mapval.MapKeys()
	keys_str := make([]string, 0, len(keys))
	for _, k := range keys {
		keys_str = append(keys_str, k.String())
	}
	return C.CString(strings.Join(keys_str, "\xff"))
}

//export c_std_map_len
func c_std_map_len(m uint64) int {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return -1
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	}
	if mapval.Kind() != reflect.Map {
		return -1
	}
	return mapval.Len()
}

//export c_std_map_set_str
func c_std_map_set_str(m uint64, key string, val uint64) {
	obj, ok := GetObject(Handle(m))
	if !ok {
		return
	}
	mapval := reflect.ValueOf(obj)
	if mapval.Kind() == reflect.Ptr {
		mapval = mapval.Elem()
	} else {
		return
	}
	if mapval.Kind() != reflect.Map {
		return
	}
	if val == IH {
		mapval.SetMapIndex(reflect.ValueOf(key), reflect.Value{})
	} else {
		obj, ok := GetObject(Handle(val))
		if !ok {
			return
		}
		mapval.SetMapIndex(reflect.ValueOf(key), reflect.ValueOf(obj))
	}
}