📄 jsfile.c
字号:
/* This is probably optional */ /* Remove possible spaces in the beginning and end */ while(i<strlen(path)-1 && path[i]==' ') i++; while(j>=0 && path[j]==' ') j--; tmp = JS_malloc(cx, j-i+2); strncpy(tmp, &path[i], j-i+1); tmp[j-i+1] = '\0'; path = tmp; /* pipe support */ if(js_filenameHasAPipe(path)) return JS_strdup(cx, path); /* file:// support */ if(!strncmp(path, URL_PREFIX, strlen(URL_PREFIX))) return js_canonicalPath(cx, &path[strlen(URL_PREFIX)-1]); if (!js_isAbsolute(path)) path = js_absolutePath(cx, path); else path = JS_strdup(cx, path); result = JS_strdup(cx, ""); current = path; base = js_fileBaseName(cx, current); dir = js_fileDirectoryName(cx, current); /* TODO: MAC -- not going to work??? */ while (strcmp(dir, current)) { if (!strcmp(base, "..")) { back++; } else if(!strcmp(base, ".")){ /* ??? */ } else { if (back>0) back--; else { tmp = result; result = JS_malloc(cx, strlen(base)+1+strlen(tmp)+1); if (!result) { JS_free(cx, dir); JS_free(cx, base); JS_free(cx, current); return NULL; } strcpy(result, base); c = strlen(result); if (*tmp) { result[c] = FILESEPARATOR; result[c+1] = '\0'; strcat(result, tmp); } JS_free(cx, tmp); } } JS_free(cx, current); JS_free(cx, base); current = dir; base = js_fileBaseName(cx, current); dir = js_fileDirectoryName(cx, current); } tmp = result; result = JS_malloc(cx, strlen(dir)+1+strlen(tmp)+1); if (!result) { JS_free(cx, dir); JS_free(cx, base); JS_free(cx, current); return NULL; } strcpy(result, dir); c = strlen(result); if (tmp[0]!='\0') { if ((result[c-1]!=FILESEPARATOR)&&(result[c-1]!=FILESEPARATOR2)) { result[c] = FILESEPARATOR; result[c+1] = '\0'; } strcat(result, tmp); } JS_free(cx, tmp); JS_free(cx, dir); JS_free(cx, base); JS_free(cx, current); return result;}/* -------------------------- Text conversion ------------------------------- *//* The following is ripped from libi18n/unicvt.c and include files.. *//* * UTF8 defines and macros */#define ONE_OCTET_BASE 0x00 /* 0xxxxxxx */#define ONE_OCTET_MASK 0x7F /* x1111111 */#define CONTINUING_OCTET_BASE 0x80 /* 10xxxxxx */#define CONTINUING_OCTET_MASK 0x3F /* 00111111 */#define TWO_OCTET_BASE 0xC0 /* 110xxxxx */#define TWO_OCTET_MASK 0x1F /* 00011111 */#define THREE_OCTET_BASE 0xE0 /* 1110xxxx */#define THREE_OCTET_MASK 0x0F /* 00001111 */#define FOUR_OCTET_BASE 0xF0 /* 11110xxx */#define FOUR_OCTET_MASK 0x07 /* 00000111 */#define FIVE_OCTET_BASE 0xF8 /* 111110xx */#define FIVE_OCTET_MASK 0x03 /* 00000011 */#define SIX_OCTET_BASE 0xFC /* 1111110x */#define SIX_OCTET_MASK 0x01 /* 00000001 */#define IS_UTF8_1ST_OF_1(x) (( (x)&~ONE_OCTET_MASK ) == ONE_OCTET_BASE)#define IS_UTF8_1ST_OF_2(x) (( (x)&~TWO_OCTET_MASK ) == TWO_OCTET_BASE)#define IS_UTF8_1ST_OF_3(x) (( (x)&~THREE_OCTET_MASK) == THREE_OCTET_BASE)#define IS_UTF8_1ST_OF_4(x) (( (x)&~FOUR_OCTET_MASK ) == FOUR_OCTET_BASE)#define IS_UTF8_1ST_OF_5(x) (( (x)&~FIVE_OCTET_MASK ) == FIVE_OCTET_BASE)#define IS_UTF8_1ST_OF_6(x) (( (x)&~SIX_OCTET_MASK ) == SIX_OCTET_BASE)#define IS_UTF8_2ND_THRU_6TH(x) \ (( (x)&~CONTINUING_OCTET_MASK ) == CONTINUING_OCTET_BASE)#define IS_UTF8_1ST_OF_UCS2(x) \ IS_UTF8_1ST_OF_1(x) \ || IS_UTF8_1ST_OF_2(x) \ || IS_UTF8_1ST_OF_3(x)#define MAX_UCS2 0xFFFF#define DEFAULT_CHAR 0x003F /* Default char is "?" */#define BYTE_MASK 0xBF#define BYTE_MARK 0x80/* Function: one_ucs2_to_utf8_char * * Function takes one UCS-2 char and writes it to a UTF-8 buffer. * We need a UTF-8 buffer because we don't know before this * function how many bytes of utf-8 data will be written. It also * takes a pointer to the end of the UTF-8 buffer so that we don't * overwrite data. This function returns the number of UTF-8 bytes * of data written, or -1 if the buffer would have been overrun. */#define LINE_SEPARATOR 0x2028#define PARAGRAPH_SEPARATOR 0x2029static int16 one_ucs2_to_utf8_char(unsigned char *tobufp, unsigned char *tobufendp, uint16 onechar){ int16 numUTF8bytes = 0; if((onechar == LINE_SEPARATOR)||(onechar == PARAGRAPH_SEPARATOR)) { strcpy((char*)tobufp, "\n"); return strlen((char*)tobufp);; } if (onechar < 0x80) { numUTF8bytes = 1; } else if (onechar < 0x800) { numUTF8bytes = 2; } else if (onechar <= MAX_UCS2) { numUTF8bytes = 3; } else { numUTF8bytes = 2; onechar = DEFAULT_CHAR; } tobufp += numUTF8bytes; /* return error if we don't have space for the whole character */ if (tobufp > tobufendp) { return(-1); } switch(numUTF8bytes) { case 3: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; *--tobufp = onechar | THREE_OCTET_BASE; break; case 2: *--tobufp = (onechar | BYTE_MARK) & BYTE_MASK; onechar >>=6; *--tobufp = onechar | TWO_OCTET_BASE; break; case 1: *--tobufp = (unsigned char)onechar; break; } return(numUTF8bytes);}/* * utf8_to_ucs2_char * * Convert a utf8 multibyte character to ucs2 * * inputs: pointer to utf8 character(s) * length of utf8 buffer ("read" length limit) * pointer to return ucs2 character * * outputs: number of bytes in the utf8 character * -1 if not a valid utf8 character sequence * -2 if the buffer is too short */static int16utf8_to_ucs2_char(const unsigned char *utf8p, int16 buflen, uint16 *ucs2p){ uint16 lead, cont1, cont2; /* * Check for minimum buffer length */ if ((buflen < 1) || (utf8p == NULL)) { return -2; } lead = (uint16) (*utf8p); /* * Check for a one octet sequence */ if (IS_UTF8_1ST_OF_1(lead)) { *ucs2p = lead & ONE_OCTET_MASK; return 1; } /* * Check for a two octet sequence */ if (IS_UTF8_1ST_OF_2(*utf8p)) { if (buflen < 2) return -2; cont1 = (uint16) *(utf8p+1); if (!IS_UTF8_2ND_THRU_6TH(cont1)) return -1; *ucs2p = (lead & TWO_OCTET_MASK) << 6; *ucs2p |= cont1 & CONTINUING_OCTET_MASK; return 2; } /* * Check for a three octet sequence */ else if (IS_UTF8_1ST_OF_3(lead)) { if (buflen < 3) return -2; cont1 = (uint16) *(utf8p+1); cont2 = (uint16) *(utf8p+2); if ( (!IS_UTF8_2ND_THRU_6TH(cont1)) || (!IS_UTF8_2ND_THRU_6TH(cont2))) return -1; *ucs2p = (lead & THREE_OCTET_MASK) << 12; *ucs2p |= (cont1 & CONTINUING_OCTET_MASK) << 6; *ucs2p |= cont2 & CONTINUING_OCTET_MASK; return 3; } else { /* not a valid utf8/ucs2 character */ return -1; }}/* ----------------------------- Helper functions --------------------------- *//* Ripped off from lm_win.c .. *//* where is strcasecmp?.. for now, it's case sensitive.. * * strcasecmp is in strings.h, but on windows it's called _stricmp... * will need to #ifdef this*/static int32js_FileHasOption(JSContext *cx, const char *oldoptions, const char *name){ char *comma, *equal, *current; char *options = JS_strdup(cx, oldoptions); int32 found = 0; current = options; for (;;) { comma = strchr(current, ','); if (comma) *comma = '\0'; equal = strchr(current, '='); if (equal) *equal = '\0'; if (strcmp(current, name) == 0) { if (!equal || strcmp(equal + 1, "yes") == 0) found = 1; else found = atoi(equal + 1); } if (equal) *equal = '='; if (comma) *comma = ','; if (found || !comma) break; current = comma + 1; } JS_free(cx, options); return found;}/* empty the buffer */static voidjs_ResetBuffers(JSFile * file){ file->charBufferUsed = JS_FALSE; file->nbBytesInBuf = 0; file->linebuffer = NULL; /* TODO: check for mem. leak? */}/* Reset file attributes */static voidjs_ResetAttributes(JSFile * file){ file->mode = file->type = 0; file->isOpen = JS_FALSE; file->handle = NULL; file->nativehandle = NULL; file->hasRandomAccess = JS_TRUE; /* innocent until proven guilty */ file->hasAutoflush = JS_FALSE; file->isNative = JS_FALSE; file->isPipe = JS_FALSE; js_ResetBuffers(file);}static JSBooljs_FileOpen(JSContext *cx, JSObject *obj, JSFile *file, char *mode){ JSString *type, *mask; jsval v[2]; jsval rval; type = JS_InternString(cx, asciistring); mask = JS_NewStringCopyZ(cx, mode); v[0] = STRING_TO_JSVAL(mask); v[1] = STRING_TO_JSVAL(type); if (!file_open(cx, obj, 2, v, &rval)) { return JS_FALSE; } return JS_TRUE;}/* Buffered version of PR_Read. Used by js_FileRead */static int32js_BufferedRead(JSFile * f, char *buf, int32 len){ int32 count = 0; while (f->nbBytesInBuf>0&&len>0) { buf[0] = f->byteBuffer[0]; f->byteBuffer[0] = f->byteBuffer[1]; f->byteBuffer[1] = f->byteBuffer[2]; f->nbBytesInBuf--; len--; buf+=1; count++; } if (len>0) { count+= (!f->isNative)? PR_Read(f->handle, buf, len): fread(buf, 1, len, f->nativehandle); } return count;}static int32js_FileRead(JSContext *cx, JSFile * file, jschar*buf, int32 len, int32 mode){ unsigned char*aux; int32 count, i; jsint remainder; unsigned char utfbuf[3]; if (file->charBufferUsed) { buf[0] = file->charBuffer; buf++; len--; file->charBufferUsed = JS_FALSE; } switch (mode) { case ASCII: aux = (unsigned char*)JS_malloc(cx, len); if (!aux) { return 0; } count = js_BufferedRead(file, aux, len); if (count==-1) { JS_free(cx, aux); return 0; } for (i = 0;i<len;i++) { buf[i] = (jschar)aux[i]; } JS_free(cx, aux); break; case UTF8: remainder = 0; for (count = 0;count<len;count++) { i = js_BufferedRead(file, utfbuf+remainder, 3-remainder); if (i<=0) { return count; } i = utf8_to_ucs2_char(utfbuf, (int16)i, &buf[count] ); if (i<0) { return count; } else { if (i==1) { utfbuf[0] = utfbuf[1]; utfbuf[1] = utfbuf[2]; remainder = 2; } else if (i==2) { utfbuf[0] = utfbuf[2]; remainder = 1; } else if (i==3) remainder = 0; } } while (remainder>0) { file->byteBuffer[file->nbBytesInBuf] = utfbuf[0]; file->nbBytesInBuf++; utfbuf[0] = utfbuf[1]; utfbuf[1] = utfbuf[2]; remainder--; } break; case UCS2: count = js_BufferedRead(file, (char*)buf, len*2)>>1; if (count==-1) { return 0; } break; } if(count==-1){ JS_ReportErrorNumber(cx, JSFile_GetErrorMessage, NULL, JSFILEMSG_OP_FAILED, "read", file->path); } return count;}static int32
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -