func mustBeMap(state State, lvalue int) *reflect.Value { var vmap *reflect.Value L := state.L ltype := C.lua_type(L, C.int(lvalue)) if ltype == C.LUA_TUSERDATA { ref := C.clua_getGoRef(L, C.int(lvalue)) if ref != nil { obj := (*refGo)(ref).obj objValue := reflect.ValueOf(obj) if objValue.Kind() == reflect.Map { vmap = &objValue } } } return vmap }
func (state State) luaToGoValue(_lvalue int, outType *reflect.Type) (reflect.Value, error) { L := state.L lvalue := C.int(_lvalue) ltype := C.lua_type(L, lvalue) gkind := reflect.Invalid if outType != nil { gkind = (*outType).Kind() } switch ltype { case C.LUA_TNONE, C.LUA_TNIL: switch gkind { case reflect.Invalid, reflect.Func, reflect.Ptr, reflect.Interface: return reflect.ValueOf(nil), nil } case C.LUA_TBOOLEAN: switch gkind { case reflect.Invalid, reflect.Bool, reflect.Interface: cv := C.lua_toboolean(L, lvalue) var v bool if cv == 0 { v = false } else { v = true } return reflect.ValueOf(v), nil } //case C.LUA_TLIGHTUSERDATA: //case C.LUA_TTHREAD: case C.LUA_TNUMBER: switch gkind { case reflect.Int: v := int(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Int8: v := int8(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Int16: v := int16(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Int32: v := int32(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Int64: v := int64(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Uint: v := uint(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Uint8: v := uint8(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Uint16: v := uint16(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Uint32: v := uint32(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Uint64: v := uint64(C.lua_tointeger(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Float32: v := float32(C.lua_tonumber(L, lvalue)) return reflect.ValueOf(v), nil case reflect.Invalid, reflect.Interface, reflect.Float64: v := float64(C.lua_tonumber(L, lvalue)) return reflect.ValueOf(v), nil } case C.LUA_TSTRING: switch gkind { case reflect.Invalid, reflect.String, reflect.Interface: v := stringFromLua(L, lvalue) return reflect.ValueOf(v), nil } case C.LUA_TTABLE: if gkind == reflect.Slice && (*outType).Elem() == typeOfKeyValue { return state.luaTableToKeyValues(int(_lvalue)) } if gkind == reflect.Invalid || gkind == reflect.Interface || (outType != nil && *outType == reflect.TypeOf(theNullTable)) { tbl := state.NewLuaTable(int(lvalue)) return reflect.ValueOf(tbl), nil } case C.LUA_TFUNCTION: if gkind == reflect.Invalid || gkind == reflect.Interface || (outType != nil && *outType == reflect.TypeOf(theNullFunction)) { fn := state.NewLuaFunction(int(lvalue)) return reflect.ValueOf(fn), nil } case C.LUA_TUSERDATA: ref := C.clua_getGoRef(L, lvalue) if ref != nil { obj := (*refGo)(ref).obj objType := reflect.TypeOf(obj) objValue := reflect.ValueOf(obj) if gkind == reflect.Invalid || gkind == reflect.Interface { return objValue, nil } if outType != nil { if objType == *outType { return objValue, nil } if objType.Kind() == reflect.Ptr { if objType.Elem() == *outType { return objValue.Elem(), nil } } } } } return reflect.ValueOf(nil), fmt.Errorf("cannot convert from lua-type `%v' to go-type `%v'", luaTypeName(ltype), gkind) }