📄 bdflib.c
字号:
unsigned long n ) { unsigned long i, u; if ( list == 0 || list->used == 0 || n == 0 ) return; if ( n >= list->used ) { list->used = 0; return; } for ( u = n, i = 0; u < list->used; i++, u++ ) list->field[i] = list->field[u]; list->used -= n; } static char * _bdf_list_join( _bdf_list_t* list, int c, unsigned long *alen ) { unsigned long i, j; char *fp, *dp; *alen = 0; if ( list == 0 || list->used == 0 ) return 0; dp = list->field[0]; for ( i = j = 0; i < list->used; i++ ) { fp = list->field[i]; while ( *fp ) dp[j++] = *fp++; if ( i + 1 < list->used ) dp[j++] = (char)c; } dp[j] = 0; *alen = j; return dp; } /* An empty string for empty fields. */ static const char empty[1] = { 0 }; /* XXX eliminate this */ static FT_Error _bdf_list_split( _bdf_list_t* list, char* separators, char* line, unsigned long linelen ) { int mult, final_empty; char *sp, *ep, *end; char seps[32]; FT_Error error = BDF_Err_Ok; /* Initialize the list. */ list->used = 0; /* If the line is empty, then simply return. */ if ( linelen == 0 || line[0] == 0 ) goto Exit; /* In the original code, if the `separators' parameter is NULL or */ /* empty, the list is split into individual bytes. We don't need */ /* this, so an error is signaled. */ if ( separators == 0 || *separators == 0 ) { error = BDF_Err_Invalid_Argument; goto Exit; } /* Prepare the separator bitmap. */ FT_MEM_ZERO( seps, 32 ); /* If the very last character of the separator string is a plus, then */ /* set the `mult' flag to indicate that multiple separators should be */ /* collapsed into one. */ for ( mult = 0, sp = separators; sp && *sp; sp++ ) { if ( *sp == '+' && *( sp + 1 ) == 0 ) mult = 1; else setsbit( seps, *sp ); } /* Break the line up into fields. */ for ( final_empty = 0, sp = ep = line, end = sp + linelen; sp < end && *sp; ) { /* Collect everything that is not a separator. */ for ( ; *ep && !sbitset( seps, *ep ); ep++ ) ; /* Resize the list if necessary. */ if ( list->used == list->size ) { error = _bdf_list_ensure( list, list->used + 1 ); if ( error ) goto Exit; } /* Assign the field appropriately. */ list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; sp = ep; if ( mult ) { /* If multiple separators should be collapsed, do it now by */ /* setting all the separator characters to 0. */ for ( ; *ep && sbitset( seps, *ep ); ep++ ) *ep = 0; } else if ( *ep != 0 ) /* Don't collapse multiple separators by making them 0, so just */ /* make the one encountered 0. */ *ep++ = 0; final_empty = ( ep > sp && *ep == 0 ); sp = ep; } /* Finally, NULL-terminate the list. */ if ( list->used + final_empty >= list->size ) { error = _bdf_list_ensure( list, list->used + final_empty + 1 ); if ( error ) goto Exit; } if ( final_empty ) list->field[list->used++] = (char*)empty; list->field[list->used] = 0; Exit: return error; }#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ static FT_Error _bdf_readstream( FT_Stream stream, _bdf_line_func_t callback, void* client_data, unsigned long *lno ) { _bdf_line_func_t cb; unsigned long lineno, buf_size; int refill, bytes, hold, to_skip; int start, end, cursor, avail; char* buf = 0; FT_Memory memory = stream->memory; FT_Error error = BDF_Err_Ok; if ( callback == 0 ) { error = BDF_Err_Invalid_Argument; goto Exit; } /* initial size and allocation of the input buffer */ buf_size = 1024; if ( FT_NEW_ARRAY( buf, buf_size ) ) goto Exit; cb = callback; lineno = 1; buf[0] = 0; start = 0; end = 0; avail = 0; cursor = 0; refill = 1; to_skip = NO_SKIP; bytes = 0; /* make compiler happy */ for (;;) { if ( refill ) { bytes = (int)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, (FT_ULong)(buf_size - cursor) ); avail = cursor + bytes; cursor = 0; refill = 0; } end = start; /* should we skip an optional character like \n or \r? */ if ( start < avail && buf[start] == to_skip ) { start += 1; to_skip = NO_SKIP; continue; } /* try to find the end of the line */ while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) end++; /* if we hit the end of the buffer, try shifting its content */ /* or even resizing it */ if ( end >= avail ) { if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ break; /* ignore it then exit */ if ( start == 0 ) { /* this line is definitely too long; try resizing the input */ /* buffer a bit to handle it. */ FT_ULong new_size; if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ { error = BDF_Err_Invalid_Argument; goto Exit; } new_size = buf_size * 2; if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) goto Exit; cursor = buf_size; buf_size = new_size; } else { bytes = avail - start; FT_MEM_COPY( buf, buf + start, bytes ); cursor = bytes; avail -= bytes; start = 0; } refill = 1; continue; } /* Temporarily NUL-terminate the line. */ hold = buf[end]; buf[end] = 0; /* XXX: Use encoding independent value for 0x1a */ if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) { error = (*cb)( buf + start, end - start, lineno, (void*)&cb, client_data ); if ( error ) break; } lineno += 1; buf[end] = (char)hold; start = end + 1; if ( hold == '\n' ) to_skip = '\r'; else if ( hold == '\r' ) to_skip = '\n'; else to_skip = NO_SKIP; } *lno = lineno; Exit: FT_FREE( buf ); return error; } /* XXX: make this work with EBCDIC also */ static const unsigned char a2i[128] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char odigits[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const unsigned char ddigits[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static const unsigned char hdigits[32] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x7e, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };#define isdigok( m, d ) (m[(d) >> 3] & ( 1 << ( (d) & 7 ) ) ) /* Routine to convert an ASCII string into an unsigned long integer. */ static unsigned long _bdf_atoul( char* s, char** end, int base ) { unsigned long v; const unsigned char* dmap; if ( s == 0 || *s == 0 ) return 0; /* Make sure the radix is something recognizable. Default to 10. */ switch ( base ) { case 8: dmap = odigits; break; case 16: dmap = hdigits; break; default: base = 10; dmap = ddigits; break; } /* Check for the special hex prefix. */ if ( *s == '0' && ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) { base = 16; dmap = hdigits; s += 2; } for ( v = 0; isdigok( dmap, *s ); s++ ) v = v * base + a2i[(int)*s]; if ( end != 0 ) *end = s; return v; } /* Routine to convert an ASCII string into an signed long integer. */ static long _bdf_atol( char* s, char** end, int base ) { long v, neg; const unsigned char* dmap; if ( s == 0 || *s == 0 ) return 0; /* Make sure the radix is something recognizable. Default to 10. */ switch ( base ) { case 8: dmap = odigits; break; case 16: dmap = hdigits; break; default: base = 10; dmap = ddigits; break; } /* Check for a minus sign. */ neg = 0; if ( *s == '-' ) { s++; neg = 1; } /* Check for the special hex prefix. */ if ( *s == '0' && ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) ) { base = 16; dmap = hdigits; s += 2; } for ( v = 0; isdigok( dmap, *s ); s++ ) v = v * base + a2i[(int)*s]; if ( end != 0 ) *end = s; return ( !neg ) ? v : -v; } /* Routine to convert an ASCII string into an signed short integer. */ static short _bdf_atos( char* s, char** end, int base ) { short v, neg; const unsigned char* dmap; if ( s == 0 || *s == 0 ) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -