Skip to content
Snippets Groups Projects
js_file.c 87.7 KiB
Newer Older
	FREE_AND_NULL(section);
	FREE_AND_NULL(key);
	return result != NULL;
deuce's avatar
deuce committed
static JSBool
js_iniSetValue(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	jsval      rval = JSVAL_FALSE;
	private_t* p;
	str_list_t list;
	jsrefcount rc;

	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) != NULL) {
		if (js_iniSetValue_internal(cx, obj, argc, argv, &list))
			rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list));
	}
	strListFree(&list);
	JS_RESUMEREQUEST(cx, rc);
deuce's avatar
deuce committed

	JS_SET_RVAL(cx, arglist, rval);
deuce's avatar
deuce committed
}

js_iniRemoveKey(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      section = ROOT_SECTION;
	char*      key = NULL;
	private_t* p;
	str_list_t list;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (argc && argv[0] != JSVAL_VOID && argv[0] != JSVAL_NULL) {
		JSVALUE_TO_MSTRING(cx, argv[0], section, NULL);
	JSVALUE_TO_MSTRING(cx, argv[1], key, NULL);
	if (JS_IsExceptionPending(cx)) {
		FREE_AND_NULL(key);
		FREE_AND_NULL(section);
		return JS_FALSE;
	}
		JS_ReportError(cx, "Invalid NULL key specified");
	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) == NULL) {
		FREE_AND_NULL(section);
		FREE_AND_NULL(key);
	if (iniRemoveKey(&list, section, key))
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list)));
js_iniRemoveSection(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      section = ROOT_SECTION;
	private_t* p;
	str_list_t list;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (argc && argv[0] != JSVAL_VOID && argv[0] != JSVAL_NULL) {
		JSVALUE_TO_MSTRING(cx, argv[0], section, NULL);
		HANDLE_PENDING(cx, section);
	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) == NULL) {
	if (iniRemoveSection(&list, section))
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list)));
static JSBool
js_iniRemoveSections(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      prefix = NULL;
	private_t* p;
	str_list_t list;
	jsrefcount rc;

	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);

	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
		return JS_FALSE;
	if (argc && argv[0] != JSVAL_VOID && argv[0] != JSVAL_NULL) {
		JSVALUE_TO_MSTRING(cx, argv[0], prefix, NULL);
		HANDLE_PENDING(cx, prefix);
	}

	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) == NULL) {
		JS_RESUMEREQUEST(cx, rc);
		FREE_AND_NULL(prefix);
		return JS_TRUE;
	}

	if (iniRemoveSections(&list, prefix))
		JS_SET_RVAL(cx, arglist, BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list)));

	FREE_AND_NULL(prefix);
	strListFree(&list);
	JS_RESUMEREQUEST(cx, rc);

	return JS_TRUE;
}
js_iniGetSections(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      prefix = NULL;
	char**     list;
	jsint      i;
	jsval      val;
	JSObject*  array;
	private_t* p;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
		JSVALUE_TO_MSTRING(cx, argv[0], prefix, NULL);
		HANDLE_PENDING(cx, prefix);
	array = JS_NewArrayObject(cx, 0, NULL);
	rc = JS_SUSPENDREQUEST(cx);
	str_list_t ini = iniReadFile(p->fp);
	list = iniGetSectionList(ini, prefix);
	strListFree(&ini);
	for (i = 0; list && list[i]; i++) {
		val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, list[i]));
		if (!JS_SetElement(cx, array, i, &val))
	rc = JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
