📄 b_file.c
字号:
/*
* The builtin File object.
* Copyright (c) 1998-1999 New Generation Software (NGS) Oy
*
* Author: Markku Rossi <mtr@ngs.fi>
*/
/*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*/
/*
* $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/ksrc/b_file.c,v $
* $Id: b_file.c 21681 2006-04-21 15:00:24Z peterw $
*/
/*
* Static methods.
*
* byteToString (BYTE) => string
* + chmod (string, int) => boolean
* + lstat (PATH) => array / boolean
* + remove (PATH) => boolean
* + rename (FROM, TO) => boolean
* + stat (PATH) => array / boolean
* stringToByte (STRING) => number
*
* Methods:
*
* open (MODE) => boolean
* close () => boolean
* setPosition (POSITION [, WHENCE]) => boolean
* getPosition () => integer
* eof () => boolean
* read (SIZE) => string
* readln () => string
* readByte () => integer
* write (STRING) => boolean
* writeln (STRING) => boolean
* writeByte (INTEGER) => boolean
* + ungetByte (BYTE) => boolean
* flush () => boolean
* getLength () => integer
* exists () => boolean
* error () => integer
* clearError () => true
*
* Properties:
*
* autoFlush boolean mutable
* bufferSize integer mutable
*/
#include "jsint.h"
#include <sys/stat.h>
/*
* Types and definitions.
*/
#define INSECURE() \
do { \
if (secure_mode) \
goto insecure_feature; \
} while (0)
/* Class context. */
struct file_ctx_st
{
/* Static methods. */
JSSymbol s_byteToString;
JSSymbol s_chmod;
JSSymbol s_lstat;
JSSymbol s_remove;
JSSymbol s_rename;
JSSymbol s_stat;
JSSymbol s_stringToByte;
/* Methods */
JSSymbol s_open;
JSSymbol s_close;
JSSymbol s_setPosition;
JSSymbol s_getPosition;
JSSymbol s_eof;
JSSymbol s_read;
JSSymbol s_readln;
JSSymbol s_readByte;
JSSymbol s_write;
JSSymbol s_writeln;
JSSymbol s_writeByte;
JSSymbol s_ungetByte;
JSSymbol s_flush;
JSSymbol s_getLength;
JSSymbol s_exists;
JSSymbol s_error;
JSSymbol s_clearError;
/* Properties. */
JSSymbol s_autoFlush;
JSSymbol s_bufferSize;
};
typedef struct file_ctx_st FileCtx;
/* Instance context. */
struct file_instance_ctx_st
{
/* Flags. */
unsigned int dont_close : 1;
char *path;
JSIOStream *stream;
/* Needed for the delete_proc. */
JSVirtualMachine *vm;
};
typedef struct file_instance_ctx_st FileInstanceCtx;
/*
* Static functions.
*/
/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
void *instance_context, JSSymbol method, JSNode *result_return,
JSNode *args)
{
FileCtx *ctx = builtin_info->obj_context;
FileInstanceCtx *ictx = instance_context;
char buf[256];
long int li = 0;
int i = 0;
/* char *cp; */
int secure_mode = vm->security & JS_VM_SECURE_FILE;
/* The default result is false. */
result_return->type = JS_BOOLEAN;
result_return->u.vboolean = 0;
/*
* Static methods.
*/
if (method == ctx->s_byteToString)
{
if (args->u.vinteger != 1)
goto argument_error;
i = -1;
if (args[1].type == JS_INTEGER)
{
i = args[1].u.vinteger;
if (i < 0 || i > 255)
i = -1;
}
js_vm_make_string (vm, result_return, NULL, 1);
if (i < 0)
result_return->u.vstring->len = 0;
else
result_return->u.vstring->data[0] = i;
}
/* ********************************************************************** */
else if (method == ctx->s_chmod)
{
#if 0
INSECURE ();
if (args->u.vinteger != 2)
goto argument_error;
if (args[1].type != JS_STRING)
goto argument_type_error;
if (args[2].type != JS_INTEGER)
goto argument_type_error;
result_return->type= JS_BOOLEAN;
cp = js_string_to_c_string (vm, &args[1]);
result_return->u.vboolean = (chmod (cp, args[2].u.vinteger) == 0);
js_free (cp);
#endif
}
/* ********************************************************************** */
else if (method == ctx->s_lstat || method == ctx->s_stat)
{
#if 0
char *path;
struct stat stat_st;
int result;
INSECURE ();
if (args->u.vinteger != 1)
goto argument_error;
path = js_string_to_c_string (vm, &args[1]);
#if HAVE_LSTAT
if (method == ctx->s_lstat)
result = lstat (path, &stat_st);
else
#endif /* HAVE_LSTAT */
result = stat (path, &stat_st);
js_free (path);
if (result >= 0)
{
JSNode *node;
/* Success. */
js_vm_make_array (vm, result_return, 13);
node = result_return->u.varray->data;
/* dev */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_dev;
node++;
/* ino */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_ino;
node++;
/* mode */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_mode;
node++;
/* nlink */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_nlink;
node++;
/* uid */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_uid;
node++;
/* gid */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_gid;
node++;
/* rdev */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_rdev;
node++;
/* size */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_size;
node++;
/* atime */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_atime;
node++;
/* mtime */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_mtime;
node++;
/* ctime */
node->type = JS_INTEGER;
node->u.vinteger = stat_st.st_ctime;
node++;
/* blksize */
node->type = JS_INTEGER;
#if HAVE_STAT_ST_ST_BLKSIZE
node->u.vinteger = stat_st.st_blksize;
#else /* not HAVE_STAT_ST_ST_BLKSIZE */
node->u.vinteger = 0;
#endif /* not HAVE_STAT_ST_ST_BLKSIZE */
node++;
/* blocks */
node->type = JS_INTEGER;
#if HAVE_STAT_ST_ST_BLOCKS
node->u.vinteger = stat_st.st_blocks;
#else /* not HAVE_STAT_ST_ST_BLOCKS */
node->u.vinteger = 0;
#endif /* not HAVE_STAT_ST_ST_BLOCKS */
}
#endif
}
/* ********************************************************************** */
else if (method == ctx->s_remove)
{
#if 0
char *path;
INSECURE ();
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_STRING)
goto argument_type_error;
path = js_string_to_c_string (vm, &args[1]);
i = remove (path);
js_free (path);
result_return->u.vboolean = (i == 0);
#endif
}
/* ********************************************************************** */
else if (method == ctx->s_rename)
{
#if 0
char *path1;
char *path2;
INSECURE ();
if (args->u.vinteger != 2)
goto argument_error;
if (args[1].type != JS_STRING || args[2].type != JS_STRING)
goto argument_type_error;
path1 = js_string_to_c_string (vm, &args[1]);
path2 = js_string_to_c_string (vm, &args[2]);
i = rename (path1, path2);
js_free (path1);
js_free (path2);
result_return->u.vboolean = (i == 0);
#endif
}
/* ********************************************************************** */
else if (method == ctx->s_stringToByte)
{
if (args->u.vinteger != 1)
goto argument_error;
result_return->type = JS_INTEGER;
if (args[1].type == JS_STRING && args[1].u.vstring->len > 0)
result_return->u.vinteger = args[i].u.vstring->data[0];
else
result_return->u.vinteger = 0;
}
/* ********************************************************************** */
else if (method == vm->syms.s_toString)
{
if (args->u.vinteger != 0)
goto argument_error;
if (ictx)
js_vm_make_string (vm, result_return, ictx->path, strlen (ictx->path));
else
js_vm_make_static_string (vm, result_return, "File", 4);
}
/* ********************************************************************** */
else if (ictx)
{
/*
* Instance methods.
*/
if (method == ctx->s_open)
{
int readp = 0;
int writep = 0;
INSECURE ();
if (args->u.vinteger != 1)
goto argument_error;
if (args[1].type != JS_STRING
|| args[1].u.vstring->len == 0
|| args[1].u.vstring->len > 3)
goto argument_type_error;
i = args[1].u.vstring->len;
memcpy (buf, args[1].u.vstring->data, i);
if (buf[i - 1] != 'b')
buf[i++] = 'b';
buf[i] = '\0';
/* Check that the mode is valid. */
if (strcmp (buf, "rb") == 0)
readp = 1;
else if (strcmp (buf, "wb") == 0)
writep = 1;
else if (strcmp (buf, "ab") == 0)
writep = 1;
else if (strcmp (buf, "r+b") == 0)
readp = writep = 1;
else if (strcmp (buf, "w+b") == 0)
readp = writep = 1;
else if (strcmp (buf, "a+b") == 0)
readp = writep = 1;
else
{
sprintf (vm->error, "File.%s(): illegal open mode \"%s\"",
js_vm_symname (vm, method), buf);
js_vm_error (vm);
}
if (ictx->stream == NULL)
{
#if 0
/* Do open. */
JS_VM_ALLOCATE_FD (vm, "File.open()");
ictx->stream = js_iostream_file (fopen (ictx->path, buf), readp,
writep, 1);
if (ictx->stream == NULL)
JS_VM_FREE_FD (vm);
else
result_return->u.vboolean = 1;
#endif
}
}
/* ***************************************************************** */
else if (method == ctx->s_close)
{
if (ictx->stream != NULL)
{
int result = 0;
if (!ictx->dont_close)
{
result = js_iostream_close (ictx->stream);
JS_VM_FREE_FD (vm);
}
ictx->stream = NULL;
result_return->u.vboolean = result >= 0;
}
}
/* ***************************************************************** */
else if (method == ctx->s_setPosition)
{
if (args->u.vinteger == 1)
{
if (args[1].type != JS_INTEGER)
goto argument_type_error;
li = args[1].u.vinteger;
i = SEEK_SET;
}
else if (args->u.vinteger == 2)
{
if (args[2].type == JS_INTEGER)
{
switch (args[2].u.vinteger)
{
case 1:
i = SEEK_CUR;
break;
case 2:
i = SEEK_END;
break;
default:
i = SEEK_SET;
break;
}
}
else
i = SEEK_SET;
}
else
goto argument_error;
if (ictx->stream && js_iostream_seek (ictx->stream, li, i) >= 0)
result_return->u.vboolean = 1;
}
/* ***************************************************************** */
else if (method == ctx->s_getPosition)
{
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
= js_iostream_get_position (ictx->stream);
}
/* ***************************************************************** */
else if (method == ctx->s_eof)
{
if (args->u.vinteger != 0)
goto argument_error;
if (ictx->stream != NULL)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -