📄 bdflib.c
字号:
/* Resize the list if necessary. */ if ( list->used == list->size ) { if ( list->size == 0 ) { if ( FT_NEW_ARRAY( list->field, 5 ) ) goto Exit; } else { if ( FT_RENEW_ARRAY ( list->field , list->size, list->size + 5 ) ) goto Exit; } list->size += 5; } /* Assign the field appropriately. */ list->field[list->used++] = ( ep > sp ) ? sp : 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 + 1 >= list->size ) { if ( list->used == list->size ) { if ( list->size == 0 ) { if ( FT_NEW_ARRAY( list->field, 5 ) ) goto Exit; } else { if ( FT_RENEW_ARRAY( list->field, list->size, list->size + 5 ) ) goto Exit; } list->size += 5; } } if ( final_empty ) list->field[list->used++] = empty; if ( list->used == list->size ) { if ( list->size == 0 ) { if ( FT_NEW_ARRAY( list->field, 5 ) ) goto Exit; } else { if ( FT_RENEW_ARRAY( list->field, list->size, list->size + 5 ) ) goto Exit; } list->size += 5; } list->field[list->used] = 0; Exit: return error; } static void _bdf_shift( unsigned long n, _bdf_list_t* list ) { 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_join( int c, unsigned long* len, _bdf_list_t* list ) { unsigned long i, j; char *fp, *dp; if ( list == 0 || list->used == 0 ) return 0; *len = 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; *len = j; return dp; } /* High speed file reader that passes each line to a callback. */ static FT_Error bdf_internal_readstream( FT_Stream stream, char* buffer, int count, int *read_bytes ) { int rbytes; unsigned long pos = stream->pos; FT_Error error = BDF_Err_Ok; if ( pos > stream->size ) { FT_ERROR(( "bdf_internal_readstream:" )); FT_ERROR(( " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); error = BDF_Err_Invalid_Stream_Operation; goto Exit; } if ( stream->read ) rbytes = stream->read( stream, pos, (unsigned char *)buffer, count ); else { rbytes = stream->size - pos; if ( rbytes > count ) rbytes = count; FT_MEM_COPY( buffer, stream->base + pos, rbytes ); } stream->pos = pos + rbytes; *read_bytes = rbytes; Exit: return error; } 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; int n, done, refill, bytes, hold; char *ls, *le, *pp, *pe, *hp; char *buf = 0; FT_Memory memory = stream->memory; FT_Error error = BDF_Err_Ok; if ( callback == 0 ) { error = BDF_Err_Invalid_Argument; goto Exit; } if ( FT_NEW_ARRAY( buf, 65536L ) ) goto Exit; cb = callback; lineno = 1; buf[0] = 0; done = 0; pp = ls = le = buf; bytes = 65536L; while ( !done ) { error = bdf_internal_readstream( stream, pp, bytes, &n ); if ( error ) goto Exit; if ( n == 0 ) break; /* Determine the new end of the buffer pages. */ pe = pp + n; for ( refill = 0; done == 0 && refill == 0; ) { while ( le < pe && *le != '\n' && *le != '\r' ) le++; if ( le == pe ) { /* Hit the end of the last page in the buffer. Need to find */ /* out how many pages to shift and how many pages need to be */ /* read in. Adjust the line start and end pointers down to */ /* point to the right places in the pages. */ pp = buf + ( ( ( ls - buf ) >> 13 ) << 13 ); n = pp - buf; ls -= n; le -= n; n = pe - pp; FT_MEM_MOVE( buf, pp, n ); pp = buf + n; bytes = 65536L - n; refill = 1; } else { /* Temporarily NULL-terminate the line. */ hp = le; hold = *le; *le = 0; /* XXX: Use encoding independent value for 0x1a */ if ( *ls != '#' && *ls != 0x1a && le > ls && ( error = (*cb)( ls, le - ls, lineno, (void *)&cb, client_data ) ) != BDF_Err_Ok ) done = 1; else { ls = ++le; /* Handle the case of DOS crlf sequences. */ if ( le < pe && hold == '\n' && *le =='\r' ) ls = ++le; } /* Increment the line number. */ lineno++; /* Restore the character at the end of the line. */ *hp = (char)hold; } } } *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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -