📄 jsfile.c
字号:
SECURITY_CHECK(cx, NULL, "close", file); if(!file->isOpen){ JS_ReportWarning(cx, "File %s is not open, can't close it, proceeding", file->path); goto out; } if(!file->isPipe){ if(file->isNative){ JS_ReportWarning(cx, "Unable to close a native file, proceeding", file->path); goto out; }else{ if(file->handle && PR_Close(file->handle)){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "close", file->path); goto out; } } }else{ if(PCLOSE(file->nativehandle)==-1){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "pclose", file->path); goto out; } } js_ResetAttributes(file); *rval = JSVAL_TRUE; return JS_TRUE;out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); SECURITY_CHECK(cx, NULL, "remove", file); JSFILE_CHECK_NATIVE("remove"); JSFILE_CHECK_CLOSED("remove"); if ((js_isDirectory(cx, file) ? PR_RmDir(file->path) : PR_Delete(file->path))==PR_SUCCESS) { js_ResetAttributes(file); *rval = JSVAL_TRUE; return JS_TRUE; } else { JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "remove", file->path); goto out; }out: *rval = JSVAL_FALSE; return JS_FALSE;}/* Raw PR-based function. No text processing. Just raw data copying. */static JSBoolfile_copyTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); char *dest = NULL; PRFileDesc *handle = NULL; char *buffer; jsval count, size; JSBool fileInitiallyOpen=JS_FALSE; SECURITY_CHECK(cx, NULL, "copyTo", file); /* may need a second argument!*/ JSFILE_CHECK_ONE_ARG("copyTo"); JSFILE_CHECK_NATIVE("copyTo"); /* remeber the state */ fileInitiallyOpen = file->isOpen; JSFILE_CHECK_READ; dest = JS_GetStringBytes(JS_ValueToString(cx, argv[0])); /* make sure we are not reading a file open for writing */ if (file->isOpen && !js_canRead(cx, file)) { JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_CANNOT_COPY_FILE_OPEN_FOR_WRITING_ERROR, file->path); goto out; } if (file->handle==NULL){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "open", file->path); goto out; } handle = PR_Open(dest, PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 0644); if(!handle){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "open", dest); goto out; } if ((size=js_size(cx, file))==JSVAL_VOID) { goto out; } buffer = JS_malloc(cx, size); count = INT_TO_JSVAL(PR_Read(file->handle, buffer, size)); /* reading panic */ if (count!=size) { JS_free(cx, buffer); JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_COPY_READ_ERROR, file->path); goto out; } count = INT_TO_JSVAL(PR_Write(handle, buffer, JSVAL_TO_INT(size))); /* writing panic */ if (count!=size) { JS_free(cx, buffer); JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_COPY_WRITE_ERROR, file->path); goto out; } JS_free(cx, buffer); if(!fileInitiallyOpen){ if(!file_close(cx, obj, 0, NULL, rval)) goto out; } if(PR_Close(handle)!=PR_SUCCESS){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "close", dest); goto out; } *rval = JSVAL_TRUE; return JS_TRUE;out: if(file->isOpen && !fileInitiallyOpen){ if(PR_Close(file->handle)!=PR_SUCCESS){ JS_ReportWarning(cx, "Can't close %s, proceeding", file->path); } } if(handle && PR_Close(handle)!=PR_SUCCESS){ JS_ReportWarning(cx, "Can't close %s, proceeding", dest); } *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_renameTo(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); char *dest; SECURITY_CHECK(cx, NULL, "renameTo", file); /* may need a second argument!*/ JSFILE_CHECK_ONE_ARG("renameTo"); JSFILE_CHECK_NATIVE("renameTo"); JSFILE_CHECK_CLOSED("renameTo"); dest = RESOLVE_PATH(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0]))); if (PR_Rename(file->path, dest)==PR_SUCCESS){ /* copy the new filename */ JS_free(cx, file->path); file->path = dest; *rval = JSVAL_TRUE; return JS_TRUE; }else{ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_RENAME_FAILED, file->path, dest); goto out; }out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); SECURITY_CHECK(cx, NULL, "flush", file); JSFILE_CHECK_NATIVE("flush"); JSFILE_CHECK_OPEN("flush"); if (PR_Sync(file->handle)==PR_SUCCESS){ *rval = JSVAL_TRUE; return JS_TRUE; }else{ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "flush", file->path); goto out; }out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); JSString *str; int32 count; uintN i; SECURITY_CHECK(cx, NULL, "write", file); JSFILE_CHECK_WRITE; for (i = 0; i<argc; i++) { str = JS_ValueToString(cx, argv[i]); count = js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str), file->type); if (count==-1){ *rval = JSVAL_FALSE; return JS_FALSE; } } *rval = JSVAL_TRUE; return JS_TRUE;out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); JSString *str; SECURITY_CHECK(cx, NULL, "writeln", file); JSFILE_CHECK_WRITE; /* don't report an error here */ if(!file_write(cx, obj, argc, argv, rval)) return JS_FALSE; /* don't do security here -- we passed the check in file_write */ str = JS_NewStringCopyZ(cx, "\n"); if (js_FileWrite(cx, file, JS_GetStringChars(str), JS_GetStringLength(str), file->type)==-1){ *rval = JSVAL_FALSE; return JS_FALSE; } /* eol causes flush if hasAutoflush is turned on */ if (file->hasAutoflush) file_flush(cx, obj, 0, NULL, rval); *rval = JSVAL_TRUE; return JS_TRUE;out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_writeAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); jsuint i; jsuint limit; JSObject *array; JSObject *elem; jsval elemval; SECURITY_CHECK(cx, NULL, "writeAll", file); JSFILE_CHECK_ONE_ARG("writeAll"); JSFILE_CHECK_WRITE; if (!JS_IsArrayObject(cx, JSVAL_TO_OBJECT(argv[0]))) { JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_FIRST_ARGUMENT_WRITEALL_NOT_ARRAY_ERROR); goto out; } array = JSVAL_TO_OBJECT(argv[0]); JS_GetArrayLength(cx, array, &limit); for (i = 0; i<limit; i++) { if (!JS_GetElement(cx, array, i, &elemval)) return JS_FALSE; elem = JSVAL_TO_OBJECT(elemval); file_writeln(cx, obj, 1, &elemval, rval); } *rval = JSVAL_TRUE; return JS_TRUE;out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); JSString *str; int32 want, count; jschar *buf; SECURITY_CHECK(cx, NULL, "read", file); JSFILE_CHECK_ONE_ARG("read"); JSFILE_CHECK_READ; if (!JS_ValueToInt32(cx, argv[0], &want)){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_FIRST_ARGUMENT_MUST_BE_A_NUMBER, "read", argv[0]); goto out; } /* want = (want>262144)?262144:want; * arbitrary size limitation */ buf = JS_malloc(cx, want*sizeof buf[0]); if (!buf) goto out; count = js_FileRead(cx, file, buf, want, file->type); if (count>0) { str = JS_NewUCStringCopyN(cx, buf, count); *rval = STRING_TO_JSVAL(str); JS_free(cx, buf); return JS_TRUE; } else { JS_free(cx, buf); goto out; }out: *rval = JSVAL_FALSE; return JS_FALSE;}static JSBoolfile_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); JSString *str; jschar *buf; int32 offset; intN room; jschar data, data2; JSBool endofline; SECURITY_CHECK(cx, NULL, "readln", file); JSFILE_CHECK_READ; if (!file->linebuffer) { buf = JS_malloc(cx, MAX_LINE_LENGTH*(sizeof data)); if (!buf) goto out; file->linebuffer = JS_NewUCString(cx, buf, MAX_LINE_LENGTH); } room = JS_GetStringLength(file->linebuffer); offset = 0; /* XXX TEST ME!! TODO: yes, please do */ for(;;) { if (!js_FileRead(cx, file, &data, 1, file->type)) { endofline = JS_FALSE; goto loop; } switch (data) { case '\n' : endofline = JS_TRUE; goto loop; case '\r' : if (!js_FileRead(cx, file, &data2, 1, file->type)) { endofline = JS_TRUE; goto loop; } if (data2!='\n') { /* We read one char too far. Buffer it. */ file->charBuffer = data2; file->charBufferUsed = JS_TRUE; } endofline = JS_TRUE; goto loop; default: if (--room < 0) { buf = JS_malloc(cx, (offset+MAX_LINE_LENGTH)*sizeof data); if (!buf) return JS_FALSE; room = MAX_LINE_LENGTH-1; memcpy(buf, JS_GetStringChars(file->linebuffer), JS_GetStringLength(file->linebuffer)); /* what follows may not be the cleanest way. */ file->linebuffer->chars = buf; file->linebuffer->length = offset+MAX_LINE_LENGTH; } file->linebuffer->chars[offset++] = data; break; } }loop: file->linebuffer->chars[offset] = 0; if ((endofline==JS_TRUE)) { str = JS_NewUCStringCopyN(cx, JS_GetStringChars(file->linebuffer), offset); *rval = STRING_TO_JSVAL(str); return JS_TRUE; }else{ goto out; }out: *rval = JSVAL_NULL; return JS_FALSE;}static JSBoolfile_readAll(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval){ JSFile *file = JS_GetInstancePrivate(cx, obj, &file_class, NULL); JSObject *array; jsint len; jsval line; SECURITY_CHECK(cx, NULL, "readAll", file); JSFILE_CHECK_READ; array = JS_NewArrayObject(cx, 0, NULL); len = 0; while(file_readln(cx, obj, 0, NULL, &line)){ JS_SetElement(cx, array, len, &line); len++; } *rval = OBJECT_TO_JSVAL(array); return JS_TRUE;out:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -