📄 b_file.c
字号:
result_return->u.vboolean = ictx->stream->at_eof;
}
/* ***************************************************************** */
else if (method == ctx->s_read)
{
size_t got;
char *buffer;
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_INTEGER || args[1].u.vinteger < 0)
goto argument_type_error;
if (ictx->stream != NULL)
{
buffer = js_vm_alloc (vm, args[1].u.vinteger + 1);
got = js_iostream_read (ictx->stream, buffer,
args[1].u.vinteger);
if (got < 0)
got = 0;
js_vm_make_static_string (vm, result_return, buffer, got);
result_return->u.vstring->staticp = 0;
}
}
/* ***************************************************************** */
else if (method == ctx->s_readln)
{
/* int ch; */
unsigned int bufpos = 0;
unsigned int buflen = 0;
char *buffer = NULL;
if (args->u.vinteger != 0)
goto argument_error;
if (ictx->stream != NULL)
{
/* Flush all buffered output data. */
js_iostream_flush (ictx->stream);
while (1)
{
/* Process all the data we have in the buffer. */
for (; ictx->stream->bufpos < ictx->stream->data_in_buf
&& (ictx->stream->buffer[ictx->stream->bufpos]
!= '\n');
ictx->stream->bufpos++)
{
if (bufpos >= buflen)
{
buflen += 1024;
buffer = js_vm_realloc (vm, buffer, buflen);
}
buffer[bufpos++]
= ictx->stream->buffer[ictx->stream->bufpos];
}
if (ictx->stream->bufpos >= ictx->stream->data_in_buf)
{
/* int result; */
/* Read past the buffer. */
if (ictx->stream->at_eof)
/* EOF seen. */
break;
/* Read more data. */
js_iostream_fill_buffer (ictx->stream);
}
else
{
/* Got it. Skip the newline character. */
ictx->stream->bufpos++;
break;
}
}
/* Remove '\r' characters. */
while (bufpos > 0)
if (buffer[bufpos - 1] == '\r')
bufpos--;
else
break;
if (buffer == NULL)
/* An empty string. Allocate one byte. */
buffer = js_vm_alloc (vm, 1);
/*
* Use the data we already had. In maximum, it has only
* 1023 bytes overhead.
*/
js_vm_make_static_string (vm, result_return, buffer, bufpos);
result_return->u.vstring->staticp = 0;
}
}
/* ***************************************************************** */
else if (method == ctx->s_readByte)
{
result_return->type = JS_INTEGER;
if (ictx->stream == NULL)
result_return->u.vinteger = -1;
else
{
retry:
if (ictx->stream->bufpos < ictx->stream->data_in_buf)
result_return->u.vinteger
= ictx->stream->buffer[ictx->stream->bufpos++];
else
{
if (ictx->stream->at_eof)
result_return->u.vinteger = -1;
else
{
js_iostream_fill_buffer (ictx->stream);
goto retry;
}
}
}
}
/* ***************************************************************** */
else if (method == ctx->s_write || method == ctx->s_writeln)
{
size_t wrote;
int autoflush;
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_STRING)
goto argument_type_error;
if (ictx->stream != NULL)
{
autoflush = ictx->stream->autoflush;
ictx->stream->autoflush = 0;
wrote = js_iostream_write (ictx->stream,
args[1].u.vstring->data,
args[1].u.vstring->len);
if (wrote == args[1].u.vstring->len)
{
/* Success. */
result_return->u.vboolean = 1;
if (method == ctx->s_writeln)
if (js_iostream_write (ictx->stream,
JS_HOST_LINE_BREAK,
JS_HOST_LINE_BREAK_LEN) < 0)
/* No, it was not a success. */
result_return->u.vboolean = 0;
}
ictx->stream->autoflush = autoflush;
if (autoflush)
js_iostream_flush (ictx->stream);
}
}
/* ***************************************************************** */
else if (method == ctx->s_writeByte)
{
unsigned char buf[1];
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_INTEGER)
goto argument_type_error;
buf[0] = args[1].u.vinteger;
if (ictx->stream != NULL)
result_return->u.vboolean
= js_iostream_write (ictx->stream, buf, 1) >= 0;
}
/* ***************************************************************** */
else if (method == ctx->s_ungetByte)
{
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_INTEGER)
goto argument_type_error;
if (ictx->stream != NULL)
result_return->u.vboolean
= js_iostream_unget (ictx->stream, args[1].u.vinteger);
}
/* ***************************************************************** */
else if (method == ctx->s_flush)
{
if (args->u.vinteger != 0)
goto argument_error;
if (ictx->stream != NULL && js_iostream_flush (ictx->stream) >= 0)
result_return->u.vboolean = 1;
}
/* ***************************************************************** */
else if (method == ctx->s_getLength)
{
if (args->u.vinteger != 0)
goto argument_error;
/* The default error code is an integer -1. */
result_return->type = JS_INTEGER;
result_return->u.vinteger = -1;
if (ictx->stream != NULL)
result_return->u.vinteger
= js_iostream_get_length (ictx->stream);
}
/* ***************************************************************** */
else if (method == ctx->s_exists)
{
#if 0
if (args->u.vinteger != 0)
goto argument_error;
if (ictx->stream)
{
/* Since we have opened the file, it must exist. */
result_return->u.vboolean = 1;
}
else
{
struct stat stat_st;
if (stat (ictx->path, &stat_st) >= 0)
result_return->u.vboolean = 1;
}
#endif
}
/* ***************************************************************** */
else if (method == ctx->s_error)
{
if (args->u.vinteger != 0)
goto argument_error;
result_return->type = JS_INTEGER;
if (ictx->stream == NULL)
result_return->u.vinteger = -1;
else
result_return->u.vinteger = ictx->stream->error;
}
/* ***************************************************************** */
else if (method == ctx->s_clearError)
{
if (args->u.vinteger != 0)
goto argument_error;
if (ictx->stream != NULL)
{
ictx->stream->error = 0;
result_return->u.vboolean = 1;
}
}
/* ***************************************************************** */
else
return JS_PROPERTY_UNKNOWN;
}
else
return JS_PROPERTY_UNKNOWN;
return JS_PROPERTY_FOUND;
/*
* Error handling.
*/
argument_error:
sprintf (vm->error, "File.%s(): illegal amount of arguments",
js_vm_symname (vm, method));
js_vm_error (vm);
argument_type_error:
sprintf (vm->error, "File.%s(): illegal argument",
js_vm_symname (vm, method));
js_vm_error (vm);
insecure_feature:
sprintf (vm->error, "File.%s(): not allowed in secure mode",
js_vm_symname (vm, method));
js_vm_error (vm);
/* NOTREACHED */
return 0;
}
/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
void *instance_context, JSSymbol property, int set, JSNode *node)
{
FileCtx *ctx = builtin_info->obj_context;
FileInstanceCtx *ictx = instance_context;
if (ictx)
{
/* Instance properties. */
if (property == ctx->s_autoFlush)
{
if (ictx->stream == NULL)
goto not_open;
if (set)
{
if (node->type != JS_BOOLEAN)
goto argument_type_error;
ictx->stream->autoflush = node->u.vboolean;
}
else
{
node->type = JS_BOOLEAN;
node->u.vboolean = ictx->stream->autoflush;
}
}
/* ***************************************************************** */
else if (property == ctx->s_bufferSize)
{
if (ictx->stream == NULL)
goto not_open;
if (set)
{
unsigned char *buf;
unsigned int len;
if (node->type != JS_INTEGER)
goto argument_type_error;
js_iostream_flush (ictx->stream);
len = node->u.vinteger;
buf = js_realloc (vm, ictx->stream->buffer, len);
ictx->stream->buflen = len;
ictx->stream->buffer = buf;
}
else
{
node->type = JS_INTEGER;
node->u.vinteger = ictx->stream->buflen;
}
}
/* ***************************************************************** */
else
{
if (!set)
node->type = JS_UNDEFINED;
return JS_PROPERTY_UNKNOWN;
}
}
else
{
if (!set)
node->type = JS_UNDEFINED;
return JS_PROPERTY_UNKNOWN;
}
return JS_PROPERTY_FOUND;
/* Error handling. */
argument_type_error:
sprintf (vm->error, "File.%s: illegal value",
js_vm_symname (vm, property));
js_vm_error (vm);
not_open:
sprintf (vm->error, "File.%s: the stream is not opened",
js_vm_symname (vm, property));
js_vm_error (vm);
/* NOTREACHED */
return 0;
}
/* New proc. */
static void
new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
JSNode *result_return)
{
FileInstanceCtx *instance;
if (args->u.vinteger != 1)
{
sprintf (vm->error, "new File(): illegal amount of arguments");
js_vm_error (vm);
}
if (args[1].type != JS_STRING)
{
sprintf (vm->error, "new File(): illegal argument");
js_vm_error (vm);
}
instance = js_calloc (vm, 1, sizeof (*instance));
instance->path = js_string_to_c_string (vm, &args[1]);
instance->vm = vm;
js_vm_builtin_create (vm, result_return, builtin_info, instance);
}
/* Delete proc. */
static void
delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
{
FileInstanceCtx *ictx = instance_context;
if (ictx)
{
if (ictx->stream)
{
if (!ictx->dont_close)
{
js_iostream_close (ictx->stream);
JS_VM_FREE_FD (ictx->vm);
}
ictx->stream = NULL;
}
js_free (ictx->path);
js_free (ictx);
}
}
/*
* Global functions.
*/
void
js_builtin_File (JSVirtualMachine *vm)
{
JSNode *n;
JSBuiltinInfo *info;
FileCtx *ctx;
ctx = js_calloc (vm, 1, sizeof (*ctx));
ctx->s_byteToString = js_vm_intern (vm, "byteToString");
ctx->s_chmod = js_vm_intern (vm, "chmod");
ctx->s_lstat = js_vm_intern (vm, "lstat");
ctx->s_remove = js_vm_intern (vm, "remove");
ctx->s_rename = js_vm_intern (vm, "rename");
ctx->s_stat = js_vm_intern (vm, "stat");
ctx->s_stringToByte = js_vm_intern (vm, "stringToByte");
ctx->s_open = js_vm_intern (vm, "open");
ctx->s_close = js_vm_intern (vm, "close");
ctx->s_setPosition = js_vm_intern (vm, "setPosition");
ctx->s_getPosition = js_vm_intern (vm, "getPosition");
ctx->s_eof = js_vm_intern (vm, "eof");
ctx->s_read = js_vm_intern (vm, "read");
ctx->s_readln = js_vm_intern (vm, "readln");
ctx->s_readByte = js_vm_intern (vm, "readByte");
ctx->s_write = js_vm_intern (vm, "write");
ctx->s_writeln = js_vm_intern (vm, "writeln");
ctx->s_writeByte = js_vm_intern (vm, "writeByte");
ctx->s_ungetByte = js_vm_intern (vm, "ungetByte");
ctx->s_flush = js_vm_intern (vm, "flush");
ctx->s_getLength = js_vm_intern (vm, "getLength");
ctx->s_exists = js_vm_intern (vm, "exists");
ctx->s_error = js_vm_intern (vm, "error");
ctx->s_clearError = js_vm_intern (vm, "clearError");
ctx->s_autoFlush = js_vm_intern (vm, "autoFlush");
ctx->s_bufferSize = js_vm_intern (vm, "bufferSize");
/* Object information. */
info = js_vm_builtin_info_create (vm);
info->method_proc = method;
info->property_proc = property;
info->new_proc = new_proc;
info->delete_proc = delete_proc;
info->obj_context = ctx;
info->obj_context_delete = js_free;
/* Define it. */
n = &vm->globals[js_vm_intern (vm, "File")];
js_vm_builtin_create (vm, n, info, NULL);
}
void
js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return,
char *path, JSIOStream *stream, int dont_close)
{
JSNode *n;
FileInstanceCtx *ictx;
/* Lookup our context. */
n = &vm->globals[js_vm_intern (vm, "File")];
/* Create a file instance. */
ictx = js_calloc (vm, 1, sizeof (*ictx));
ictx->path = js_strdup (vm, path);
ictx->stream = stream;
ictx->dont_close = dont_close;
ictx->vm = vm;
/* Create the builtin. */
js_vm_builtin_create (vm, result_return, n->u.vbuiltin->info, ictx);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -