00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define PICOINTERNAL_C
00037
00040
00041 #include <string.h>
00042 #include "picointernal.h"
00043
00044
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
00065 if (size == 0)
00066 return NULL;
00067 if (_pico_ptr_malloc == NULL)
00068 return NULL;
00069
00070
00071 ptr = _pico_ptr_malloc(size);
00072 if (ptr == NULL)
00073 return NULL;
00074
00075
00076 memset(ptr, 0, size);
00077
00078
00079 return ptr;
00080 }
00081
00085 void *_pico_calloc (size_t num, size_t size)
00086 {
00087 void *ptr;
00088
00089
00090 if (num == 0 || size == 0)
00091 return NULL;
00092 if (_pico_ptr_malloc == NULL)
00093 return NULL;
00094
00095
00096 ptr = _pico_ptr_malloc(num * size);
00097 if (ptr == NULL)
00098 return NULL;
00099
00100
00101 memset(ptr, 0, num * size);
00102
00103
00104 return ptr;
00105 }
00106
00110 void *_pico_realloc (void **ptr, size_t oldSize, size_t newSize)
00111 {
00112 void *ptr2;
00113
00114
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
00123 ptr2 = _pico_alloc(newSize);
00124 if (ptr2 == NULL)
00125 return NULL;
00126
00127
00128 if (*ptr != NULL) {
00129 memcpy(ptr2, *ptr, oldSize);
00130 _pico_free(*ptr);
00131 }
00132
00133
00134 *ptr = ptr2;
00135 return *ptr;
00136 }
00137
00147 char *_pico_clone_alloc (const char *str)
00148 {
00149 char* cloned;
00150
00151
00152 if (str == NULL)
00153 return NULL;
00154
00155
00156 cloned = _pico_alloc(strlen(str) + 1);
00157 if (cloned == NULL)
00158 return NULL;
00159
00160
00161 strcpy(cloned, str);
00162
00163
00164 return cloned;
00165 }
00166
00170 void _pico_free (void *ptr)
00171 {
00172
00173 if (ptr == NULL)
00174 return;
00175 if (_pico_ptr_free == NULL)
00176 return;
00177
00178
00179 _pico_ptr_free(ptr);
00180 }
00181
00185 void _pico_load_file (char *name, unsigned char **buffer, int *bufSize)
00186 {
00187
00188 if (name == NULL) {
00189 *bufSize = -1;
00190 return;
00191 }
00192 if (_pico_ptr_load_file == NULL) {
00193 *bufSize = -1;
00194 return;
00195 }
00196
00197
00198 _pico_ptr_load_file(name, buffer, bufSize);
00199 }
00200
00204 void _pico_free_file (void *buffer)
00205 {
00206
00207 if (buffer == NULL)
00208 return;
00209
00210
00211 if (_pico_ptr_free_file == NULL) {
00212 free(buffer);
00213 return;
00214 }
00215
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
00228 if (format == NULL)
00229 return;
00230 if (_pico_ptr_print == NULL)
00231 return;
00232
00233
00234 va_start(argptr,format);
00235 vsprintf(str, format, argptr);
00236 va_end(argptr);
00237
00238
00239 if (str[strlen(str) - 1] == '\n')
00240 str[strlen(str) - 1] = '\0';
00241
00242
00243 _pico_ptr_print(level, str);
00244 }
00245
00246
00247
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
00260
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')
00270 *str1++ = *str2++;
00271 return str;
00272 }
00273
00274
00275
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
00300
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
00314
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
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
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
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
00551
00552
00553
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
00570
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
00585
00586
00587
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
00612
00613
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
00633
00634
00635
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
00669
00670
00671
00672
00673
00674 int _pico_getline (char *buf, int bufsize, char *dest, int destsize)
00675 {
00676 int pos;
00677
00678
00679 if (dest == NULL || destsize < 1)
00680 return -1;
00681 memset(dest, 0, destsize);
00682
00683
00684 if (buf == NULL || bufsize < 1)
00685 return -1;
00686
00687
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
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
00708 if (buffer == NULL || bufSize <= 0)
00709 return NULL;
00710
00711
00712 p = _pico_alloc(sizeof(*p));
00713 if (p == NULL)
00714 return NULL;
00715 memset(p, 0, sizeof(*p));
00716
00717
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
00726 p->buffer = (char *) buffer;
00727 p->cursor = (char *) buffer;
00728 p->bufSize = bufSize;
00729 p->max = p->buffer + bufSize;
00730 p->curLine = 1;
00731
00732
00733 return p;
00734 }
00735
00739 void _pico_free_parser (picoParser_t *p)
00740 {
00741
00742 if (p == NULL)
00743 return;
00744
00745
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
00766 if (p == NULL || p->buffer == NULL || p->cursor < p->buffer || p->cursor >= p->max)
00767 return 0;
00768
00769
00770 p->tokenSize = 0;
00771 p->token[0] = '\0';
00772 old = p->cursor;
00773
00774
00775 while (p->cursor < p->max && *p->cursor <= ' ') {
00776 if (*p->cursor == '\n') {
00777 p->curLine++;
00778 hasLFs++;
00779 }
00780 p->cursor++;
00781 }
00782
00783 if ((hasLFs > 0) && !allowLFs) {
00784 p->cursor = old;
00785 return 0;
00786 }
00787
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
00806 p->token[p->tokenSize] = '\0';
00807 return 1;
00808 }
00809
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
00817 p->token[p->tokenSize] = '\0';
00818 return 1;
00819 }
00820
00825 char *_pico_parse_first (picoParser_t *p)
00826 {
00827
00828 if (p == NULL)
00829 return NULL;
00830
00831
00832 if (!_pico_parse_ex(p, 1, 1))
00833 return NULL;
00834
00835
00836 return p->token;
00837 }
00838
00844 char *_pico_parse (picoParser_t *p, int allowLFs)
00845 {
00846
00847 if (p == NULL)
00848 return NULL;
00849
00850
00851 if (!_pico_parse_ex(p, allowLFs, 1))
00852 return NULL;
00853
00854
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
00878 if (p == NULL)
00879 return 0;
00880
00881
00882 level = 0;
00883
00884
00885 while (1) {
00886
00887 if (!_pico_parse_ex(p, 1, 1)) {
00888
00889 return 0;
00890 }
00891
00892 if (firstToken && p->token[0] != '{') {
00893
00894 return 0;
00895 }
00896
00897 firstToken = 0;
00898
00899
00900 if (p->token[1] == '\0') {
00901 if (p->token[0] == '{')
00902 level++;
00903 else if (p->token[0] == '}')
00904 level--;
00905 }
00906
00907 if (level == 0)
00908 break;
00909 }
00910
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
00937 if (p == NULL || out == NULL)
00938 return 0;
00939
00940
00941 *out = 0;
00942 token = _pico_parse(p, 0);
00943 if (token == NULL)
00944 return 0;
00945 *out = atoi(token);
00946
00947
00948 return 1;
00949 }
00950
00951 int _pico_parse_int_def (picoParser_t *p, int *out, int def)
00952 {
00953 char *token;
00954
00955
00956 if (p == NULL || out == NULL)
00957 return 0;
00958
00959
00960 *out = def;
00961 token = _pico_parse(p, 0);
00962 if (token == NULL)
00963 return 0;
00964 *out = atoi(token);
00965
00966
00967 return 1;
00968 }
00969
00970 int _pico_parse_float (picoParser_t *p, float *out)
00971 {
00972 char *token;
00973
00974
00975 if (p == NULL || out == NULL)
00976 return 0;
00977
00978
00979 *out = 0.0f;
00980 token = _pico_parse(p, 0);
00981 if (token == NULL)
00982 return 0;
00983 *out = (float) atof(token);
00984
00985
00986 return 1;
00987 }
00988
00989 int _pico_parse_float_def (picoParser_t *p, float *out, float def)
00990 {
00991 char *token;
00992
00993
00994 if (p == NULL || out == NULL)
00995 return 0;
00996
00997
00998 *out = def;
00999 token = _pico_parse(p, 0);
01000 if (token == NULL)
01001 return 0;
01002 *out = (float) atof(token);
01003
01004
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
01014 if (p == NULL || out == NULL)
01015 return 0;
01016
01017
01018 _pico_zero_vec(out);
01019
01020
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
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
01039 if (p == NULL || out == NULL)
01040 return 0;
01041
01042
01043 _pico_copy_vec(def, out);
01044
01045
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
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
01064 if (p == NULL || out == NULL)
01065 return 0;
01066
01067
01068 _pico_zero_vec2(out);
01069
01070
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
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
01089 if (p == NULL || out == NULL)
01090 return 0;
01091
01092
01093 _pico_copy_vec2(def, out);
01094
01095
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
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
01114 if (p == NULL || out == NULL)
01115 return 0;
01116
01117
01118 _pico_zero_vec4(out);
01119
01120
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
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
01139 if (p == NULL || out == NULL)
01140 return 0;
01141
01142
01143 _pico_copy_vec4(def, out);
01144
01145
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
01155 return 1;
01156 }
01157
01161 picoMemStream_t *_pico_new_memstream (picoByte_t *buffer, int bufSize)
01162 {
01163 picoMemStream_t *s;
01164
01165
01166 if (buffer == NULL || bufSize <= 0)
01167 return NULL;
01168
01169
01170 s = _pico_alloc(sizeof(*s));
01171 if (s == NULL)
01172 return NULL;
01173 memset(s, 0, sizeof(*s));
01174
01175
01176 s->buffer = buffer;
01177 s->curPos = buffer;
01178 s->bufSize = bufSize;
01179 s->flag = 0;
01180
01181
01182 return s;
01183 }
01184
01188 void _pico_free_memstream (picoMemStream_t *s)
01189 {
01190
01191 if (s == NULL)
01192 return;
01193
01194
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
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
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
01229 if (s == NULL)
01230 return -1;
01231
01232
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
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
01285 if (s == NULL)
01286 return -1;
01287
01288 return s->curPos - s->buffer;
01289 }