1 /* -----------------------------------------------------------------------------
\r
5 Copyright (c) 2002, Randy Reddig & seaw0lf
\r
8 Redistribution and use in source and binary forms, with or without modification,
\r
9 are permitted provided that the following conditions are met:
\r
11 Redistributions of source code must retain the above copyright notice, this list
\r
12 of conditions and the following disclaimer.
\r
14 Redistributions in binary form must reproduce the above copyright notice, this
\r
15 list of conditions and the following disclaimer in the documentation and/or
\r
16 other materials provided with the distribution.
\r
18 Neither the names of the copyright holders nor the names of its contributors may
\r
19 be used to endorse or promote products derived from this software without
\r
20 specific prior written permission.
\r
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
\r
23 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
\r
24 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\r
25 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
\r
26 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
\r
27 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\r
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
\r
29 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
\r
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
\r
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
33 ----------------------------------------------------------------------------- */
\r
38 #define PICOINTERNAL_C
\r
43 * - fix p->curLine for parser routines. increased twice
\r
48 #include "picointernal.h"
\r
52 /* function pointers */
\r
53 void *(*_pico_ptr_malloc )( size_t ) = malloc;
\r
54 void (*_pico_ptr_free )( void* ) = free;
\r
55 void (*_pico_ptr_load_file )( char*, unsigned char**, int* ) = NULL;
\r
56 void (*_pico_ptr_free_file )( void* ) = NULL;
\r
57 void (*_pico_ptr_print )( int, const char* ) = NULL;
\r
67 * kludged memory allocation wrapper
\r
69 void *_pico_alloc( size_t size )
\r
73 /* some sanity checks */
\r
76 if (_pico_ptr_malloc == NULL)
\r
79 /* allocate memory */
\r
80 ptr = _pico_ptr_malloc(size);
\r
84 /* zero out allocated memory */
\r
87 /* return pointer to allocated memory */
\r
92 * _pico_calloc wrapper
\r
94 void *_pico_calloc( size_t num, size_t size )
\r
98 /* some sanity checks */
\r
99 if( num == 0 || size == 0 )
\r
101 if (_pico_ptr_malloc == NULL)
\r
104 /* allocate memory */
\r
105 ptr = _pico_ptr_malloc(num*size);
\r
109 /* zero out allocated memory */
\r
110 memset(ptr,0,num*size);
\r
112 /* return pointer to allocated memory */
\r
117 * memory reallocation wrapper (note: only grows,
\r
118 * but never shrinks or frees)
\r
120 void *_pico_realloc( void **ptr, size_t oldSize, size_t newSize )
\r
124 /* sanity checks */
\r
127 if( newSize < oldSize )
\r
129 if (_pico_ptr_malloc == NULL)
\r
132 /* allocate new pointer */
\r
133 ptr2 = _pico_alloc( newSize );
\r
140 memcpy( ptr2, *ptr, oldSize );
\r
141 _pico_free( *ptr );
\r
144 /* fix up and return */
\r
149 /* _pico_clone_alloc:
\r
150 * handy function for quick string allocation/copy. it clones
\r
151 * the given string and returns a pointer to the new allocated
\r
152 * clone (which must be freed by caller of course) or returns
\r
153 * NULL on memory alloc or param errors. if 'size' is -1 the
\r
154 * length of the input string is used, otherwise 'size' is used
\r
155 * as custom clone size (the string is cropped to fit into mem
\r
158 char *_pico_clone_alloc( char *str, int size )
\r
164 if (str == NULL) return NULL;
\r
166 /* set real size of cloned string */
\r
167 cloneSize = (size < 0) ? strlen(str) : size;
\r
169 /* allocate memory */
\r
170 cloned = _pico_alloc( cloneSize+1 ); /* bugfix! */
\r
171 if (cloned == NULL)
\r
174 /* zero out memory allocated by cloned string */
\r
175 memset( cloned,0,cloneSize );
\r
177 /* copy input string to cloned string */
\r
178 if (cloneSize < strlen( str )) {
\r
179 memcpy( cloned,str,cloneSize );
\r
180 cloned[ cloneSize ] = '\0';
\r
182 strcpy( cloned,str );
\r
184 /* return ptr to cloned string */
\r
189 * wrapper around the free function pointer
\r
191 void _pico_free( void *ptr )
\r
193 /* sanity checks */
\r
196 if (_pico_ptr_free == NULL)
\r
199 /* free the allocated memory */
\r
200 _pico_ptr_free( ptr );
\r
203 /* _pico_load_file:
\r
204 * wrapper around the loadfile function pointer
\r
206 void _pico_load_file( char *name, unsigned char **buffer, int *bufSize )
\r
208 /* sanity checks */
\r
214 if (_pico_ptr_load_file == NULL)
\r
219 /* do the actual call to read in the file; */
\r
220 /* BUFFER IS ALLOCATED BY THE EXTERNAL LOADFILE FUNC */
\r
221 _pico_ptr_load_file( name,buffer,bufSize );
\r
224 /* _pico_free_file:
\r
225 * wrapper around the file free function pointer
\r
227 void _pico_free_file( void *buffer )
\r
229 /* sanity checks */
\r
230 if( buffer == NULL )
\r
233 /* use default free */
\r
234 if( _pico_ptr_free_file == NULL )
\r
239 /* free the allocated file */
\r
240 _pico_ptr_free_file( buffer );
\r
244 * wrapper around the print function pointer -sea
\r
246 void _pico_printf( int level, const char *format, ...)
\r
251 /* sanity checks */
\r
252 if( format == NULL )
\r
254 if (_pico_ptr_print == NULL)
\r
257 /* format string */
\r
258 va_start( argptr,format );
\r
259 vsprintf( str,format,argptr );
\r
262 /* remove linefeeds */
\r
263 if (str[ strlen(str)-1 ] == '\n')
\r
264 str[ strlen(str)-1 ] = '\0';
\r
266 /* do the actual call */
\r
267 _pico_ptr_print( level,str );
\r
271 * left trims the given string -sea
\r
273 char *_pico_strltrim( char *str )
\r
275 char *str1 = str, *str2 = str;
\r
277 while (isspace(*str2)) str2++;
\r
279 while( *str2 != '\0' ) /* fix: ydnar */
\r
285 * right trims the given string -sea
\r
287 char *_pico_strrtrim( char *str )
\r
296 if (allspace && !isspace(*str1)) allspace = 0;
\r
299 if (allspace) *str = '\0';
\r
302 while ((isspace(*str1)) && (str1 >= str))
\r
310 * pico internal string-to-lower routine.
\r
312 char *_pico_strlwr( char *str )
\r
315 for (cp=str; *cp; ++cp)
\r
317 if ('A' <= *cp && *cp <= 'Z')
\r
319 *cp += ('a' - 'A');
\r
325 /* _pico_strchcount:
\r
326 * counts how often the given char appears in str. -sea
\r
328 int _pico_strchcount( char *str, int ch )
\r
331 while (*str++) if (*str == ch) count++;
\r
335 void _pico_zero_bounds( picoVec3_t mins, picoVec3_t maxs )
\r
338 for (i=0; i<3; i++)
\r
345 void _pico_expand_bounds( picoVec3_t p, picoVec3_t mins, picoVec3_t maxs )
\r
348 for (i=0; i<3; i++)
\r
350 float value = p[i];
\r
351 if (value < mins[i]) mins[i] = value;
\r
352 if (value > maxs[i]) maxs[i] = value;
\r
356 void _pico_zero_vec( picoVec3_t vec )
\r
358 vec[ 0 ] = vec[ 1 ] = vec[ 2 ] = 0;
\r
361 void _pico_zero_vec2( picoVec2_t vec )
\r
363 vec[ 0 ] = vec[ 1 ] = 0;
\r
366 void _pico_zero_vec4( picoVec4_t vec )
\r
368 vec[ 0 ] = vec[ 1 ] = vec[ 2 ] = vec[ 3 ] = 0;
\r
371 void _pico_set_vec( picoVec3_t v, float a, float b, float c )
\r
378 void _pico_set_vec4( picoVec4_t v, float a, float b, float c, float d )
\r
386 void _pico_copy_vec( picoVec3_t src, picoVec3_t dest )
\r
388 dest[ 0 ] = src[ 0 ];
\r
389 dest[ 1 ] = src[ 1 ];
\r
390 dest[ 2 ] = src[ 2 ];
\r
393 void _pico_copy_vec2( picoVec2_t src, picoVec2_t dest )
\r
395 dest[ 0 ] = src[ 0 ];
\r
396 dest[ 1 ] = src[ 1 ];
\r
399 void _pico_copy_vec4( picoVec4_t src, picoVec4_t dest )
\r
401 dest[ 0 ] = src[ 0 ];
\r
402 dest[ 1 ] = src[ 1 ];
\r
403 dest[ 2 ] = src[ 2 ];
\r
404 dest[ 3 ] = src[ 3 ];
\r
408 picoVec_t _pico_normalize_vec( picoVec3_t vec )
\r
412 len = sqrt( vec[ 0 ] * vec[ 0 ] + vec[ 1 ] * vec[ 1 ] + vec[ 2 ] * vec[ 2 ] );
\r
413 if( len == 0.0 ) return 0.0;
\r
415 vec[ 0 ] *= (picoVec_t) ilen;
\r
416 vec[ 1 ] *= (picoVec_t) ilen;
\r
417 vec[ 2 ] *= (picoVec_t) ilen;
\r
418 return (picoVec_t) len;
\r
421 void _pico_add_vec( picoVec3_t a, picoVec3_t b, picoVec3_t dest )
\r
423 dest[ 0 ] = a[ 0 ] + b[ 0 ];
\r
424 dest[ 1 ] = a[ 1 ] + b[ 1 ];
\r
425 dest[ 2 ] = a[ 2 ] + b[ 2 ];
\r
428 void _pico_subtract_vec( picoVec3_t a, picoVec3_t b, picoVec3_t dest )
\r
430 dest[ 0 ] = a[ 0 ] - b[ 0 ];
\r
431 dest[ 1 ] = a[ 1 ] - b[ 1 ];
\r
432 dest[ 2 ] = a[ 2 ] - b[ 2 ];
\r
435 void _pico_scale_vec( picoVec3_t v, float scale, picoVec3_t dest )
\r
437 dest[ 0 ] = v[ 0 ] * scale;
\r
438 dest[ 1 ] = v[ 1 ] * scale;
\r
439 dest[ 2 ] = v[ 2 ] * scale;
\r
442 void _pico_scale_vec4( picoVec4_t v, float scale, picoVec4_t dest )
\r
444 dest[ 0 ] = v[ 0 ] * scale;
\r
445 dest[ 1 ] = v[ 1 ] * scale;
\r
446 dest[ 2 ] = v[ 2 ] * scale;
\r
447 dest[ 3 ] = v[ 3 ] * scale;
\r
450 picoVec_t _pico_dot_vec( picoVec3_t a, picoVec3_t b )
\r
452 return a[ 0 ] * b[ 0 ] + a[ 1 ] * b[ 1 ] + a[ 2 ] * b[ 2 ];
\r
455 void _pico_cross_vec( picoVec3_t a, picoVec3_t b, picoVec3_t dest )
\r
457 dest[ 0 ] = a[ 1 ] * b[ 2 ] - a[ 2 ] * b[ 1 ];
\r
458 dest[ 1 ] = a[ 2 ] * b[ 0 ] - a[ 0 ] * b[ 2 ];
\r
459 dest[ 2 ] = a[ 0 ] * b[ 1 ] - a[ 1 ] * b[ 0 ];
\r
462 picoVec_t _pico_calc_plane( picoVec4_t plane, picoVec3_t a, picoVec3_t b, picoVec3_t c )
\r
466 _pico_subtract_vec( b, a, ba );
\r
467 _pico_subtract_vec( c, a, ca );
\r
468 _pico_cross_vec( ca, ba, plane );
\r
469 plane[ 3 ] = _pico_dot_vec( a, plane );
\r
470 return _pico_normalize_vec( plane );
\r
473 /* separate from _pico_set_vec4 */
\r
474 void _pico_set_color( picoColor_t c, int r, int g, int b, int a )
\r
482 void _pico_copy_color( picoColor_t src, picoColor_t dest )
\r
484 dest[ 0 ] = src[ 0 ];
\r
485 dest[ 1 ] = src[ 1 ];
\r
486 dest[ 2 ] = src[ 2 ];
\r
487 dest[ 3 ] = src[ 3 ];
\r
490 #ifdef __BIG_ENDIAN__
\r
492 int _pico_big_long ( int src ) { return src; }
\r
493 short _pico_big_short( short src ) { return src; }
\r
494 float _pico_big_float( float src ) { return src; }
\r
496 int _pico_little_long( int src )
\r
498 return ((src & 0xFF000000) >> 24) |
\r
499 ((src & 0x00FF0000) >> 8) |
\r
500 ((src & 0x0000FF00) << 8) |
\r
501 ((src & 0x000000FF) << 24);
\r
504 short _pico_little_short( short src )
\r
506 return ((src & 0xFF00) >> 8) |
\r
507 ((src & 0x00FF) << 8);
\r
510 float _pico_little_float( float src )
\r
512 floatSwapUnion in,out;
\r
514 out.c[ 0 ] = in.c[ 3 ];
\r
515 out.c[ 1 ] = in.c[ 2 ];
\r
516 out.c[ 2 ] = in.c[ 1 ];
\r
517 out.c[ 3 ] = in.c[ 0 ];
\r
520 #else /*__BIG_ENDIAN__*/
\r
522 int _pico_little_long ( int src ) { return src; }
\r
523 short _pico_little_short( short src ) { return src; }
\r
524 float _pico_little_float( float src ) { return src; }
\r
526 int _pico_big_long( int src )
\r
528 return ((src & 0xFF000000) >> 24) |
\r
529 ((src & 0x00FF0000) >> 8) |
\r
530 ((src & 0x0000FF00) << 8) |
\r
531 ((src & 0x000000FF) << 24);
\r
534 short _pico_big_short( short src )
\r
536 return ((src & 0xFF00) >> 8) |
\r
537 ((src & 0x00FF) << 8);
\r
540 float _pico_big_float( float src )
\r
542 floatSwapUnion in,out;
\r
544 out.c[ 0 ] = in.c[ 3 ];
\r
545 out.c[ 1 ] = in.c[ 2 ];
\r
546 out.c[ 2 ] = in.c[ 1 ];
\r
547 out.c[ 3 ] = in.c[ 0 ];
\r
550 #endif /*__BIG_ENDIAN__*/
\r
553 * case-insensitive strstr. -sea
\r
555 char *_pico_stristr( char *str, const char *substr )
\r
557 const int sublen = strlen(substr);
\r
560 if (!_pico_strnicmp(str,substr,sublen)) break;
\r
563 if (!(*str)) str = NULL;
\r
569 changes dos \ style path separators to /
\r
572 void _pico_unixify( char *path )
\r
578 if( *path == '\\' )
\r
585 * removes file name portion from given file path and converts
\r
586 * the directory separators to un*x style. returns 1 on success
\r
587 * or 0 when 'destSize' was exceeded. -sea
\r
589 int _pico_nofname( const char *path, char *dest, int destSize )
\r
591 int left = destSize;
\r
594 while ((*dest = *path) != '\0')
\r
596 if (*dest == '/' || *dest == '\\')
\r
614 * returns ptr to filename portion in given path or an empty
\r
615 * string otherwise. given 'path' is not altered. -sea
\r
617 char *_pico_nopath( const char *path )
\r
620 src = (char *)path + (strlen(path) - 1);
\r
622 if (path == NULL) return (char *)"";
\r
623 if (!strchr((char *)path,'/') && !strchr((char *)path,'\\'))
\r
624 return ((char *)path);
\r
626 while ((src--) != path)
\r
628 if (*src == '/' || *src == '\\')
\r
635 * sets/changes the file extension for the given filename
\r
636 * or filepath's filename portion. the given 'path' *is*
\r
637 * altered. leave 'ext' empty to remove extension. -sea
\r
639 char *_pico_setfext( char *path, const char *ext )
\r
644 src = path + (strlen(path) - 1);
\r
646 if (ext == NULL) ext = "";
\r
647 if (strlen(ext ) < 1) remfext = 1;
\r
648 if (strlen(path) < 1)
\r
651 while ((src--) != path)
\r
653 if (*src == '/' || *src == '\\')
\r
672 * extracts one line from the given buffer and stores it in dest.
\r
673 * returns -1 on error or the length of the line on success. i've
\r
674 * removed string trimming here. this can be done manually by the
\r
677 int _pico_getline( char *buf, int bufsize, char *dest, int destsize )
\r
682 if (dest == NULL || destsize < 1) return -1;
\r
683 memset( dest,0,destsize );
\r
686 if (buf == NULL || bufsize < 1)
\r
689 /* get next line */
\r
690 for (pos=0; pos<bufsize && pos<destsize; pos++)
\r
692 if (buf[pos] == '\n') { pos++; break; }
\r
693 dest[pos] = buf[pos];
\r
695 /* terminate dest and return */
\r
700 /* _pico_parse_skip_white:
\r
701 * skips white spaces in current pico parser, sets *hasLFs
\r
702 * to 1 if linefeeds were skipped, and either returns the
\r
703 * parser's cursor pointer or NULL on error. -sea
\r
705 void _pico_parse_skip_white( picoParser_t *p, int *hasLFs )
\r
707 /* sanity checks */
\r
708 if (p == NULL || p->cursor == NULL)
\r
711 /* skin white spaces */
\r
714 /* sanity checks */
\r
715 if (p->cursor < p->buffer ||
\r
716 p->cursor >= p->max)
\r
720 /* break for chars other than white spaces */
\r
721 if (*p->cursor > 0x20) break;
\r
722 if (*p->cursor == 0x00) return;
\r
724 /* a bit of linefeed handling */
\r
725 if (*p->cursor == '\n')
\r
730 /* go to next character */
\r
735 /* _pico_new_parser:
\r
736 * allocates a new ascii parser object.
\r
738 picoParser_t *_pico_new_parser( picoByte_t *buffer, int bufSize )
\r
743 if( buffer == NULL || bufSize <= 0 )
\r
746 /* allocate reader */
\r
747 p = _pico_alloc( sizeof(picoParser_t) );
\r
748 if (p == NULL) return NULL;
\r
749 memset( p,0,sizeof(picoParser_t) );
\r
751 /* allocate token space */
\r
753 p->tokenMax = 1024;
\r
754 p->token = _pico_alloc( p->tokenMax );
\r
755 if( p->token == NULL )
\r
761 p->buffer = buffer;
\r
762 p->cursor = buffer;
\r
763 p->bufSize = bufSize;
\r
764 p->max = p->buffer + bufSize;
\r
765 p->curLine = 1; /* sea: new */
\r
767 /* return ptr to parser */
\r
771 /* _pico_free_parser:
\r
772 * frees an existing pico parser object.
\r
774 void _pico_free_parser( picoParser_t *p )
\r
777 if (p == NULL) return;
\r
779 /* free the parser */
\r
780 if (p->token != NULL)
\r
782 _pico_free( p->token );
\r
788 * reads the next token from given pico parser object. if param
\r
789 * 'allowLFs' is 1 it will read beyond linefeeds and return 0 when
\r
790 * the EOF is reached. if 'allowLFs' is 0 it will return 0 when
\r
791 * the EOL is reached. if 'handleQuoted' is 1 the parser function
\r
792 * will handle "quoted" strings and return the data between the
\r
793 * quotes as token. returns 0 on end/error or 1 on success. -sea
\r
795 int _pico_parse_ex( picoParser_t *p, int allowLFs, int handleQuoted )
\r
800 /* sanity checks */
\r
801 if( p == NULL || p->buffer == NULL ||
\r
802 p->cursor < p->buffer ||
\r
803 p->cursor >= p->max )
\r
807 /* clear parser token */
\r
809 p->token[ 0 ] = '\0';
\r
812 /* skip whitespaces */
\r
813 while( p->cursor < p->max && *p->cursor <= 32 )
\r
815 if (*p->cursor == '\n')
\r
822 /* return if we're not allowed to go beyond lfs */
\r
823 if ((hasLFs > 0) && !allowLFs)
\r
828 /* get next quoted string */
\r
829 if (*p->cursor == '\"' && handleQuoted)
\r
832 while (p->cursor < p->max && *p->cursor)
\r
834 if (*p->cursor == '\\')
\r
836 if (*(p->cursor+1) == '"')
\r
840 p->token[ p->tokenSize++ ] = *p->cursor++;
\r
843 else if (*p->cursor == '\"')
\r
848 else if (*p->cursor == '\n')
\r
852 p->token[ p->tokenSize++ ] = *p->cursor++;
\r
854 /* terminate token */
\r
855 p->token[ p->tokenSize ] = '\0';
\r
858 /* otherwise get next word */
\r
859 while( p->cursor < p->max && *p->cursor > 32 )
\r
861 if (*p->cursor == '\n')
\r
865 p->token[ p->tokenSize++ ] = *p->cursor++;
\r
867 /* terminate token */
\r
868 p->token[ p->tokenSize ] = '\0';
\r
872 /* _pico_parse_first:
\r
873 * reads the first token from the next line and returns
\r
874 * a pointer to it. returns NULL on EOL or EOF. -sea
\r
876 char *_pico_parse_first( picoParser_t *p )
\r
879 if (p == NULL) return NULL;
\r
881 /* try to read next token (with lfs & quots) */
\r
882 if (!_pico_parse_ex( p,1,1 ))
\r
885 /* return ptr to the token string */
\r
890 * reads the next token from the parser and returns a pointer
\r
891 * to it. quoted strings are handled as usual. returns NULL
\r
892 * on EOL or EOF. -sea
\r
894 char *_pico_parse( picoParser_t *p, int allowLFs )
\r
897 if (p == NULL) return NULL;
\r
899 /* try to read next token (with quots) */
\r
900 if (!_pico_parse_ex( p,allowLFs,1 ))
\r
903 /* return ptr to the token string */
\r
907 /* _pico_parse_skip_rest:
\r
908 * skips the rest of the current line in parser.
\r
910 void _pico_parse_skip_rest( picoParser_t *p )
\r
912 while( _pico_parse_ex( p,0,0 ) ) ;
\r
915 /* _pico_parse_skip_braced:
\r
916 * parses/skips over a braced section. returns 1 on success
\r
917 * or 0 on error (when there was no closing bracket and the
\r
918 * end of buffer was reached or when the opening bracket was
\r
921 int _pico_parse_skip_braced( picoParser_t *p )
\r
923 int firstToken = 1;
\r
927 if (p == NULL) return 0;
\r
929 /* set the initial level for parsing */
\r
932 /* skip braced section */
\r
935 /* read next token (lfs allowed) */
\r
936 if (!_pico_parse_ex( p,1,1 ))
\r
938 /* end of parser buffer reached */
\r
941 /* first token must be an opening bracket */
\r
942 if (firstToken && p->token[0] != '{')
\r
944 /* opening bracket missing */
\r
947 /* we only check this once */
\r
951 if (p->token[1] == '\0')
\r
953 if (p->token[0] == '{') level++;
\r
954 if (p->token[0] == '}') level--;
\r
956 /* break if we're back at our starting level */
\r
957 if (level == 0) break;
\r
959 /* successfully skipped braced section */
\r
963 int _pico_parse_check( picoParser_t *p, int allowLFs, char *str )
\r
965 if (!_pico_parse_ex( p,allowLFs,1 ))
\r
967 if (!strcmp(p->token,str))
\r
972 int _pico_parse_checki( picoParser_t *p, int allowLFs, char *str )
\r
974 if (!_pico_parse_ex( p,allowLFs,1 ))
\r
976 if (!_pico_stricmp(p->token,str))
\r
981 int _pico_parse_int( picoParser_t *p, int *out )
\r
985 /* sanity checks */
\r
986 if (p == NULL || out == NULL)
\r
989 /* get token and turn it into an integer */
\r
991 token = _pico_parse( p,0 );
\r
992 if (token == NULL) return 0;
\r
993 *out = atoi( token );
\r
999 int _pico_parse_int_def( picoParser_t *p, int *out, int def )
\r
1003 /* sanity checks */
\r
1004 if (p == NULL || out == NULL)
\r
1007 /* get token and turn it into an integer */
\r
1009 token = _pico_parse( p,0 );
\r
1010 if (token == NULL) return 0;
\r
1011 *out = atoi( token );
\r
1017 int _pico_parse_float( picoParser_t *p, float *out )
\r
1021 /* sanity checks */
\r
1022 if (p == NULL || out == NULL)
\r
1025 /* get token and turn it into a float */
\r
1027 token = _pico_parse( p,0 );
\r
1028 if (token == NULL) return 0;
\r
1029 *out = (float) atof( token );
\r
1035 int _pico_parse_float_def( picoParser_t *p, float *out, float def )
\r
1039 /* sanity checks */
\r
1040 if (p == NULL || out == NULL)
\r
1043 /* get token and turn it into a float */
\r
1045 token = _pico_parse( p,0 );
\r
1046 if (token == NULL) return 0;
\r
1047 *out = (float) atof( token );
\r
1053 int _pico_parse_vec( picoParser_t *p, picoVec3_t out )
\r
1058 /* sanity checks */
\r
1059 if (p == NULL || out == NULL)
\r
1062 /* zero out outination vector */
\r
1063 _pico_zero_vec( out );
\r
1065 /* parse three vector components */
\r
1066 for (i=0; i<3; i++)
\r
1068 token = _pico_parse( p,0 );
\r
1069 if (token == NULL)
\r
1071 _pico_zero_vec( out );
\r
1074 out[ i ] = (float) atof( token );
\r
1080 int _pico_parse_vec_def( picoParser_t *p, picoVec3_t out, picoVec3_t def )
\r
1085 /* sanity checks */
\r
1086 if (p == NULL || out == NULL)
\r
1089 /* assign default vector value */
\r
1090 _pico_copy_vec( def,out );
\r
1092 /* parse three vector components */
\r
1093 for (i=0; i<3; i++)
\r
1095 token = _pico_parse( p,0 );
\r
1096 if (token == NULL)
\r
1098 _pico_copy_vec( def,out );
\r
1101 out[ i ] = (float) atof( token );
\r
1107 int _pico_parse_vec2( picoParser_t *p, picoVec2_t out )
\r
1112 /* sanity checks */
\r
1113 if (p == NULL || out == NULL)
\r
1116 /* zero out outination vector */
\r
1117 _pico_zero_vec2( out );
\r
1119 /* parse two vector components */
\r
1120 for (i=0; i<2; i++)
\r
1122 token = _pico_parse( p,0 );
\r
1123 if (token == NULL)
\r
1125 _pico_zero_vec2( out );
\r
1128 out[ i ] = (float) atof( token );
\r
1134 int _pico_parse_vec2_def( picoParser_t *p, picoVec2_t out, picoVec2_t def )
\r
1139 /* sanity checks */
\r
1140 if (p == NULL || out == NULL)
\r
1143 /* assign default vector value */
\r
1144 _pico_copy_vec2( def,out );
\r
1146 /* parse two vector components */
\r
1147 for (i=0; i<2; i++)
\r
1149 token = _pico_parse( p,0 );
\r
1150 if (token == NULL)
\r
1152 _pico_copy_vec2( def,out );
\r
1155 out[ i ] = (float) atof( token );
\r
1161 int _pico_parse_vec4( picoParser_t *p, picoVec4_t out )
\r
1166 /* sanity checks */
\r
1167 if (p == NULL || out == NULL)
\r
1170 /* zero out outination vector */
\r
1171 _pico_zero_vec4( out );
\r
1173 /* parse four vector components */
\r
1174 for (i=0; i<4; i++)
\r
1176 token = _pico_parse( p,0 );
\r
1177 if (token == NULL)
\r
1179 _pico_zero_vec4( out );
\r
1182 out[ i ] = (float) atof( token );
\r
1188 int _pico_parse_vec4_def( picoParser_t *p, picoVec4_t out, picoVec4_t def )
\r
1193 /* sanity checks */
\r
1194 if (p == NULL || out == NULL)
\r
1197 /* assign default vector value */
\r
1198 _pico_copy_vec4( def,out );
\r
1200 /* parse four vector components */
\r
1201 for (i=0; i<4; i++)
\r
1203 token = _pico_parse( p,0 );
\r
1204 if (token == NULL)
\r
1206 _pico_copy_vec4( def,out );
\r
1209 out[ i ] = (float) atof( token );
\r
1215 /* _pico_new_memstream:
\r
1216 * allocates a new memorystream object.
\r
1218 picoMemStream_t *_pico_new_memstream( picoByte_t *buffer, int bufSize )
\r
1220 picoMemStream_t *s;
\r
1222 /* sanity check */
\r
1223 if( buffer == NULL || bufSize <= 0 )
\r
1226 /* allocate stream */
\r
1227 s = _pico_alloc( sizeof(picoMemStream_t) );
\r
1228 if (s == NULL) return NULL;
\r
1229 memset( s,0,sizeof(picoMemStream_t) );
\r
1232 s->buffer = buffer;
\r
1233 s->curPos = buffer;
\r
1234 s->bufSize = bufSize;
\r
1237 /* return ptr to stream */
\r
1241 /* _pico_free_memstream:
\r
1242 * frees an existing pico memorystream object.
\r
1244 void _pico_free_memstream( picoMemStream_t *s )
\r
1246 /* sanity check */
\r
1247 if (s == NULL) return;
\r
1249 /* free the stream */
\r
1253 /* _pico_memstream_read:
\r
1254 * reads data from a pico memorystream into a buffer.
\r
1256 int _pico_memstream_read( picoMemStream_t *s, void *buffer, int len )
\r
1260 /* sanity checks */
\r
1261 if (s == NULL || buffer == NULL)
\r
1264 if (s->curPos + len > s->buffer + s->bufSize)
\r
1266 s->flag |= PICO_IOEOF;
\r
1267 len = s->buffer + s->bufSize - s->curPos;
\r
1271 /* read the data */
\r
1272 memcpy( buffer, s->curPos, len );
\r
1277 /* _pico_memstream_read:
\r
1278 * reads a character from a pico memorystream
\r
1280 int _pico_memstream_getc( picoMemStream_t *s )
\r
1284 /* sanity check */
\r
1288 /* read the character */
\r
1289 if (_pico_memstream_read( s, &c, 1) == 0)
\r
1295 /* _pico_memstream_seek:
\r
1296 * sets the current read position to a different location
\r
1298 int _pico_memstream_seek( picoMemStream_t *s, long offset, int origin )
\r
1302 /* sanity check */
\r
1306 if (origin == PICO_SEEK_SET)
\r
1308 s->curPos = s->buffer + offset;
\r
1309 overflow = s->curPos - ( s->buffer + s->bufSize );
\r
1312 s->curPos = s->buffer + s->bufSize;
\r
1313 return offset - overflow;
\r
1317 else if (origin == PICO_SEEK_CUR)
\r
1319 s->curPos += offset;
\r
1320 overflow = s->curPos - ( s->buffer + s->bufSize );
\r
1323 s->curPos = s->buffer + s->bufSize;
\r
1324 return offset - overflow;
\r
1328 else if (origin == PICO_SEEK_END)
\r
1330 s->curPos = ( s->buffer + s->bufSize ) - offset;
\r
1331 overflow = s->buffer - s->curPos;
\r
1334 s->curPos = s->buffer;
\r
1335 return offset - overflow;
\r
1343 /* _pico_memstream_tell:
\r
1344 * returns the current read position in the pico memorystream
\r
1346 long _pico_memstream_tell( picoMemStream_t *s )
\r
1348 /* sanity check */
\r
1352 return s->curPos - s->buffer;
\r