static duk_ret_t js_RawFile_read(duk_context* ctx) { int n_args = duk_get_top(ctx); long num_bytes = n_args >= 1 ? duk_require_int(ctx, 0) : 0; bytearray_t* array; FILE* file; long pos; void* read_buffer; duk_push_this(ctx); file = duk_require_sphere_obj(ctx, -1, "RawFile"); duk_pop(ctx); if (file == NULL) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "RawFile:read(): File has been closed"); if (n_args < 1) { // if no arguments, read entire file back to front pos = ftell(file); num_bytes = (fseek(file, 0, SEEK_END), ftell(file)); fseek(file, 0, SEEK_SET); } if (num_bytes <= 0) duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "RawFile:read(): Read size out of range (%u)", num_bytes); if (!(read_buffer = malloc(num_bytes))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "RawFile:read(): Failed to allocate buffer for file read"); num_bytes = (long)fread(read_buffer, 1, num_bytes, file); if (n_args < 1) // reset file position after whole-file read fseek(file, pos, SEEK_SET); if (!(array = bytearray_from_buffer(read_buffer, (int)num_bytes))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "RawFile:read(): Failed to create byte array"); duk_push_sphere_bytearray(ctx, array); return 1; }
static duk_ret_t js_CreateByteArrayFromString(duk_context* ctx) { lstring_t* string = duk_require_lstring_t(ctx, 0); bytearray_t* array; if (string->length > INT_MAX) duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "CreateByteArrayFromString(): Input string too large, size of byte array cannot exceed 2 GB"); if (!(array = bytearray_from_lstring(string))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "CreateByteArrayFromString(): Failed to create byte array from string (internal error)"); duk_push_sphere_bytearray(ctx, array); return 1; }
static duk_ret_t js_CreateByteArray(duk_context* ctx) { int size = duk_require_int(ctx, 0); bytearray_t* array; if (size < 0) duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "CreateByteArray(): Size cannot be negative (%i)", size); if (!(array = new_bytearray(size))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "CreateByteArray(): Failed to create new byte array (internal error)"); duk_push_sphere_bytearray(ctx, array); return 1; }
static duk_ret_t js_ByteArray_concat(duk_context* ctx) { bytearray_t* array2 = duk_require_sphere_bytearray(ctx, 0); bytearray_t* array; bytearray_t* new_array; duk_push_this(ctx); duk_get_prop_string(ctx, -1, "\xFF" "ptr"); array = duk_get_pointer(ctx, -1); duk_pop(ctx); duk_pop(ctx); if (array->size + array2->size > INT_MAX) duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "ByteArray:concat(): Unable to concatenate, final size would exceed 2 GB (size1: %u, size2: %u)", array->size, array2->size); if (!(new_array = concat_bytearrays(array, array2))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "ByteArray:concat(): Failed to create concatenated byte array (internal error)"); duk_push_sphere_bytearray(ctx, new_array); return 1; }
static duk_ret_t js_ByteArray_slice(duk_context* ctx) { int n_args = duk_get_top(ctx); int start = duk_require_int(ctx, 0); int end = (n_args >= 2) ? duk_require_int(ctx, 1) : INT_MAX; bytearray_t* array; int end_norm; bytearray_t* new_array; duk_push_this(ctx); duk_get_prop_string(ctx, -1, "\xFF" "ptr"); array = duk_get_pointer(ctx, -1); duk_pop(ctx); duk_pop(ctx); end_norm = fmin(end >= 0 ? end : array->size + end, array->size); if (end_norm < start || end_norm > array->size) duk_error_ni(ctx, -1, DUK_ERR_RANGE_ERROR, "ByteArray:slice(): Start and/or end values out of bounds (start: %i, end: %i - size: %i)", start, end_norm, array->size); if (!(new_array = slice_bytearray(array, start, end_norm - start))) duk_error_ni(ctx, -1, DUK_ERR_ERROR, "ByteArray:slice(): Failed to create sliced byte array (internal error)"); duk_push_sphere_bytearray(ctx, new_array); return 1; }