Add a helper for getting array length: tf_util_get_length.

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3925 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2022-07-09 15:13:35 +00:00
parent 982b5817a2
commit 7f350a3d87
8 changed files with 86 additions and 102 deletions

View File

@ -239,23 +239,14 @@ static bool _serialize_storeInternal(tf_task_t* task, tf_taskstub_t* to, buffer_
else if (JS_IsArray(tf_task_get_context(task), value)) else if (JS_IsArray(tf_task_get_context(task), value))
{ {
_serialize_writeInt32(buffer, kArray); _serialize_writeInt32(buffer, kArray);
JSValue length_val = JS_GetPropertyStr(tf_task_get_context(task), value, "length"); int length = tf_util_get_length(tf_task_get_context(task), value);
int length; _serialize_writeInt32(buffer, length);
if (JS_ToInt32(tf_task_get_context(task), &length, length_val) == 0) for (int i = 0; i < length; ++i)
{ {
_serialize_writeInt32(buffer, length); JSValue element = JS_GetPropertyUint32(tf_task_get_context(task), value, i);
for (int i = 0; i < length; ++i) _serialize_storeInternal(task, to, buffer, element, depth + 1);
{ JS_FreeValue(context, element);
JSValue element = JS_GetPropertyUint32(tf_task_get_context(task), value, i);
_serialize_storeInternal(task, to, buffer, element, depth + 1);
JS_FreeValue(context, element);
}
} }
else
{
_serialize_writeInt32(buffer, 0);
}
JS_FreeValue(tf_task_get_context(task), length_val);
} }
else if (JS_IsFunction(tf_task_get_context(task), value)) else if (JS_IsFunction(tf_task_get_context(task), value))
{ {

View File

@ -4,6 +4,7 @@
#include "ssb.connections.h" #include "ssb.connections.h"
#include "ssb.db.h" #include "ssb.db.h"
#include "trace.h" #include "trace.h"
#include "util.js.h"
#include <assert.h> #include <assert.h>
#include <base64c.h> #include <base64c.h>
@ -1045,33 +1046,28 @@ static bool _tf_ssb_name_equals(JSContext* context, JSValue object, const char**
if (JS_IsArray(context, name)) if (JS_IsArray(context, name))
{ {
int length; int length = tf_util_get_length(context, name);
JSValue lengthval = JS_GetPropertyStr(context, name, "length"); for (int i = 0; i < length; i++)
if (JS_ToInt32(context, &length, lengthval) == 0)
{ {
for (int i = 0; i < length; i++) if (!match[i])
{ {
if (!match[i]) result = false;
{ break;
result = false;
break;
}
JSValue element = JS_GetPropertyUint32(context, name, i);
const char* str = JS_ToCString(context, element);
if (!str || strcmp(str, match[i]) != 0)
{
result = false;
}
JS_FreeCString(context, str);
JS_FreeValue(context, element);
} }
if (result && match[length])
JSValue element = JS_GetPropertyUint32(context, name, i);
const char* str = JS_ToCString(context, element);
if (!str || strcmp(str, match[i]) != 0)
{ {
result = false; result = false;
} }
JS_FreeCString(context, str);
JS_FreeValue(context, element);
}
if (result && match[length])
{
result = false;
} }
JS_FreeValue(context, lengthval);
} }
else else
{ {

View File

@ -3,6 +3,7 @@
#include "mem.h" #include "mem.h"
#include "ssb.h" #include "ssb.h"
#include "trace.h" #include "trace.h"
#include "util.js.h"
#include <base64c.h> #include <base64c.h>
#include <sodium/crypto_hash_sha256.h> #include <sodium/crypto_hash_sha256.h>
@ -425,68 +426,65 @@ bool tf_ssb_db_get_latest_message_by_author(tf_ssb_t* ssb, const char* author, i
static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds) static bool _tf_ssb_sqlite_bind_json(JSContext* context, sqlite3* db, sqlite3_stmt* statement, JSValue binds)
{ {
bool all_bound = true;
int32_t length = 0;
if (JS_IsUndefined(binds)) if (JS_IsUndefined(binds))
{ {
return true; return true;
} }
JSValue lengthval = JS_GetPropertyStr(context, binds, "length"); if (!JS_IsArray(context, binds))
if (JS_ToInt32(context, &length, lengthval) == 0)
{ {
for (int i = 0; i < length; i++) printf("Expected bind parameters to be an array.\n");
return false;
}
bool all_bound = true;
int32_t length = tf_util_get_length(context, binds);
for (int i = 0; i < length; i++)
{
JSValue value = JS_GetPropertyUint32(context, binds, i);
if (JS_IsString(value))
{ {
JSValue value = JS_GetPropertyUint32(context, binds, i); size_t str_len = 0;
if (JS_IsString(value)) const char* str = JS_ToCStringLen(context, &str_len, value);
if (str)
{ {
size_t str_len = 0; if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK)
const char* str = JS_ToCStringLen(context, &str_len, value);
if (str)
{
if (sqlite3_bind_text(statement, i + 1, str, str_len, SQLITE_TRANSIENT) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
JS_FreeCString(context, str);
}
else
{
printf("expected cstring\n");
}
}
else if (JS_IsNumber(value))
{
int64_t number = 0;
JS_ToInt64(context, &number, value);
if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
}
else if (JS_IsNull(value))
{
if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK)
{ {
printf("failed to bind: %s\n", sqlite3_errmsg(db)); printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false; all_bound = false;
} }
JS_FreeCString(context, str);
} }
else else
{ {
const char* str = JS_ToCString(context, value); printf("expected cstring\n");
printf("expected string: %s\n", str);
JS_FreeCString(context, str);
} }
JS_FreeValue(context, value);
} }
else if (JS_IsNumber(value))
{
int64_t number = 0;
JS_ToInt64(context, &number, value);
if (sqlite3_bind_int64(statement, i + 1, number) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
}
else if (JS_IsNull(value))
{
if (sqlite3_bind_null(statement, i + 1) != SQLITE_OK)
{
printf("failed to bind: %s\n", sqlite3_errmsg(db));
all_bound = false;
}
}
else
{
const char* str = JS_ToCString(context, value);
printf("expected string: %s\n", str);
JS_FreeCString(context, str);
}
JS_FreeValue(context, value);
} }
else
{
printf("expected array\n");
}
JS_FreeValue(context, lengthval);
return all_bound; return all_bound;
} }

View File

@ -3,6 +3,7 @@
#include "mem.h" #include "mem.h"
#include "ssb.db.h" #include "ssb.db.h"
#include "ssb.h" #include "ssb.h"
#include "util.js.h"
#include <quickjs.h> #include <quickjs.h>
#include <stdlib.h> #include <stdlib.h>
@ -51,10 +52,7 @@ static void _tf_ssb_import_add_app(tf_ssb_t* ssb, const char* user, const char*
JS_FreeValue(context, apps); JS_FreeValue(context, apps);
apps = JS_NewArray(context); apps = JS_NewArray(context);
} }
int32_t length = 0; int32_t length = tf_util_get_length(context, apps);;
JSValue lengthval = JS_GetPropertyStr(context, apps, "length");
JS_ToInt32(context, &length, lengthval);
JS_FreeValue(context, lengthval);
JS_SetPropertyUint32(context, apps, length, JS_NewString(context, app)); JS_SetPropertyUint32(context, apps, length, JS_NewString(context, app));
JSValue json = JS_JSONStringify(context, apps, JS_NULL, JS_NULL); JSValue json = JS_JSONStringify(context, apps, JS_NULL, JS_NULL);

View File

@ -488,14 +488,10 @@ static JSValue _tf_ssb_add_rpc(JSContext* context, JSValueConst this_val, int ar
return JS_ThrowTypeError(context, "Expected argument 2 to be a function."); return JS_ThrowTypeError(context, "Expected argument 2 to be a function.");
} }
JSValue length_val = JS_GetPropertyStr(context, argv[0], "length");
int length = 0;
JS_ToInt32(context, &length, length_val);
JS_FreeValue(context, length_val);
enum { k_max_name_parts = 16 }; enum { k_max_name_parts = 16 };
const char* name[k_max_name_parts + 1] = { 0 }; const char* name[k_max_name_parts + 1] = { 0 };
int length = tf_util_get_length(context, argv[0]);
if (length >= k_max_name_parts) if (length >= k_max_name_parts)
{ {
return JS_ThrowInternalError(context, "Too many parts to RPC name."); return JS_ThrowInternalError(context, "Too many parts to RPC name.");

View File

@ -423,22 +423,17 @@ JSValue _task_invokeExport_internal(tf_taskstub_t* from, tf_task_t* to, exportid
JSValue arguments = tf_serialize_load(to, from, buffer, size); JSValue arguments = tf_serialize_load(to, from, buffer, size);
JSValue* argument_array = NULL; JSValue* argument_array = NULL;
JSValue length_val = JS_GetPropertyStr(to->_context, arguments, "length");
int length;
JSValue this_val = JS_NULL; JSValue this_val = JS_NULL;
if (JS_ToInt32(to->_context, &length, length_val) == 0) int length = tf_util_get_length(to->_context, arguments);
if (length > 0)
{ {
if (length > 0) this_val = JS_GetPropertyUint32(to->_context, arguments, 0);
{ argument_array = alloca(sizeof(JSValue) * (length - 1));
this_val = JS_GetPropertyUint32(to->_context, arguments, 0); }
argument_array = alloca(sizeof(JSValue) * (length - 1)); for (int i = 1; i < length; ++i)
} {
for (int i = 1; i < length; ++i) argument_array[i - 1] = JS_GetPropertyUint32(to->_context, arguments, i);
{
argument_array[i - 1] = JS_GetPropertyUint32(to->_context, arguments, i);
}
} }
JS_FreeValue(to->_context, length_val);
JSValue function = export->_function; JSValue function = export->_function;
JSPropertyDescriptor desc = { 0 }; JSPropertyDescriptor desc = { 0 };

View File

@ -205,3 +205,12 @@ void tf_util_register(JSContext* context)
JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2)); JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2));
JS_FreeValue(context, global); JS_FreeValue(context, global);
} }
int tf_util_get_length(JSContext* context, JSValue value)
{
JSValue length = JS_GetPropertyStr(context, value, "length");
int result = 0;
JS_ToInt32(context, &result, length);
JS_FreeValue(context, length);
return result;
}

View File

@ -9,3 +9,4 @@ JSValue tf_util_utf8_decode(JSContext* context, JSValue value);
uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj); uint8_t* tf_util_try_get_array_buffer(JSContext* context, size_t* psize, JSValueConst obj);
JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element); JSValue tf_util_try_get_typed_array_buffer(JSContext* context, JSValueConst obj, size_t* pbyte_offset, size_t* pbyte_length, size_t* pbytes_per_element);
bool tf_util_report_error(JSContext* context, JSValue value); bool tf_util_report_error(JSContext* context, JSValue value);
int tf_util_get_length(JSContext* context, JSValue value);