picointernal.c

Go to the documentation of this file.
00001 /* -----------------------------------------------------------------------------
00002 
00003  PicoModel Library
00004 
00005  Copyright (c) 2002, Randy Reddig & seaw0lf
00006  All rights reserved.
00007 
00008  Redistribution and use in source and binary forms, with or without modification,
00009  are permitted provided that the following conditions are met:
00010 
00011  Redistributions of source code must retain the above copyright notice, this list
00012  of conditions and the following disclaimer.
00013 
00014  Redistributions in binary form must reproduce the above copyright notice, this
00015  list of conditions and the following disclaimer in the documentation and/or
00016  other materials provided with the distribution.
00017 
00018  Neither the names of the copyright holders nor the names of its contributors may
00019  be used to endorse or promote products derived from this software without
00020  specific prior written permission.
00021 
00022  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00023  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00024  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00025  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
00026  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00027  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
00029  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00031  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 
00033  ----------------------------------------------------------------------------- */
00034 
00035 /* marker */
00036 #define PICOINTERNAL_C
00037 
00040 /* dependencies */
00041 #include <string.h>
00042 #include "picointernal.h"
00043 
00044 /* function pointers */
00045 void *(*_pico_ptr_malloc) (size_t) = malloc;
00046 void (*_pico_ptr_free) (void*) = free;
00047 void (*_pico_ptr_load_file) (char*, unsigned char**, int*) = NULL;
00048 void (*_pico_ptr_free_file) (void*) = NULL;
00049 void (*_pico_ptr_print) (int, const char*) = NULL;
00050 
00051 typedef union
00052 {
00053     float f;
00054     char c[4];
00055 } floatSwapUnion;
00056 
00060 void *_pico_alloc (size_t size)
00061 {
00062     void *ptr;
00063 
00064     /* some sanity checks */
00065     if (size == 0)
00066         return NULL;
00067     if (_pico_ptr_malloc == NULL)
00068         return NULL;
00069 
00070     /* allocate memory */
00071     ptr = _pico_ptr_malloc(size);
00072     if (ptr == NULL)
00073         return NULL;
00074 
00075     /* zero out allocated memory */
00076     memset(ptr, 0, size);
00077 
00078     /* return pointer to allocated memory */
00079     return ptr;
00080 }
00081 
00085 void *_pico_calloc (size_t num, size_t size)
00086 {
00087     void *ptr;
00088 
00089     /* some sanity checks */
00090     if (num == 0 || size == 0)
00091         return NULL;
00092     if (_pico_ptr_malloc == NULL)
00093         return NULL;
00094 
00095     /* allocate memory */
00096     ptr = _pico_ptr_malloc(num * size);
00097     if (ptr == NULL)
00098         return NULL;
00099 
00100     /* zero out allocated memory */
00101     memset(ptr, 0, num * size);
00102 
00103     /* return pointer to allocated memory */
00104     return ptr;
00105 }
00106 
00110 void *_pico_realloc (void **ptr, size_t oldSize, size_t newSize)
00111 {
00112     void *ptr2;
00113 
00114     /* sanity checks */
00115     if (ptr == NULL)
00116         return NULL;
00117     if (newSize < oldSize)
00118         return *ptr;
00119     if (_pico_ptr_malloc == NULL)
00120         return NULL;
00121 
00122     /* allocate new pointer */
00123     ptr2 = _pico_alloc(newSize);
00124     if (ptr2 == NULL)
00125         return NULL;
00126 
00127     /* copy */
00128     if (*ptr != NULL) {
00129         memcpy(ptr2, *ptr, oldSize);
00130         _pico_free(*ptr);
00131     }
00132 
00133     /* fix up and return */
00134     *ptr = ptr2;
00135     return *ptr;
00136 }
00137 
00147 char *_pico_clone_alloc (const char *str)
00148 {
00149     char* cloned;
00150 
00151     /* sanity check */
00152     if (str == NULL)
00153         return NULL;
00154 
00155     /* allocate memory */
00156     cloned = _pico_alloc(strlen(str) + 1);
00157     if (cloned == NULL)
00158         return NULL;
00159 
00160     /* copy input string to cloned string */
00161     strcpy(cloned, str);
00162 
00163     /* return ptr to cloned string */
00164     return cloned;
00165 }
00166 
00170 void _pico_free (void *ptr)
00171 {
00172     /* sanity checks */
00173     if (ptr == NULL)
00174         return;
00175     if (_pico_ptr_free == NULL)
00176         return;
00177 
00178     /* free the allocated memory */
00179     _pico_ptr_free(ptr);
00180 }
00181 
00185 void _pico_load_file (char *name, unsigned char **buffer, int *bufSize)
00186 {
00187     /* sanity checks */
00188     if (name == NULL) {
00189         *bufSize = -1;
00190         return;
00191     }
00192     if (_pico_ptr_load_file == NULL) {
00193         *bufSize = -1;
00194         return;
00195     }
00196     /* do the actual call to read in the file;
00197      * BUFFER IS ALLOCATED BY THE EXTERNAL LOADFILE FUNC */
00198     _pico_ptr_load_file(name, buffer, bufSize);
00199 }
00200 
00204 void _pico_free_file (void *buffer)
00205 {
00206     /* sanity checks */
00207     if (buffer == NULL)
00208         return;
00209 
00210     /* use default free */
00211     if (_pico_ptr_free_file == NULL) {
00212         free(buffer);
00213         return;
00214     }
00215     /* free the allocated file */
00216     _pico_ptr_free_file(buffer);
00217 }
00218 
00222 void _pico_printf (int level, const char *format, ...)
00223 {
00224     char str[4096];
00225     va_list argptr;
00226 
00227     /* sanity checks */
00228     if (format == NULL)
00229         return;
00230     if (_pico_ptr_print == NULL)
00231         return;
00232 
00233     /* format string */
00234     va_start(argptr,format);
00235     vsprintf(str, format, argptr);
00236     va_end(argptr);
00237 
00238     /* remove linefeeds */
00239     if (str[strlen(str) - 1] == '\n')
00240         str[strlen(str) - 1] = '\0';
00241 
00242     /* do the actual call */
00243     _pico_ptr_print(level, str);
00244 }
00245 
00246 /* _pico_first_token:
00247  * trims everything after the first whitespace-delimited token
00248  */
00249 
00250 void _pico_first_token (char *str)
00251 {
00252     if (!str || !*str)
00253         return;
00254     while (*str && !isspace(*str))
00255         str++;
00256     *str = '\0';
00257 }
00258 
00259 /* _pico_strltrim:
00260  * left trims the given string -sea
00261  */
00262 char *_pico_strltrim (char *str)
00263 {
00264     char *str1 = str, *str2 = str;
00265 
00266     while (isspace(*str2))
00267         str2++;
00268     if (str2 != str)
00269         while (*str2 != '\0') /* fix: ydnar */
00270             *str1++ = *str2++;
00271     return str;
00272 }
00273 
00274 /* _pico_strrtrim:
00275  * right trims the given string -sea
00276  */
00277 char *_pico_strrtrim (char *str)
00278 {
00279     if (str && *str) {
00280         char *str1 = str;
00281         int allspace = 1;
00282 
00283         while (*str1) {
00284             if (allspace && !isspace(*str1))
00285                 allspace = 0;
00286             str1++;
00287         }
00288         if (allspace)
00289             *str = '\0';
00290         else {
00291             str1--;
00292             while ((isspace(*str1)) && (str1 >= str))
00293                 *str1-- = '\0';
00294         }
00295     }
00296     return str;
00297 }
00298 
00299 /* _pico_strlwr:
00300  *  pico internal string-to-lower routine.
00301  */
00302 char *_pico_strlwr (char *str)
00303 {
00304     char *cp;
00305     for (cp = str; *cp; ++cp) {
00306         if ('A' <= *cp && *cp <= 'Z') {
00307             *cp += ('a' - 'A');
00308         }
00309     }
00310     return str;
00311 }
00312 
00313 /* _pico_strchcount:
00314  *  counts how often the given char appears in str. -sea
00315  */
00316 int _pico_strchcount (char *str, int ch)
00317 {
00318     int count = 0;
00319     while (*str++)
00320         if (*str == ch)
00321             count++;
00322     return count;
00323 }
00324 
00325 void _pico_zero_bounds (picoVec3_t mins, picoVec3_t maxs)
00326 {
00327     int i;
00328     for (i = 0; i < 3; i++) {
00329         mins[i] = +999999;
00330         maxs[i] = -999999;
00331     }
00332 }
00333 
00334 void _pico_expand_bounds (picoVec3_t p, picoVec3_t mins, picoVec3_t maxs)
00335 {
00336     int i;
00337     for (i = 0; i < 3; i++) {
00338         float value = p[i];
00339         if (value < mins[i])
00340             mins[i] = value;
00341         if (value > maxs[i])
00342             maxs[i] = value;
00343     }
00344 }
00345 
00346 void _pico_zero_vec (picoVec3_t vec)
00347 {
00348     vec[0] = vec[1] = vec[2] = 0;
00349 }
00350 
00351 void _pico_zero_vec2 (picoVec2_t vec)
00352 {
00353     vec[0] = vec[1] = 0;
00354 }
00355 
00356 void _pico_zero_vec4 (picoVec4_t vec)
00357 {
00358     vec[0] = vec[1] = vec[2] = vec[3] = 0;
00359 }
00360 
00361 void _pico_set_vec (picoVec3_t v, float a, float b, float c)
00362 {
00363     v[0] = a;
00364     v[1] = b;
00365     v[2] = c;
00366 }
00367 
00368 void _pico_set_vec4 (picoVec4_t v, float a, float b, float c, float d)
00369 {
00370     v[0] = a;
00371     v[1] = b;
00372     v[2] = c;
00373     v[3] = d;
00374 }
00375 
00376 void _pico_copy_vec (picoVec3_t src, picoVec3_t dest)
00377 {
00378     dest[0] = src[0];
00379     dest[1] = src[1];
00380     dest[2] = src[2];
00381 }
00382 
00383 void _pico_copy_vec2 (picoVec2_t src, picoVec2_t dest)
00384 {
00385     dest[0] = src[0];
00386     dest[1] = src[1];
00387 }
00388 
00389 static void _pico_copy_vec4 (picoVec4_t src, picoVec4_t dest)
00390 {
00391     dest[0] = src[0];
00392     dest[1] = src[1];
00393     dest[2] = src[2];
00394     dest[3] = src[3];
00395 }
00396 
00397 /* ydnar */
00398 picoVec_t _pico_normalize_vec (picoVec3_t vec)
00399 {
00400     double len, ilen;
00401 
00402     len = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
00403     if (len == 0.0)
00404         return 0.0;
00405     ilen = 1.0 / len;
00406     vec[0] *= (picoVec_t) ilen;
00407     vec[1] *= (picoVec_t) ilen;
00408     vec[2] *= (picoVec_t) ilen;
00409     return (picoVec_t) len;
00410 }
00411 
00412 void _pico_add_vec (picoVec3_t a, picoVec3_t b, picoVec3_t dest)
00413 {
00414     dest[0] = a[0] + b[0];
00415     dest[1] = a[1] + b[1];
00416     dest[2] = a[2] + b[2];
00417 }
00418 
00419 void _pico_subtract_vec (picoVec3_t a, picoVec3_t b, picoVec3_t dest)
00420 {
00421     dest[0] = a[0] - b[0];
00422     dest[1] = a[1] - b[1];
00423     dest[2] = a[2] - b[2];
00424 }
00425 
00426 void _pico_scale_vec (picoVec3_t v, float scale, picoVec3_t dest)
00427 {
00428     dest[0] = v[0] * scale;
00429     dest[1] = v[1] * scale;
00430     dest[2] = v[2] * scale;
00431 }
00432 
00433 void _pico_scale_vec4 (picoVec4_t v, float scale, picoVec4_t dest)
00434 {
00435     dest[0] = v[0] * scale;
00436     dest[1] = v[1] * scale;
00437     dest[2] = v[2] * scale;
00438     dest[3] = v[3] * scale;
00439 }
00440 
00441 picoVec_t _pico_dot_vec (picoVec3_t a, picoVec3_t b)
00442 {
00443     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
00444 }
00445 
00446 void _pico_cross_vec (picoVec3_t a, picoVec3_t b, picoVec3_t dest)
00447 {
00448     dest[0] = a[1] * b[2] - a[2] * b[1];
00449     dest[1] = a[2] * b[0] - a[0] * b[2];
00450     dest[2] = a[0] * b[1] - a[1] * b[0];
00451 }
00452 
00453 picoVec_t _pico_calc_plane (picoVec4_t plane, picoVec3_t a, picoVec3_t b, picoVec3_t c)
00454 {
00455     picoVec3_t ba, ca;
00456 
00457     _pico_subtract_vec(b, a, ba);
00458     _pico_subtract_vec(c, a, ca);
00459     _pico_cross_vec(ca, ba, plane);
00460     plane[3] = _pico_dot_vec(a, plane);
00461     return _pico_normalize_vec(plane);
00462 }
00463 
00464 /* separate from _pico_set_vec4 */
00465 void _pico_set_color (picoColor_t c, int r, int g, int b, int a)
00466 {
00467     c[0] = r;
00468     c[1] = g;
00469     c[2] = b;
00470     c[3] = a;
00471 }
00472 
00473 void _pico_copy_color (picoColor_t src, picoColor_t dest)
00474 {
00475     dest[0] = src[0];
00476     dest[1] = src[1];
00477     dest[2] = src[2];
00478     dest[3] = src[3];
00479 }
00480 
00481 #ifdef __BIG_ENDIAN__
00482 
00483 int _pico_big_long (int src) {
00484     return src;
00485 }
00486 short _pico_big_short(short src) {
00487     return src;
00488 }
00489 float _pico_big_float(float src) {
00490     return src;
00491 }
00492 
00493 int _pico_little_long(int src) {
00494     return ((src & 0xFF000000) >> 24) |
00495     ((src & 0x00FF0000) >> 8) |
00496     ((src & 0x0000FF00) << 8) |
00497     ((src & 0x000000FF) << 24);
00498 }
00499 
00500 short _pico_little_short(short src) {
00501     return ((src & 0xFF00) >> 8) |
00502     ((src & 0x00FF) << 8);
00503 }
00504 
00505 float _pico_little_float(float src) {
00506     floatSwapUnion in,out;
00507     in.f = src;
00508     out.c[0] = in.c[3];
00509     out.c[1] = in.c[2];
00510     out.c[2] = in.c[1];
00511     out.c[3] = in.c[0];
00512     return out.f;
00513 }
00514 #else /*__BIG_ENDIAN__*/
00515 
00516 int _pico_little_long (int src)
00517 {
00518     return src;
00519 }
00520 short _pico_little_short (short src)
00521 {
00522     return src;
00523 }
00524 float _pico_little_float (float src)
00525 {
00526     return src;
00527 }
00528 
00529 int _pico_big_long (int src)
00530 {
00531     return ((src & 0xFF000000) >> 24) | ((src & 0x00FF0000) >> 8) | ((src & 0x0000FF00) << 8) | ((src & 0x000000FF)
00532             << 24);
00533 }
00534 
00535 short _pico_big_short (short src)
00536 {
00537     return ((src & 0xFF00) >> 8) | ((src & 0x00FF) << 8);
00538 }
00539 
00540 float _pico_big_float (float src)
00541 {
00542     floatSwapUnion in, out;
00543     in.f = src;
00544     out.c[0] = in.c[3];
00545     out.c[1] = in.c[2];
00546     out.c[2] = in.c[1];
00547     out.c[3] = in.c[0];
00548     return out.f;
00549 }
00550 #endif /*__BIG_ENDIAN__*/
00551 
00552 /* _pico_stristr:
00553  *  case-insensitive strstr. -sea
00554  */
00555 const char *_pico_stristr (const char *str, const char *substr)
00556 {
00557     const size_t sublen = strlen(substr);
00558     while (*str) {
00559         if (!_pico_strnicmp(str, substr, sublen))
00560             break;
00561         str++;
00562     }
00563     if (!(*str))
00564         str = NULL;
00565     return str;
00566 }
00567 
00568 /*
00569  _pico_unixify()
00570  changes dos \ style path separators to /
00571  */
00572 
00573 void _pico_unixify (char *path)
00574 {
00575     if (path == NULL)
00576         return;
00577     while (*path) {
00578         if (*path == '\\')
00579             *path = '/';
00580         path++;
00581     }
00582 }
00583 
00584 /* _pico_nofname:
00585  *  removes file name portion from given file path and converts
00586  *  the directory separators to un*x style. returns 1 on success
00587  *  or 0 when 'destSize' was exceeded. -sea
00588  */
00589 int _pico_nofname (const char *path, char *dest, int destSize)
00590 {
00591     int left = destSize;
00592     char *temp = dest;
00593 
00594     while ((*dest = *path) != '\0') {
00595         if (*dest == '/' || *dest == '\\') {
00596             temp = (dest + 1);
00597             *dest = '/';
00598         }
00599         dest++;
00600         path++;
00601 
00602         if (--left < 1) {
00603             *temp = '\0';
00604             return 0;
00605         }
00606     }
00607     *temp = '\0';
00608     return 1;
00609 }
00610 
00611 /* _pico_nopath:
00612  *  returns ptr to filename portion in given path or an empty
00613  *  string otherwise. given 'path' is not altered. -sea
00614  */
00615 const char *_pico_nopath (const char *path)
00616 {
00617     const char *src;
00618     src = path + (strlen(path) - 1);
00619 
00620     if (path == NULL)
00621         return "";
00622     if (!strchr(path, '/') && !strchr(path, '\\'))
00623         return (path);
00624 
00625     while ((src--) != path) {
00626         if (*src == '/' || *src == '\\')
00627             return (++src);
00628     }
00629     return "";
00630 }
00631 
00632 /* _pico_setfext:
00633  *  sets/changes the file extension for the given filename
00634  *  or filepath's filename portion. the given 'path' *is*
00635  *  altered. leave 'ext' empty to remove extension. -sea
00636  */
00637 char *_pico_setfext (char *path, const char *ext)
00638 {
00639     char *src;
00640     int remfext = 0;
00641 
00642     src = path + (strlen(path) - 1);
00643 
00644     if (ext == NULL)
00645         ext = "";
00646     if (strlen(ext) < 1)
00647         remfext = 1;
00648     if (strlen(path) < 1)
00649         return path;
00650 
00651     while ((src--) != path) {
00652         if (*src == '/' || *src == '\\')
00653             return path;
00654 
00655         if (*src == '.') {
00656             if (remfext) {
00657                 *src = '\0';
00658                 return path;
00659             }
00660             *(++src) = '\0';
00661             break;
00662         }
00663     }
00664     strcat(path, ext);
00665     return path;
00666 }
00667 
00668 /* _pico_getline:
00669  *  extracts one line from the given buffer and stores it in dest.
00670  *  returns -1 on error or the length of the line on success. i've
00671  *  removed string trimming here. this can be done manually by the
00672  *  calling func.
00673  */
00674 int _pico_getline (char *buf, int bufsize, char *dest, int destsize)
00675 {
00676     int pos;
00677 
00678     /* check output */
00679     if (dest == NULL || destsize < 1)
00680         return -1;
00681     memset(dest, 0, destsize);
00682 
00683     /* check input */
00684     if (buf == NULL || bufsize < 1)
00685         return -1;
00686 
00687     /* get next line */
00688     for (pos = 0; pos < bufsize && pos < destsize; pos++) {
00689         if (buf[pos] == '\n') {
00690             pos++;
00691             break;
00692         }
00693         dest[pos] = buf[pos];
00694     }
00695     /* terminate dest and return */
00696     dest[pos] = '\0';
00697     return pos;
00698 }
00699 
00703 picoParser_t *_pico_new_parser (picoByte_t *buffer, int bufSize)
00704 {
00705     picoParser_t *p;
00706 
00707     /* sanity check */
00708     if (buffer == NULL || bufSize <= 0)
00709         return NULL;
00710 
00711     /* allocate reader */
00712     p = _pico_alloc(sizeof(*p));
00713     if (p == NULL)
00714         return NULL;
00715     memset(p, 0, sizeof(*p));
00716 
00717     /* allocate token space */
00718     p->tokenSize = 0;
00719     p->tokenMax = 1024;
00720     p->token = _pico_alloc(p->tokenMax);
00721     if (p->token == NULL) {
00722         _pico_free(p);
00723         return NULL;
00724     }
00725     /* setup */
00726     p->buffer = (char *) buffer;
00727     p->cursor = (char *) buffer;
00728     p->bufSize = bufSize;
00729     p->max = p->buffer + bufSize;
00730     p->curLine = 1; /* sea: new */
00731 
00732     /* return ptr to parser */
00733     return p;
00734 }
00735 
00739 void _pico_free_parser (picoParser_t *p)
00740 {
00741     /* sanity check */
00742     if (p == NULL)
00743         return;
00744 
00745     /* free the parser */
00746     if (p->token != NULL) {
00747         _pico_free(p->token);
00748     }
00749     _pico_free(p);
00750 }
00751 
00760 int _pico_parse_ex (picoParser_t *p, int allowLFs, int handleQuoted)
00761 {
00762     int hasLFs = 0;
00763     char *old;
00764 
00765     /* sanity checks */
00766     if (p == NULL || p->buffer == NULL || p->cursor < p->buffer || p->cursor >= p->max)
00767         return 0;
00768 
00769     /* clear parser token */
00770     p->tokenSize = 0;
00771     p->token[0] = '\0';
00772     old = p->cursor;
00773 
00774     /* skip whitespaces */
00775     while (p->cursor < p->max && *p->cursor <= ' ') {
00776         if (*p->cursor == '\n') {
00777             p->curLine++;
00778             hasLFs++;
00779         }
00780         p->cursor++;
00781     }
00782     /* return if we're not allowed to go beyond lfs */
00783     if ((hasLFs > 0) && !allowLFs) {
00784         p->cursor = old;
00785         return 0;
00786     }
00787     /* get next quoted string */
00788     if (*p->cursor == '\"' && handleQuoted) {
00789         p->cursor++;
00790         while (p->cursor < p->max && *p->cursor) {
00791             if (*p->cursor == '\\') {
00792                 if (*(p->cursor + 1) == '"') {
00793                     p->cursor++;
00794                 }
00795                 p->token[p->tokenSize++] = *p->cursor++;
00796                 continue;
00797             } else if (*p->cursor == '\"') {
00798                 p->cursor++;
00799                 break;
00800             } else if (*p->cursor == '\n') {
00801                 p->curLine++;
00802             }
00803             p->token[p->tokenSize++] = *p->cursor++;
00804         }
00805         /* terminate token */
00806         p->token[p->tokenSize] = '\0';
00807         return 1;
00808     }
00809     /* otherwise get next word */
00810     while (p->cursor < p->max && *p->cursor > 32) {
00811         if (*p->cursor == '\n') {
00812             p->curLine++;
00813         }
00814         p->token[p->tokenSize++] = *p->cursor++;
00815     }
00816     /* terminate token */
00817     p->token[p->tokenSize] = '\0';
00818     return 1;
00819 }
00820 
00825 char *_pico_parse_first (picoParser_t *p)
00826 {
00827     /* sanity check */
00828     if (p == NULL)
00829         return NULL;
00830 
00831     /* try to read next token (with lfs & quots) */
00832     if (!_pico_parse_ex(p, 1, 1))
00833         return NULL;
00834 
00835     /* return ptr to the token string */
00836     return p->token;
00837 }
00838 
00844 char *_pico_parse (picoParser_t *p, int allowLFs)
00845 {
00846     /* sanity check */
00847     if (p == NULL)
00848         return NULL;
00849 
00850     /* try to read next token (with quots) */
00851     if (!_pico_parse_ex(p, allowLFs, 1))
00852         return NULL;
00853 
00854     /* return ptr to the token string */
00855     return p->token;
00856 }
00857 
00861 void _pico_parse_skip_rest (picoParser_t *p)
00862 {
00863     while (_pico_parse_ex(p, 0, 0)) {
00864     }
00865 }
00866 
00872 int _pico_parse_skip_braced (picoParser_t *p)
00873 {
00874     int firstToken = 1;
00875     int level;
00876 
00877     /* sanity check */
00878     if (p == NULL)
00879         return 0;
00880 
00881     /* set the initial level for parsing */
00882     level = 0;
00883 
00884     /* skip braced section */
00885     while (1) {
00886         /* read next token (lfs allowed) */
00887         if (!_pico_parse_ex(p, 1, 1)) {
00888             /* end of parser buffer reached */
00889             return 0;
00890         }
00891         /* first token must be an opening bracket */
00892         if (firstToken && p->token[0] != '{') {
00893             /* opening bracket missing */
00894             return 0;
00895         }
00896         /* we only check this once */
00897         firstToken = 0;
00898 
00899         /* update level */
00900         if (p->token[1] == '\0') {
00901             if (p->token[0] == '{')
00902                 level++;
00903             else if (p->token[0] == '}')
00904                 level--;
00905         }
00906         /* break if we're back at our starting level */
00907         if (level == 0)
00908             break;
00909     }
00910     /* successfully skipped braced section */
00911     return 1;
00912 }
00913 
00914 int _pico_parse_check (picoParser_t *p, int allowLFs, char *str)
00915 {
00916     if (!_pico_parse_ex(p, allowLFs, 1))
00917         return 0;
00918     if (!strcmp(p->token, str))
00919         return 1;
00920     return 0;
00921 }
00922 
00923 int _pico_parse_checki (picoParser_t *p, int allowLFs, char *str)
00924 {
00925     if (!_pico_parse_ex(p, allowLFs, 1))
00926         return 0;
00927     if (!_pico_stricmp(p->token, str))
00928         return 1;
00929     return 0;
00930 }
00931 
00932 int _pico_parse_int (picoParser_t *p, int *out)
00933 {
00934     char *token;
00935 
00936     /* sanity checks */
00937     if (p == NULL || out == NULL)
00938         return 0;
00939 
00940     /* get token and turn it into an integer */
00941     *out = 0;
00942     token = _pico_parse(p, 0);
00943     if (token == NULL)
00944         return 0;
00945     *out = atoi(token);
00946 
00947     /* success */
00948     return 1;
00949 }
00950 
00951 int _pico_parse_int_def (picoParser_t *p, int *out, int def)
00952 {
00953     char *token;
00954 
00955     /* sanity checks */
00956     if (p == NULL || out == NULL)
00957         return 0;
00958 
00959     /* get token and turn it into an integer */
00960     *out = def;
00961     token = _pico_parse(p, 0);
00962     if (token == NULL)
00963         return 0;
00964     *out = atoi(token);
00965 
00966     /* success */
00967     return 1;
00968 }
00969 
00970 int _pico_parse_float (picoParser_t *p, float *out)
00971 {
00972     char *token;
00973 
00974     /* sanity checks */
00975     if (p == NULL || out == NULL)
00976         return 0;
00977 
00978     /* get token and turn it into a float */
00979     *out = 0.0f;
00980     token = _pico_parse(p, 0);
00981     if (token == NULL)
00982         return 0;
00983     *out = (float) atof(token);
00984 
00985     /* success */
00986     return 1;
00987 }
00988 
00989 int _pico_parse_float_def (picoParser_t *p, float *out, float def)
00990 {
00991     char *token;
00992 
00993     /* sanity checks */
00994     if (p == NULL || out == NULL)
00995         return 0;
00996 
00997     /* get token and turn it into a float */
00998     *out = def;
00999     token = _pico_parse(p, 0);
01000     if (token == NULL)
01001         return 0;
01002     *out = (float) atof(token);
01003 
01004     /* success */
01005     return 1;
01006 }
01007 
01008 int _pico_parse_vec (picoParser_t *p, picoVec3_t out)
01009 {
01010     char *token;
01011     int i;
01012 
01013     /* sanity checks */
01014     if (p == NULL || out == NULL)
01015         return 0;
01016 
01017     /* zero out outination vector */
01018     _pico_zero_vec(out);
01019 
01020     /* parse three vector components */
01021     for (i = 0; i < 3; i++) {
01022         token = _pico_parse(p, 0);
01023         if (token == NULL) {
01024             _pico_zero_vec(out);
01025             return 0;
01026         }
01027         out[i] = (float) atof(token);
01028     }
01029     /* success */
01030     return 1;
01031 }
01032 
01033 int _pico_parse_vec_def (picoParser_t *p, picoVec3_t out, picoVec3_t def)
01034 {
01035     char *token;
01036     int i;
01037 
01038     /* sanity checks */
01039     if (p == NULL || out == NULL)
01040         return 0;
01041 
01042     /* assign default vector value */
01043     _pico_copy_vec(def, out);
01044 
01045     /* parse three vector components */
01046     for (i = 0; i < 3; i++) {
01047         token = _pico_parse(p, 0);
01048         if (token == NULL) {
01049             _pico_copy_vec(def, out);
01050             return 0;
01051         }
01052         out[i] = (float) atof(token);
01053     }
01054     /* success */
01055     return 1;
01056 }
01057 
01058 int _pico_parse_vec2 (picoParser_t *p, picoVec2_t out)
01059 {
01060     char *token;
01061     int i;
01062 
01063     /* sanity checks */
01064     if (p == NULL || out == NULL)
01065         return 0;
01066 
01067     /* zero out outination vector */
01068     _pico_zero_vec2(out);
01069 
01070     /* parse two vector components */
01071     for (i = 0; i < 2; i++) {
01072         token = _pico_parse(p, 0);
01073         if (token == NULL) {
01074             _pico_zero_vec2(out);
01075             return 0;
01076         }
01077         out[i] = (float) atof(token);
01078     }
01079     /* success */
01080     return 1;
01081 }
01082 
01083 int _pico_parse_vec2_def (picoParser_t *p, picoVec2_t out, picoVec2_t def)
01084 {
01085     char *token;
01086     int i;
01087 
01088     /* sanity checks */
01089     if (p == NULL || out == NULL)
01090         return 0;
01091 
01092     /* assign default vector value */
01093     _pico_copy_vec2(def, out);
01094 
01095     /* parse two vector components */
01096     for (i = 0; i < 2; i++) {
01097         token = _pico_parse(p, 0);
01098         if (token == NULL) {
01099             _pico_copy_vec2(def, out);
01100             return 0;
01101         }
01102         out[i] = (float) atof(token);
01103     }
01104     /* success */
01105     return 1;
01106 }
01107 
01108 int _pico_parse_vec4 (picoParser_t *p, picoVec4_t out)
01109 {
01110     char *token;
01111     int i;
01112 
01113     /* sanity checks */
01114     if (p == NULL || out == NULL)
01115         return 0;
01116 
01117     /* zero out outination vector */
01118     _pico_zero_vec4(out);
01119 
01120     /* parse four vector components */
01121     for (i = 0; i < 4; i++) {
01122         token = _pico_parse(p, 0);
01123         if (token == NULL) {
01124             _pico_zero_vec4(out);
01125             return 0;
01126         }
01127         out[i] = (float) atof(token);
01128     }
01129     /* success */
01130     return 1;
01131 }
01132 
01133 int _pico_parse_vec4_def (picoParser_t *p, picoVec4_t out, picoVec4_t def)
01134 {
01135     char *token;
01136     int i;
01137 
01138     /* sanity checks */
01139     if (p == NULL || out == NULL)
01140         return 0;
01141 
01142     /* assign default vector value */
01143     _pico_copy_vec4(def, out);
01144 
01145     /* parse four vector components */
01146     for (i = 0; i < 4; i++) {
01147         token = _pico_parse(p, 0);
01148         if (token == NULL) {
01149             _pico_copy_vec4(def, out);
01150             return 0;
01151         }
01152         out[i] = (float) atof(token);
01153     }
01154     /* success */
01155     return 1;
01156 }
01157 
01161 picoMemStream_t *_pico_new_memstream (picoByte_t *buffer, int bufSize)
01162 {
01163     picoMemStream_t *s;
01164 
01165     /* sanity check */
01166     if (buffer == NULL || bufSize <= 0)
01167         return NULL;
01168 
01169     /* allocate stream */
01170     s = _pico_alloc(sizeof(*s));
01171     if (s == NULL)
01172         return NULL;
01173     memset(s, 0, sizeof(*s));
01174 
01175     /* setup */
01176     s->buffer = buffer;
01177     s->curPos = buffer;
01178     s->bufSize = bufSize;
01179     s->flag = 0;
01180 
01181     /* return ptr to stream */
01182     return s;
01183 }
01184 
01188 void _pico_free_memstream (picoMemStream_t *s)
01189 {
01190     /* sanity check */
01191     if (s == NULL)
01192         return;
01193 
01194     /* free the stream */
01195     _pico_free(s);
01196 }
01197 
01201 int _pico_memstream_read (picoMemStream_t *s, void *buffer, int len)
01202 {
01203     int ret = 1;
01204 
01205     /* sanity checks */
01206     if (s == NULL || buffer == NULL)
01207         return 0;
01208 
01209     if (s->curPos + len > s->buffer + s->bufSize) {
01210         s->flag |= PICO_IOEOF;
01211         len = s->buffer + s->bufSize - s->curPos;
01212         ret = 0;
01213     }
01214 
01215     /* read the data */
01216     memcpy(buffer, s->curPos, len);
01217     s->curPos += len;
01218     return ret;
01219 }
01220 
01224 int _pico_memstream_getc (picoMemStream_t *s)
01225 {
01226     int c = 0;
01227 
01228     /* sanity check */
01229     if (s == NULL)
01230         return -1;
01231 
01232     /* read the character */
01233     if (_pico_memstream_read(s, &c, 1) == 0)
01234         return -1;
01235 
01236     return c;
01237 }
01238 
01242 int _pico_memstream_seek (picoMemStream_t *s, long offset, int origin)
01243 {
01244     int overflow;
01245 
01246     /* sanity check */
01247     if (s == NULL)
01248         return -1;
01249 
01250     if (origin == PICO_SEEK_SET) {
01251         s->curPos = s->buffer + offset;
01252         overflow = s->curPos - (s->buffer + s->bufSize);
01253         if (overflow > 0) {
01254             s->curPos = s->buffer + s->bufSize;
01255             return offset - overflow;
01256         }
01257         return 0;
01258     } else if (origin == PICO_SEEK_CUR) {
01259         s->curPos += offset;
01260         overflow = s->curPos - (s->buffer + s->bufSize);
01261         if (overflow > 0) {
01262             s->curPos = s->buffer + s->bufSize;
01263             return offset - overflow;
01264         }
01265         return 0;
01266     } else if (origin == PICO_SEEK_END) {
01267         s->curPos = (s->buffer + s->bufSize) - offset;
01268         overflow = s->buffer - s->curPos;
01269         if (overflow > 0) {
01270             s->curPos = s->buffer;
01271             return offset - overflow;
01272         }
01273         return 0;
01274     }
01275 
01276     return -1;
01277 }
01278 
01282 long _pico_memstream_tell (picoMemStream_t *s)
01283 {
01284     /* sanity check */
01285     if (s == NULL)
01286         return -1;
01287 
01288     return s->curPos - s->buffer;
01289 }

Generated by  doxygen 1.6.2