js_iniGetKeys(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      section = ROOT_SECTION;
	char**     list;
	jsint      i;
	jsval      val;
	JSObject*  array;
	private_t* p;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (argc && argv[0] != JSVAL_VOID && argv[0] != JSVAL_NULL) {
		JSVALUE_TO_MSTRING(cx, argv[0], section, NULL);
		HANDLE_PENDING(cx, section);
	array = JS_NewArrayObject(cx, 0, NULL);
	rc = JS_SUSPENDREQUEST(cx);
	str_list_t ini = iniReadFile(p->fp);
	list = iniGetKeyList(ini, section);
	strListFree(&ini);
	for (i = 0; list && list[i]; i++) {
		val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, list[i]));
		if (!JS_SetElement(cx, array, i, &val))
	rc = JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
js_iniGetObject(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *       obj = JS_THIS_OBJECT(cx, arglist);
	jsval *          argv = JS_ARGV(cx, arglist);
	char*            section = ROOT_SECTION;
	jsint            i;
	JSObject*        object;
	private_t*       p;
	jsrefcount       rc;
	bool             lowercase = false;
	bool             blanks = false;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (argc > argn && !JSVAL_IS_BOOLEAN(argv[argn]) && !JSVAL_NULL_OR_VOID(argv[argn])) {
		JSVALUE_TO_MSTRING(cx, argv[argn], section, NULL);
		HANDLE_PENDING(cx, section);
	if (argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) {
		lowercase = JSVAL_TO_BOOLEAN(argv[argn]);
		argn++;
	if (argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) {
		blanks = JSVAL_TO_BOOLEAN(argv[argn]);
		argn++;
	}
	rc = JS_SUSPENDREQUEST(cx);
	str_list_t ini = iniReadFile(p->fp);
	list = iniGetNamedStringList(ini, section);
	strListFree(&ini);
	object = JS_NewObject(cx, NULL, NULL, obj);
	for (i = 0; list && list[i]; i++) {
		if (lowercase)
		JS_DefineProperty(cx, object, list[i]->name
		                  , get_value(cx, list[i]->value, blanks)
		                  , NULL, NULL, JSPROP_ENUMERATE);
	rc = JS_SUSPENDREQUEST(cx);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(object));
js_iniSetObject(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	jsint      i;
	JSObject*  object;
	JSIdArray* id_array;
	jsval      set_argv[3];
	jsval      rval;
	char*      cp;
	private_t* p;
	str_list_t list;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	set_argv[0] = argv[0];    /* section */
	if (!JSVAL_IS_OBJECT(argv[1]) || argv[1] == JSVAL_NULL)
	object = JSVAL_TO_OBJECT(argv[1]);
	if (object == NULL || (id_array = JS_Enumerate(cx, object)) == NULL)
	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) == NULL) {
		JS_DestroyIdArray(cx, id_array);
		return JS_TRUE;
	}
	JS_RESUMEREQUEST(cx, rc);

	rval = JSVAL_TRUE;
	for (i = 0; i < id_array->length; i++)  {
		JS_IdToValue(cx, id_array->vector[i], &set_argv[1]);
		JSVALUE_TO_MSTRING(cx, set_argv[1], cp, NULL);
		if (cp == NULL) {
			JS_DestroyIdArray(cx, id_array);
			JS_ReportError(cx, "Invalid NULL property");
			return JS_FALSE;
		}
		if (JS_IsExceptionPending(cx)) {
			JS_DestroyIdArray(cx, id_array);
		(void)JS_GetProperty(cx, object, cp, &set_argv[2]);
		if (!js_iniSetValue_internal(cx, obj, 3, set_argv, &list)) {
	rc = JS_SUSPENDREQUEST(cx);
	if (rval == JSVAL_TRUE)
		rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list));
	strListFree(&list);
	JS_RESUMEREQUEST(cx, rc);
deuce's avatar
deuce committed
	JS_SET_RVAL(cx, arglist, rval);
	JS_DestroyIdArray(cx, id_array);
js_iniGetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *       obj = JS_THIS_OBJECT(cx, arglist);
	jsval *          argv = JS_ARGV(cx, arglist);
	const char *     name_def = "name";
	char*            name = (char *)name_def;
	char*            sec_name;
	char*            prefix = NULL;
	char**           sec_list;
	str_list_t       ini;
	jsint            i, k;
	jsval            val;
	JSObject*        array;
	JSObject*        object;
	private_t*       p;
	jsrefcount       rc;
	bool             lowercase = false;
	bool             blanks = false;
	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (argc > argn && JSVAL_IS_STRING(argv[argn])) {
		JSVALUE_TO_MSTRING(cx, argv[argn], name, NULL);
		HANDLE_PENDING(cx, name);
			JS_ReportError(cx, "Invalid name argument");
			return JS_FALSE;
		}
		argn++;
	}
	if (argc > argn && JSVAL_IS_STRING(argv[argn])) {
		JSVALUE_TO_MSTRING(cx, argv[argn], prefix, NULL);
		argn++;
	}
	if (argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) {
		lowercase = JSVAL_TO_BOOLEAN(argv[argn]);
		argn++;
	if (argc > argn && JSVAL_IS_BOOLEAN(argv[argn])) {
		blanks = JSVAL_TO_BOOLEAN(argv[argn]);
		argn++;
	}
	if (JS_IsExceptionPending(cx)) {
		if (name != name_def)
			free(name);
		return JS_FALSE;
	}
	array = JS_NewArrayObject(cx, 0, NULL);
	rc = JS_SUSPENDREQUEST(cx);
	ini = iniReadFile(p->fp);
	sec_list = iniGetSectionList(ini, prefix);
	for (i = 0; sec_list && sec_list[i]; i++) {
		object = JS_NewObject(cx, NULL, NULL, obj);
		sec_name = sec_list[i];
		if (prefix != NULL)
			sec_name += strlen(prefix);
		if (lowercase)
		JS_DefineProperty(cx, object, name
		                  , STRING_TO_JSVAL(JS_NewStringCopyZ(cx, sec_name))
		                  , NULL, NULL, JSPROP_ENUMERATE);
		rc = JS_SUSPENDREQUEST(cx);
		key_list = iniGetNamedStringList(ini, sec_list[i]);
		for (k = 0; key_list && key_list[k]; k++) {
			if (lowercase)
			JS_DefineProperty(cx, object, key_list[k]->name
			                  , get_value(cx, key_list[k]->value, blanks)
			                  , NULL, NULL, JSPROP_ENUMERATE);
		rc = JS_SUSPENDREQUEST(cx);
		iniFreeNamedStringList(key_list);
		val = OBJECT_TO_JSVAL(object);
		if (!JS_SetElement(cx, array, i, &val))
	rc = JS_SUSPENDREQUEST(cx);
	if (name != name_def)
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
js_iniSetAllObjects(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *  obj = JS_THIS_OBJECT(cx, arglist);
	jsval *     argv = JS_ARGV(cx, arglist);
	const char *name_def = "name";
	char*       name = (char *)name_def;
	jsuint      i;
	jsint       j;
	jsuint      count;
	JSObject*   array;
	JSObject*   object;
	jsval       oval;
	jsval       set_argv[3];
	JSIdArray*  id_array;
	jsval       rval;
	char*       cp = NULL;
	str_list_t  list;
	jsrefcount  rc;
	private_t*  p;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if (JSVAL_IS_NULL(argv[0]) || !JSVAL_IS_OBJECT(argv[0]))
	array = JSVAL_TO_OBJECT(argv[0]);
	if (array == NULL || !JS_IsArrayObject(cx, array))
	if (!JS_GetArrayLength(cx, array, &count))
		JSVALUE_TO_MSTRING(cx, argv[1], name, NULL);
		HANDLE_PENDING(cx, name);
			JS_ReportError(cx, "Invalid NULL name property");
			return JS_FALSE;
		}
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
		if (name != name_def)
			free(name);
	if (p->fp == NULL) {
		if (name != name_def)
			free(name);
	rc = JS_SUSPENDREQUEST(cx);
	if ((list = iniReadFile(p->fp)) == NULL) {
		if (name != name_def)
	for (i = 0; i < count && rval == JSVAL_TRUE; i++)  {
		if (!JS_GetElement(cx, array, i, &oval))
		if (!JSVAL_IS_OBJECT(oval))  /* must be an array of objects */
		object = JSVAL_TO_OBJECT(oval);
		if (object == NULL || !JS_GetProperty(cx, object, name, &set_argv[0]))
		if ((id_array = JS_Enumerate(cx, object)) == NULL) {
			if (name != name_def)
		for (j = 0; j < id_array->length; j++)  {
			JS_IdToValue(cx, id_array->vector[j], &set_argv[1]);
			JSVALUE_TO_MSTRING(cx, set_argv[1], cp, NULL);
			if (JS_IsExceptionPending(cx)) {
				JS_DestroyIdArray(cx, id_array);
				if (name != name_def)
					free(name);
				return JS_FALSE;
			}
			if (strcmp(cp, name) == 0) {
			if (!JS_GetProperty(cx, object, cp, &set_argv[2])) {
				FREE_AND_NULL(cp);
				continue;
			}
			FREE_AND_NULL(cp);  /* Moved from before JS_GetProperty() call */
			if (!js_iniSetValue_internal(cx, obj, 3, set_argv, &list)) {
		JS_DestroyIdArray(cx, id_array);
	if (name != name_def)
	rc = JS_SUSPENDREQUEST(cx);
	if (rval == JSVAL_TRUE)
		rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp, list));
	strListFree(&list);
	JS_RESUMEREQUEST(cx, rc);

	JS_SET_RVAL(cx, arglist, rval);

static JSBool
js_iniReadAll(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	private_t* p;
	jsrefcount rc;

	JS_SET_RVAL(cx, arglist, JSVAL_NULL);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL)
	JSObject* array = JS_NewArrayObject(cx, 0, NULL);
	if (array == NULL)
	rc = JS_SUSPENDREQUEST(cx);
	str_list_t list = iniReadFile(p->fp);
	JS_RESUMEREQUEST(cx, rc);
	for (size_t i = 0; list != NULL && list[i] != NULL; i++) {
		JSString* js_str;
		if ((js_str = JS_NewStringCopyZ(cx, list[i])) == NULL)
		jsval     val = STRING_TO_JSVAL(js_str);
		if (!JS_SetElement(cx, array, i, &val))
			break;
	}
	strListFree(&list);
	JS_SET_RVAL(cx, arglist, OBJECT_TO_JSVAL(array));
static JSBool
js_raw_write(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      cp = NULL;
	size_t     len;     /* string length */
	JSString*  str;
	private_t* p;
	jsrefcount rc;
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if ((str = JS_ValueToString(cx, argv[0])) == NULL)

	JSSTRING_TO_MSTRING(cx, str, cp, &len);
	rc = JS_SUSPENDREQUEST(cx);
	if (write(fileno(p->fp), cp, len) == (size_t)len) {
		dbprintf(FALSE, p, "wrote %lu raw bytes", len);
		JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
	} else {
		free(cp);
		dbprintf(TRUE, p, "raw write of %lu bytes failed", len);
js_write(JSContext *cx, uintN argc, jsval *arglist)
	JSObject * obj = JS_THIS_OBJECT(cx, arglist);
	jsval *    argv = JS_ARGV(cx, arglist);
	char*      cp = NULL;
	char*      uubuf = NULL;
	size_t     len;     /* string length */
	int        decoded_len;
	size_t     tlen;    /* total length to write (may be greater than len) */
	int32      i;
	JSString*  str;
	private_t* p;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if ((str = JS_ValueToString(cx, argv[0])) == NULL)
	JSSTRING_TO_MSTRING(cx, str, cp, &len);
	rc = JS_SUSPENDREQUEST(cx);
	if ((p->uuencoded || p->b64encoded || p->yencoded)
	    && len && (uubuf = malloc(len)) != NULL) {
		if (p->uuencoded)
			decoded_len = uudecode(uubuf, len, cp, len);
		else if (p->yencoded)
			decoded_len = ydecode(uubuf, len, cp, len);
			decoded_len = b64_decode(uubuf, len, cp, len);
		if (decoded_len < 0) {
		len = decoded_len;
	tlen = len;
	if (argc > 1 && !JSVAL_NULL_OR_VOID(argv[1])) {
		if (!JS_ValueToInt32(cx, argv[1], &i)) {
		tlen = i;
		if (len > tlen)
			len = tlen;
	rc = JS_SUSPENDREQUEST(cx);
	if (fwrite(cp, 1, len, p->fp) == (size_t)len) {
		if (tlen > len) {
			len = tlen - len;
			if ((cp = malloc(len)) == NULL) {
				JS_ReportError(cx, "malloc failure of %u bytes", len);
			memset(cp, p->etx, len);
			if (fwrite(cp, 1, len, p->fp) < len) {
				free(cp);
				JS_RESUMEREQUEST(cx, rc);
				return JS_TRUE;
			}
		dbprintf(FALSE, p, "wrote %lu bytes", (ulong)tlen);
		JS_SET_RVAL(cx, arglist, JSVAL_TRUE);
		dbprintf(TRUE, p, "write of %lu bytes failed", (ulong)len);
deuce's avatar
deuce committed
js_writeln_internal(JSContext *cx, JSObject *obj, jsval *arg, jsval *rval)
	const char *cp_def = "";
	char*       cp = (char *)cp_def;
	JSString*   str;
	private_t*  p;
	jsrefcount  rc;
deuce's avatar
deuce committed
	*rval = JSVAL_FALSE;
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (arg) {
		if ((str = JS_ValueToString(cx, *arg)) == NULL) {
			JS_ReportError(cx, "JS_ValueToString failed");
		JSSTRING_TO_MSTRING(cx, str, cp, NULL);
		if (cp == NULL)
			cp = (char *)cp_def;
	rc = JS_SUSPENDREQUEST(cx);
	if (p->rot13)
	if (fprintf(p->fp, "%s\n", cp) != 0)
deuce's avatar
deuce committed
		*rval = JSVAL_TRUE;
deuce's avatar
deuce committed
static JSBool
js_writeln(JSContext *cx, uintN argc, jsval *arglist)
{
	JSObject *obj = JS_THIS_OBJECT(cx, arglist);
	jsval *   argv = JS_ARGV(cx, arglist);
	jsval     rval;
	JSBool    ret;
deuce's avatar
deuce committed

	if (argc) {
		ret = js_writeln_internal(cx, obj, &argv[0], &rval);
deuce's avatar
deuce committed
	}
	else {
		ret = js_writeln_internal(cx, obj, NULL, &rval);
deuce's avatar
deuce committed
	}
	JS_SET_RVAL(cx, arglist, rval);

deuce's avatar
deuce committed
}

static JSBool
js_writebin(JSContext *cx, uintN argc, jsval *arglist)
	JSObject *obj = JS_THIS_OBJECT(cx, arglist);
	jsval *   argv = JS_ARGV(cx, arglist);
		uint8_t *b;
		uint16_t *w;
		uint32_t *l;
		uint64_t *q;
		int8_t *sb;
		int16_t *sw;
		int32_t *sl;
		int64_t *sq;
	size_t     wr = 0;
	int32      size = sizeof(int32_t);
	jsuint     count = 1;
	void *     buffer;
	private_t* p;
	JSObject*  array = NULL;
	jsval      elemval;
	jsdouble   val = 0;
	jsrefcount rc;
	JS_SET_RVAL(cx, arglist, JSVAL_FALSE);
	if ((p = (private_t*)js_GetClassPrivate(cx, obj, &js_file_class)) == NULL) {
	if (JSVAL_IS_OBJECT(argv[0]) && !JSVAL_IS_NULL(argv[0])) {
		array = JSVAL_TO_OBJECT(argv[0]);
		if (array != NULL && JS_IsArrayObject(cx, array)) {
			if (!JS_GetArrayLength(cx, array, &count))
	if (array == NULL) {
		if (!JS_ValueToNumber(cx, argv[0], &val))
	if (argc > 1 && !JSVAL_NULL_OR_VOID(argv[1])) {
		if (!JS_ValueToInt32(cx, argv[1], &size))
	if (size != sizeof(BYTE) && size != sizeof(WORD) && size != sizeof(DWORD) && size != sizeof(uint64_t)) {
		rc = JS_SUSPENDREQUEST(cx);
		dbprintf(TRUE, p, "unsupported binary write size: %d", size);
	buffer = calloc(size, count);
	if (buffer == NULL) {
		rc = JS_SUSPENDREQUEST(cx);
		dbprintf(TRUE, p, "malloc failure of %u bytes", size * count);
	o.b = buffer;
	if (array == NULL) {
		switch (size) {
				if (val < 0)
					*o.sb = (int8_t)val;
					*o.b = (uint8_t)val;
				if (val < 0)
					*o.sw = (int16_t)val;
					*o.w = (uint16_t)val;
				if (p->network_byte_order)
				if (val < 0)
					*o.sl = (int32_t)val;
					*o.l = (uint32_t)val;
				if (p->network_byte_order)
					*o.sq = (int64_t)val;
				else
					*o.q = (uint64_t)val;
				if (p->network_byte_order)
					*o.q = BE_INT64(*o.q);
				else
					*o.q = LE_INT64(*o.q);
		for (wr = 0; wr < count; wr++) {
			if (!JS_GetElement(cx, array, wr, &elemval))
			if (!JS_ValueToNumber(cx, elemval, &val))