jsfile.c
来自「一个基于alice开发的机器人」· C语言 代码 · 共 2,148 行 · 第 1/5 页
C
2,148 行
{
char *tmp;
char *path = oldpath;
char *base, *dir, *current, *result;
jsint c;
jsint back = 0;
unsigned int i = 0, j = strlen(path)-1;
/* 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 0x2029
static 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 int16
utf8_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 int32
js_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 void
js_ResetBuffers(JSFile * file)
{
file->charBufferUsed = JS_FALSE;
file->nbBytesInBuf = 0;
file->linebuffer = NULL; /* TODO: check for mem. leak? */
}
/* Reset file attributes */
static void
js_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 JSBool
js_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 int32
js_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 int32
js_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:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?