diff --git a/include/ntcore_c.h b/include/ntcore_c.h index d2113138f8..e63e84e0ad 100644 --- a/include/ntcore_c.h +++ b/include/ntcore_c.h @@ -339,8 +339,13 @@ void NT_DisposeString(struct NT_String *str); /* sets length to zero and pointer to null */ void NT_InitString(struct NT_String *str); +/* Gets the type for the specified key, or unassigned if non existent. */ +enum NT_Type NT_GetType(const char *name, size_t name_len); + void NT_DisposeConnectionInfoArray(struct NT_ConnectionInfo *arr, size_t count); +void NT_DisposeEntryInfoArray(struct NT_EntryInfo *arr, size_t count); + void NT_DisposeRpcDefinition(struct NT_RpcDefinition *def); void NT_DisposeRpcCallInfo(struct NT_RpcCallInfo *call_info); @@ -353,6 +358,63 @@ typedef void (*NT_LogFunc)(unsigned int level, const char *file, unsigned int line, const char *msg); void NT_SetLogger(NT_LogFunc func, unsigned int min_level); +/* +Interop Utility Functions +*/ + +/* Memory Allocators */ +char *NT_AllocateCharArray(size_t size); + +double *NT_AllocateDoubleArray(size_t size); + +int *NT_AllocateBooleanArray(size_t size); + +struct NT_String *NT_AllocateNTStringArray(size_t size); + +struct NT_String NT_AllocateNTString(size_t size); + +void NT_FreeDoubleArray(double *v_double); +void NT_FreeBooleanArray(int *v_boolean); +void NT_FreeStringArray(struct NT_String *v_string, size_t arr_size); + +enum NT_Type NT_GetTypeFromValue(struct NT_Value *value); + +int NT_GetEntryBooleanFromValue(struct NT_Value *value, unsigned long long *last_change, int *v_boolean); +int NT_GetEntryDoubleFromValue(struct NT_Value *value, unsigned long long *last_change, double *v_double); +int NT_GetEntryStringFromValue(struct NT_Value *value, unsigned long long *last_change, struct NT_String *v_string); +int NT_GetEntryRawFromValue(struct NT_Value *value, unsigned long long *last_change, struct NT_String *v_raw); + +int *NT_GetEntryBooleanArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size); +double *NT_GetEntryDoubleArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size); +NT_String *NT_GetEntryStringArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size); + + +int NT_GetEntryBoolean(const char* name, size_t name_len, unsigned long long *last_change, int *v_boolean); +int NT_GetEntryDouble(const char* name, size_t name_len, unsigned long long *last_change, double *v_double); +int NT_GetEntryString(const char *name, size_t name_len, unsigned long long *last_change, struct NT_String *v_string); +int NT_GetEntryRaw(const char *name, size_t name_len, unsigned long long *last_change, struct NT_String *v_raw); + +int *NT_GetEntryBooleanArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size); +double *NT_GetEntryDoubleArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size); +NT_String *NT_GetEntryStringArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size); + +/* Entry Value Setters */ +int NT_SetEntryDouble(const char *name, size_t name_len, + double v_double, int force); +int NT_SetEntryBoolean(const char *name, size_t name_len, + int v_boolean, int force); +int NT_SetEntryString(const char *name, size_t name_len, + struct NT_String v_string, int force); +int NT_SetEntryRaw(const char *name, size_t name_len, + struct NT_String v_raw, int force); + +int NT_SetEntryBooleanArray(const char *name, size_t name_len, + const int *arr, size_t size, int force); +int NT_SetEntryDoubleArray(const char *name, size_t name_len, + const double *arr, size_t size, int force); +int NT_SetEntryNTStringArray(const char *name, size_t name_len, + const struct NT_String *arr, size_t size, int force); + #ifdef __cplusplus } #endif diff --git a/ntcore.def b/ntcore.def index 97bbbd1a92..232bb4b6a3 100644 --- a/ntcore.def +++ b/ntcore.def @@ -41,6 +41,38 @@ NT_PackRpcValues @42 NT_UnpackRpcValues @43 NT_DisposeRpcDefinition @44 NT_DisposeRpcCallInfo @45 +NT_GetType @46 +NT_AllocateDoubleArray @47 +NT_AllocateBooleanArray @48 +NT_AllocateNTStringArray @49 +NT_AllocateNTString @50 +NT_FreeDoubleArray @51 +NT_FreeBooleanArray @52 +NT_FreeStringArray @53 +NT_GetTypeFromValue @54 +NT_GetEntryBooleanFromValue @55 +NT_GetEntryDoubleFromValue @56 +NT_GetEntryStringFromValue @57 +NT_GetEntryRawFromValue @58 +NT_GetEntryBooleanArrayFromValue @59 +NT_GetEntryDoubleArrayFromValue @60 +NT_GetEntryStringArrayFromValue @61 +NT_GetEntryBoolean @62 +NT_GetEntryDouble @63 +NT_GetEntryString @64 +NT_GetEntryRaw @65 +NT_GetEntryBooleanArray @66 +NT_GetEntryDoubleArray @67 +NT_GetEntryStringArray @68 +NT_SetEntryDouble @69 +NT_SetEntryBoolean @70 +NT_SetEntryString @71 +NT_SetEntryRaw @72 +NT_SetEntryBooleanArray @73 +NT_SetEntryDoubleArray @74 +NT_SetEntryNTStringArray @75 +NT_DisposeEntryInfoArray @76 +NT_AllocateCharArray @77 ; JNI functions JNI_OnLoad diff --git a/src/ntcore_c.cpp b/src/ntcore_c.cpp index 334513dc2a..38db6c2659 100644 --- a/src/ntcore_c.cpp +++ b/src/ntcore_c.cpp @@ -76,6 +76,10 @@ static void DisposeConnectionInfo(NT_ConnectionInfo *info) { std::free(info->remote_name); } +static void DisposeEntryInfo(NT_EntryInfo *info) { + std::free(info->name.str); +} + static RpcParamDef ConvertFromC(const NT_RpcParamDef& in) { RpcParamDef out; out.name = ConvertFromC(in.name); @@ -409,11 +413,22 @@ void NT_InitString(NT_String *str) { str->len = 0; } +enum NT_Type NT_GetType(const char *name, size_t name_len) { + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v) return NT_Type::NT_UNASSIGNED; + return v->type(); +} + void NT_DisposeConnectionInfoArray(NT_ConnectionInfo *arr, size_t count) { for (size_t i = 0; i < count; i++) DisposeConnectionInfo(&arr[i]); std::free(arr); } +void NT_DisposeEntryInfoArray(NT_EntryInfo *arr, size_t count){ + for (size_t i = 0; i < count; i++) DisposeEntryInfo(&arr[i]); + std::free(arr); +} + void NT_DisposeRpcDefinition(NT_RpcDefinition *def) { NT_DisposeString(&def->name); @@ -436,3 +451,328 @@ void NT_DisposeRpcCallInfo(NT_RpcCallInfo *call_info) { NT_DisposeString(&call_info->name); NT_DisposeString(&call_info->params); } + +/* Interop Utility Functions */ + +/* Array and Struct Allocations */ + +/* Allocates a char array of the specified size.*/ +char *NT_AllocateCharArray(size_t size) +{ + char *retVal = static_cast( + std::malloc(size * sizeof(char))); + return retVal; +} + +/* Allocates an integer or boolean array of the specified size. */ +int *NT_AllocateBooleanArray(size_t size) +{ + int *retVal = static_cast( + std::malloc(size * sizeof(int))); + return retVal; +} + +/* Allocates a double array of the specified size. */ +double *NT_AllocateDoubleArray(size_t size) +{ + double *retVal = static_cast( + std::malloc(size * sizeof(double))); + return retVal; +} + +/* Allocates an NT_String array of the specified size. */ +struct NT_String *NT_AllocateNTStringArray(size_t size) +{ + NT_String *retVal = static_cast( + std::malloc(size * sizeof(NT_String))); + return retVal; +} + +/* Allocates */ +struct NT_String NT_AllocateNTString(size_t size) +{ + NT_String retVal; + retVal.len = size; + retVal.str = static_cast( + std::malloc(size * sizeof(char))); + return retVal; +} + +void NT_FreeDoubleArray(double *v_double) +{ + std::free(v_double); +} +void NT_FreeBooleanArray(int *v_boolean) +{ + std::free(v_boolean); +} +void NT_FreeStringArray(struct NT_String *v_string, size_t arr_size) +{ + for (size_t i = 0; i < arr_size; i++) + std::free(v_string[i].str); + std::free(v_string); +} + +int NT_SetEntryDouble(const char *name, size_t name_len, double v_double, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeDouble(v_double)); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeDouble(v_double)); + } +} + +int NT_SetEntryBoolean(const char *name, size_t name_len, int v_boolean, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeBoolean(v_boolean)); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeBoolean(v_boolean)); + } +} + +int NT_SetEntryString(const char *name, size_t name_len, struct NT_String v_string, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeString(StringRef(v_string.str, v_string.len))); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeString(StringRef(v_string.str, v_string.len))); + } + +} + +int NT_SetEntryRaw(const char *name, size_t name_len, struct NT_String v_raw, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeString(StringRef(v_raw.str, v_raw.len))); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeString(StringRef(v_raw.str, v_raw.len))); + } + +} + +int NT_SetEntryBooleanArray(const char *name, size_t name_len, const int *arr, size_t size, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeBooleanArray(llvm::makeArrayRef(arr, size))); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeBooleanArray(llvm::makeArrayRef(arr, size))); + } +} + +int NT_SetEntryDoubleArray(const char *name, size_t name_len, const double *arr, size_t size, int force) +{ + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeDoubleArray(llvm::makeArrayRef(arr, size))); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeDoubleArray(llvm::makeArrayRef(arr, size))); + } +} + +int NT_SetEntryNTStringArray(const char *name, size_t name_len, const struct NT_String *arr, size_t size, int force) +{ + std::vector v; + v.reserve(size); + for (size_t i = 0; i < size; ++i) + v.push_back(ConvertFromC(arr[i])); + + if (force != 0) + { + nt::SetEntryTypeValue(StringRef(name, name_len), Value::MakeStringArray(std::move(v))); + return 1; + } + else + { + return nt::SetEntryValue(StringRef(name, name_len), Value::MakeStringArray(std::move(v))); + } + +} + +enum NT_Type NT_GetTypeFromValue(struct NT_Value *value) +{ + if (!value) return NT_Type::NT_UNASSIGNED; + return value->type; +} + +int NT_GetEntryBooleanFromValue(struct NT_Value *value, unsigned long long *last_change, int *v_boolean) +{ + if (!value || value->type != NT_Type::NT_BOOLEAN) + { + return 0; + } + *v_boolean = value->data.v_boolean; + *last_change = value->last_change; + return 1; + +} + +int NT_GetEntryDoubleFromValue(struct NT_Value *value, unsigned long long *last_change, double *v_double) +{ + if (!value || value->type != NT_Type::NT_DOUBLE) + { + return 0; + } + *last_change = value->last_change; + *v_double = value->data.v_double; + return 1; +} + +int NT_GetEntryStringFromValue(struct NT_Value *value, unsigned long long *last_change, struct NT_String *v_string) +{ + if (!value || value->type != NT_Type::NT_STRING) + { + return 0; + } + *last_change = value->last_change; + NT_DisposeString(v_string); + *v_string = value->data.v_string; + return 1; +} + +int NT_GetEntryRawFromValue(struct NT_Value *value, unsigned long long *last_change, struct NT_String *v_raw) +{ + if (!value || value->type != NT_Type::NT_RAW) + { + return 0; + } + *last_change = value->last_change; + NT_DisposeString(v_raw); + *v_raw = value->data.v_raw; + return 1; +} + +int *NT_GetEntryBooleanArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size) +{ + if (!value || value->type != NT_Type::NT_BOOLEAN_ARRAY) return nullptr; + *last_change = value->last_change; + *arr_size = value->data.arr_boolean.size; + return value->data.arr_boolean.arr; +} + +double *NT_GetEntryDoubleArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size) +{ + if (!value || value->type != NT_Type::NT_DOUBLE_ARRAY) return nullptr; + *last_change = value->last_change; + *arr_size = value->data.arr_double.size; + return value->data.arr_double.arr; +} + +NT_String *NT_GetEntryStringArrayFromValue(struct NT_Value *value, unsigned long long *last_change, size_t *arr_size) +{ + if (!value || value->type != NT_Type::NT_STRING_ARRAY) return nullptr; + *last_change = value->last_change; + *arr_size = value->data.arr_string.size; + return value->data.arr_string.arr; +} + +int NT_GetEntryBoolean(const char* name, size_t name_len, unsigned long long *last_change, int *v_boolean) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsBoolean()) + { + return 0; + } + *v_boolean = v->GetBoolean(); + *last_change = v->last_change(); + return 1; +} + +int NT_GetEntryDouble(const char* name, size_t name_len, unsigned long long *last_change, double *v_double) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsDouble()) + { + return 0; + } + *last_change = v->last_change(); + *v_double = v->GetDouble(); + return 1; +} + +int NT_GetEntryString(const char *name, size_t name_len, unsigned long long *last_change, struct NT_String *v_string) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsString()) { + return 0; + } + *last_change = v->last_change(); + nt::ConvertToC(v->GetString(), v_string); + return 1; +} + +int NT_GetEntryRaw(const char *name, size_t name_len, unsigned long long *last_change, struct NT_String *v_raw) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsRaw()) + { + return 0; + } + *last_change = v->last_change(); + nt::ConvertToC(v->GetRaw(), v_raw); + return 1; +} + +int *NT_GetEntryBooleanArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsBooleanArray()) return nullptr; + *last_change = v->last_change(); + auto vArr = v->GetBooleanArray(); + int *arr = static_cast(std::malloc(vArr.size() * sizeof(int))); + *arr_size = vArr.size(); + std::copy(vArr.begin(), vArr.end(), arr); + return arr; +} + +double *NT_GetEntryDoubleArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsDoubleArray()) return nullptr; + *last_change = v->last_change(); + auto vArr = v->GetDoubleArray(); + double *arr = static_cast(std::malloc(vArr.size() * sizeof(double))); + *arr_size = vArr.size(); + std::copy(vArr.begin(), vArr.end(), arr); + return arr; +} + +NT_String *NT_GetEntryStringArray(const char* name, size_t name_len, unsigned long long *last_change, size_t *arr_size) +{ + auto v = nt::GetEntryValue(StringRef(name, name_len)); + if (!v || !v->IsStringArray()) return nullptr; + *last_change = v->last_change(); + auto vArr = v->GetStringArray(); + NT_String *arr = + static_cast(std::malloc(vArr.size()*sizeof(NT_String))); + for (size_t i = 0; i < vArr.size(); ++i) + { + ConvertToC(vArr[i], &arr[i]); + } + *arr_size = vArr.size(); + return arr; +} +