1 |
/* |
/* |
2 |
* Copyright 2000 Computing Research Labs, New Mexico State University |
* Copyright 2000 Computing Research Labs, New Mexico State University |
3 |
* Copyright 2001, 2002, 2003, 2004 Francesco Zappa Nardelli |
* Copyright 2001, 2002, 2003, 2004, 2005 Francesco Zappa Nardelli |
4 |
* |
* |
5 |
* Permission is hereby granted, free of charge, to any person obtaining a |
* Permission is hereby granted, free of charge, to any person obtaining a |
6 |
* copy of this software and associated documentation files (the "Software"), |
* copy of this software and associated documentation files (the "Software"), |
392 |
_bdf_list_init( _bdf_list_t* list, |
_bdf_list_init( _bdf_list_t* list, |
393 |
FT_Memory memory ) |
FT_Memory memory ) |
394 |
{ |
{ |
395 |
FT_ZERO(list); |
FT_ZERO( list ); |
396 |
list->memory = memory; |
list->memory = memory; |
397 |
} |
} |
398 |
|
|
399 |
|
|
400 |
static void |
static void |
401 |
_bdf_list_done( _bdf_list_t* list ) |
_bdf_list_done( _bdf_list_t* list ) |
402 |
{ |
{ |
403 |
FT_Memory memory = list->memory; |
FT_Memory memory = list->memory; |
404 |
|
|
405 |
|
|
406 |
if ( memory ) |
if ( memory ) |
407 |
{ |
{ |
408 |
FT_FREE( list->field ); |
FT_FREE( list->field ); |
409 |
FT_ZERO(list); |
FT_ZERO( list ); |
410 |
} |
} |
411 |
} |
} |
412 |
|
|
415 |
_bdf_list_ensure( _bdf_list_t* list, |
_bdf_list_ensure( _bdf_list_t* list, |
416 |
int num_items ) |
int num_items ) |
417 |
{ |
{ |
418 |
FT_Error error = 0; |
FT_Error error = BDF_Err_Ok; |
419 |
|
|
420 |
|
|
421 |
if ( num_items > (int)list->size ) |
if ( num_items > (int)list->size ) |
422 |
{ |
{ |
423 |
int oldsize = list->size; |
int oldsize = list->size; |
424 |
int newsize = oldsize + (oldsize >> 1) + 4; |
int newsize = oldsize + ( oldsize >> 1 ) + 4; |
425 |
int bigsize = FT_INT_MAX / sizeof(char*); |
int bigsize = FT_INT_MAX / sizeof ( char* ); |
426 |
FT_Memory memory = list->memory; |
FT_Memory memory = list->memory; |
427 |
|
|
428 |
|
|
429 |
if ( oldsize == bigsize ) |
if ( oldsize == bigsize ) |
430 |
{ |
{ |
431 |
error = FT_Err_Out_Of_Memory; |
error = BDF_Err_Out_Of_Memory; |
432 |
goto Exit; |
goto Exit; |
433 |
} |
} |
434 |
else if ( newsize < oldsize || newsize > bigsize ) |
else if ( newsize < oldsize || newsize > bigsize ) |
439 |
|
|
440 |
list->size = newsize; |
list->size = newsize; |
441 |
} |
} |
442 |
|
|
443 |
Exit: |
Exit: |
444 |
return error; |
return error; |
445 |
} |
} |
498 |
} |
} |
499 |
|
|
500 |
|
|
|
|
|
501 |
/* An empty string for empty fields. */ |
/* An empty string for empty fields. */ |
502 |
|
|
503 |
static const char empty[1] = { 0 }; /* XXX eliminate this */ |
static const char empty[1] = { 0 }; /* XXX eliminate this */ |
504 |
|
|
505 |
|
|
|
|
|
506 |
static FT_Error |
static FT_Error |
507 |
_bdf_list_split( _bdf_list_t* list, |
_bdf_list_split( _bdf_list_t* list, |
508 |
char* separators, |
char* separators, |
556 |
/* Resize the list if necessary. */ |
/* Resize the list if necessary. */ |
557 |
if ( list->used == list->size ) |
if ( list->used == list->size ) |
558 |
{ |
{ |
559 |
error = _bdf_list_ensure( list, list->used+1 ); |
error = _bdf_list_ensure( list, list->used + 1 ); |
560 |
if ( error ) |
if ( error ) |
561 |
goto Exit; |
goto Exit; |
562 |
} |
} |
585 |
/* Finally, NULL-terminate the list. */ |
/* Finally, NULL-terminate the list. */ |
586 |
if ( list->used + final_empty >= list->size ) |
if ( list->used + final_empty >= list->size ) |
587 |
{ |
{ |
588 |
error = _bdf_list_ensure( list, list->used+final_empty+1 ); |
error = _bdf_list_ensure( list, list->used + final_empty + 1 ); |
589 |
if ( error ) |
if ( error ) |
590 |
goto Exit; |
goto Exit; |
591 |
} |
} |
600 |
} |
} |
601 |
|
|
602 |
|
|
|
|
|
603 |
#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ |
#define NO_SKIP 256 /* this value cannot be stored in a 'char' */ |
604 |
|
|
605 |
|
|
606 |
static FT_Error |
static FT_Error |
607 |
_bdf_readstream( FT_Stream stream, |
_bdf_readstream( FT_Stream stream, |
608 |
_bdf_line_func_t callback, |
_bdf_line_func_t callback, |
624 |
goto Exit; |
goto Exit; |
625 |
} |
} |
626 |
|
|
627 |
/* initial size and allocation of the input buffer |
/* initial size and allocation of the input buffer */ |
|
*/ |
|
628 |
buf_size = 1024; |
buf_size = 1024; |
629 |
|
|
630 |
if ( FT_NEW_ARRAY( buf, buf_size ) ) |
if ( FT_NEW_ARRAY( buf, buf_size ) ) |
631 |
goto Exit; |
goto Exit; |
632 |
|
|
633 |
cb = callback; |
cb = callback; |
634 |
lineno = 1; |
lineno = 1; |
635 |
buf[0] = 0; |
buf[0] = 0; |
636 |
start = 0; |
start = 0; |
637 |
end = 0; |
end = 0; |
638 |
avail = 0; |
avail = 0; |
639 |
cursor = 0; |
cursor = 0; |
640 |
refill = 1; |
refill = 1; |
641 |
to_skip = NO_SKIP; |
to_skip = NO_SKIP; |
642 |
bytes = 0; /* make compiler happy */ |
bytes = 0; /* make compiler happy */ |
643 |
|
|
644 |
for (;;) |
for (;;) |
645 |
{ |
{ |
646 |
if ( refill ) |
if ( refill ) |
647 |
{ |
{ |
648 |
bytes = (int) FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, |
bytes = (int)FT_Stream_TryRead( stream, (FT_Byte*)buf + cursor, |
649 |
(FT_ULong)(buf_size - cursor) ); |
(FT_ULong)(buf_size - cursor) ); |
650 |
avail = cursor + bytes; |
avail = cursor + bytes; |
651 |
cursor = 0; |
cursor = 0; |
654 |
|
|
655 |
end = start; |
end = start; |
656 |
|
|
657 |
/* should we skip an optional character like \n or \r ? */ |
/* should we skip an optional character like \n or \r? */ |
658 |
if ( start < avail && buf[start] == to_skip ) |
if ( start < avail && buf[start] == to_skip ) |
659 |
{ |
{ |
660 |
start += 1; |
start += 1; |
666 |
while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) |
while ( end < avail && buf[end] != '\n' && buf[end] != '\r' ) |
667 |
end++; |
end++; |
668 |
|
|
669 |
/* if we hit the end of the buffer, try shifting its content |
/* if we hit the end of the buffer, try shifting its content */ |
670 |
* or even resizing it |
/* or even resizing it */ |
|
*/ |
|
671 |
if ( end >= avail ) |
if ( end >= avail ) |
672 |
{ |
{ |
673 |
if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ |
if ( bytes == 0 ) /* last line in file doesn't end in \r or \n */ |
675 |
|
|
676 |
if ( start == 0 ) |
if ( start == 0 ) |
677 |
{ |
{ |
678 |
/* this line is definitely too long, try resizing the input buffer |
/* this line is definitely too long; try resizing the input */ |
679 |
* a bit to handle it. |
/* buffer a bit to handle it. */ |
|
*/ |
|
680 |
FT_ULong new_size; |
FT_ULong new_size; |
681 |
|
|
682 |
if ( buf_size >= 65536UL ) /* limit ourselves to 64 Kb */ |
|
683 |
|
if ( buf_size >= 65536UL ) /* limit ourselves to 64KByte */ |
684 |
{ |
{ |
685 |
error = BDF_Err_Invalid_Argument; |
error = BDF_Err_Invalid_Argument; |
686 |
goto Exit; |
goto Exit; |
687 |
} |
} |
688 |
|
|
689 |
new_size = buf_size*2; |
new_size = buf_size * 2; |
690 |
if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) |
if ( FT_RENEW_ARRAY( buf, buf_size, new_size ) ) |
691 |
goto Exit; |
goto Exit; |
692 |
|
|
697 |
{ |
{ |
698 |
bytes = avail - start; |
bytes = avail - start; |
699 |
|
|
700 |
FT_MEM_COPY( buf, buf+start, bytes ); |
FT_MEM_COPY( buf, buf + start, bytes ); |
701 |
|
|
702 |
cursor = bytes; |
cursor = bytes; |
703 |
avail -= bytes; |
avail -= bytes; |
714 |
/* XXX: Use encoding independent value for 0x1a */ |
/* XXX: Use encoding independent value for 0x1a */ |
715 |
if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) |
if ( buf[start] != '#' && buf[start] != 0x1a && end > start ) |
716 |
{ |
{ |
717 |
error = (*cb)( buf+start, end-start, lineno, (void*)&cb, client_data ); |
error = (*cb)( buf + start, end - start, lineno, |
718 |
|
(void*)&cb, client_data ); |
719 |
if ( error ) |
if ( error ) |
720 |
break; |
break; |
721 |
} |
} |
722 |
|
|
723 |
lineno += 1; |
lineno += 1; |
724 |
buf[end] = (char)hold; |
buf[end] = (char)hold; |
725 |
start = end+1; |
start = end + 1; |
726 |
|
|
727 |
if ( hold == '\n' ) |
if ( hold == '\n' ) |
728 |
to_skip = '\r'; |
to_skip = '\r'; |