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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 #include <string.h>
00106 #include <stdlib.h>
00107 #include <stdio.h>
00108 #include <unistd.h>
00109 #include <ctype.h>
00110
00111 #include "keyValuePair.h"
00112
00113
00114
00115
00116
00117
00118
00119
00120 static char* keyPtrs[MAXKEYS] ;
00121 static char* valPtrs[MAXKEYS] ;
00122 static KeyType valTypes[MAXKEYS] ;
00123 static int nelements[MAXKEYS] ;
00124 static int nkeys = 0 ;
00125 static char* kvpBuffer = NULL ;
00126 static int kvpBufferSize ;
00127 static char* spare = NULL ;
00128 static int spaceLeft = 0 ;
00129 static KvpErrorCode lastError = KVP_E_OK ;
00130
00131
00132
00133 static void kvpRealloc (
00134 int minExtension
00135 )
00136 {
00137 char* newBuffer ;
00138 int newSize;
00139 int item ;
00140 int length ;
00141 int extension ;
00142
00143
00144 if (minExtension < KVP_MIN_BUFFER_SIZE) {
00145 extension = KVP_MIN_BUFFER_SIZE ;
00146 }
00147 else {
00148 extension = minExtension ;
00149 }
00150
00151 newSize = kvpBufferSize + extension ;
00152 newBuffer = malloc (newSize) ;
00153 spare = newBuffer ;
00154 spaceLeft = newSize ;
00155
00156
00157 for (item = 0; item < nkeys; item++) {
00158 keyPtrs[item] = strcpy (spare, keyPtrs[item]) ;
00159 length = strlen (keyPtrs[item]) + 1 ;
00160 spare += length ;
00161 spaceLeft -= length ;
00162
00163 valPtrs[item] = strcpy (spare, valPtrs[item]) ;
00164 length = strlen (valPtrs[item]) + 1 ;
00165 spare += length ;
00166 spaceLeft -= length ;
00167 }
00168
00169
00170 free (kvpBuffer) ;
00171 kvpBuffer = newBuffer ;
00172 kvpBufferSize = newSize ;
00173 }
00174
00175 void kvpDumpInternals (void)
00176 {
00177 printf ("kvpBuffer=%p spare=%p kvpBufferSize=%d spaceLeft=%d nkeys=%d\n",
00178 kvpBuffer,
00179 spare,
00180 kvpBufferSize,
00181 spaceLeft,
00182 nkeys) ;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 static char* stripSpaces (char* string)
00195 {
00196 char* endPtr ;
00197 char* tPtr;
00198
00199 while (isspace(*string)) {
00200 string++ ;
00201 }
00202
00203 tPtr = string ;
00204 endPtr = string ;
00205 while (*tPtr != 0) {
00206 if (!isspace (*tPtr)) {
00207 endPtr = tPtr ;
00208 }
00209 tPtr++ ;
00210 }
00211 *(endPtr + 1) = 0 ;
00212
00213 return (string) ;
00214 }
00215
00216 static int validateValue (
00217 char* value,
00218 KeyType valType
00219 )
00220 {
00221 int inNumber ;
00222 int hexCandidate ;
00223 int octalCandidate ;
00224 int decimalPoint ;
00225 int digit ;
00226 int count ;
00227 int exponent ;
00228
00229 count = 0 ;
00230 inNumber = 0 ;
00231 hexCandidate = 0 ;
00232 octalCandidate = 0 ;
00233 decimalPoint = 0 ;
00234 exponent = 0 ;
00235 while (*value != 0) {
00236 if (valType == KT_STRING) {
00237 count++ ;
00238 }
00239 else {
00240 if (hexCandidate == 2) {
00241 digit = isxdigit (*value) ;
00242 }
00243 else {
00244 digit = isdigit (*value) ;
00245 if ((octalCandidate == 1) && (*value > '7')) {
00246 lastError = KVP_E_ILLNUMBER ;
00247 return (-1) ;
00248 }
00249 }
00250 if (digit) {
00251 if (!inNumber) {
00252 count++ ;
00253 inNumber = 1 ;
00254 if ((*value == '0') && valType == KT_INT) {
00255
00256 hexCandidate = 1;
00257 }
00258 else {
00259 hexCandidate = 0;
00260 }
00261 }
00262 else if (hexCandidate == 1) {
00263
00264
00265 hexCandidate = 0 ;
00266 octalCandidate = 1 ;
00267
00268 if (*value > '7') {
00269 lastError = KVP_E_ILLNUMBER ;
00270 return (-1) ;
00271 }
00272 }
00273 }
00274 else {
00275 if ((hexCandidate == 1) && tolower (*value) == 'x') {
00276 hexCandidate = 2 ;
00277 }
00278 else if ((*value == '+') || (*value == '-')) {
00279 if (inNumber) {
00280 if (exponent != 1) {
00281
00282 lastError = KVP_E_ILLNUMBER ;
00283 return (-1) ;
00284 }
00285 }
00286 else {
00287 inNumber = 1 ;
00288 count++ ;
00289 }
00290 }
00291 else if ((valType == KT_FLOAT) && (*value == '.')) {
00292 if (decimalPoint == 0) {
00293 decimalPoint = 1 ;
00294 }
00295 else {
00296 lastError = KVP_E_ILLNUMBER ;
00297 return (-1) ;
00298 }
00299 }
00300 else if ((valType == KT_FLOAT) && tolower(*value) == 'e') {
00301 if (exponent == 0) {
00302 exponent = 1 ;
00303 }
00304 else {
00305 lastError = KVP_E_ILLNUMBER ;
00306 return (-1) ;
00307 }
00308 }
00309 else {
00310 if ((*value == ' ') || (*value == '\t') ||
00311 (*value == ',')) {
00312 inNumber = 0 ;
00313 hexCandidate = 0 ;
00314 octalCandidate = 0 ;
00315 decimalPoint = 0 ;
00316 exponent = 0 ;
00317 }
00318 else {
00319 lastError = KVP_E_ILLNUMBER ;
00320 return (-1) ;
00321 }
00322 }
00323 }
00324 }
00325 value++ ;
00326 }
00327 return (count) ;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 int kvpFindKey (
00340 const char* key
00341 )
00342 {
00343 int keynum ;
00344 int candidate ;
00345 const char* kStart ;
00346 int kLength ;
00347
00348 candidate = -1 ;
00349 kStart = key ;
00350 while (isspace(*kStart)) {
00351 kStart++ ;
00352 }
00353 kLength = strlen (kStart) ;
00354 while ((kLength > 0) && isspace (kStart[kLength-1])) {
00355 kLength-- ;
00356 }
00357
00358 for (keynum = 0 ; keynum < nkeys ; keynum++) {
00359 if ((strncmp (kStart, keyPtrs[keynum], kLength) == 0) &&
00360 (strlen (keyPtrs[keynum]) == (size_t)kLength)) {
00361 candidate = keynum ;
00362 }
00363 }
00364 return (candidate) ;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377 static int kvpGetBase (
00378 const char* key,
00379 int defaultValue,
00380 int radix
00381 )
00382 {
00383 int value ;
00384 int kValue ;
00385 char* valString ;
00386 char* endPtr ;
00387
00388 value = defaultValue ;
00389
00390 valString = kvpGetString (key) ;
00391 if (valString != NULL) {
00392 kValue = strtol (valString, &endPtr, radix) ;
00393 if (valString != endPtr) {
00394 value = kValue ;
00395 lastError = KVP_E_OK ;
00396 }
00397 else {
00398 lastError = KVP_E_BADVALUE ;
00399 }
00400 }
00401 else {
00402 lastError = KVP_E_NOTFOUND ;
00403 }
00404 return (value) ;
00405 }
00406
00407 #ifndef VxWorks
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 static KvpErrorCode kvpSet (
00418 const char *key,
00419 const void *value,
00420 KeyType type,
00421 int count
00422 )
00423 {
00424 int nchars ;
00425 int element ;
00426 int* iPtr ;
00427 float* fPtr ;
00428 int entry ;
00429 int valueSpace ;
00430 int keyLength ;
00431 int requiredSpace ;
00432
00433
00434 if (spare == NULL) {
00435 kvpInit (0) ;
00436 }
00437
00438
00439 entry = kvpFindKey (key) ;
00440 if (entry >= 0) {
00441 lastError = KVP_E_DUPLICATE ;
00442 return (lastError) ;
00443 }
00444
00445
00446 if (nkeys >= MAXKEYS) {
00447 lastError = KVP_E_TOOMANY ;
00448 return (lastError) ;
00449 }
00450
00451 keyLength = strlen (key) + 1 ;
00452 requiredSpace = keyLength ;
00453 switch (type) {
00454 case KT_INT:
00455 requiredSpace += count * MAX_INT_LENGTH;
00456 break;
00457 case KT_FLOAT:
00458 requiredSpace += count * MAX_FLOAT_LENGTH;
00459 break;
00460 case KT_STRING:
00461 requiredSpace += strlen (value) ;
00462 break;
00463 default:
00464 lastError = KVP_E_BADTYPE ;
00465 return (lastError) ;
00466 }
00467
00468
00469 if (spaceLeft < requiredSpace) {
00470 kvpRealloc (requiredSpace) ;
00471 }
00472
00473
00474 keyPtrs[nkeys] = spare ;
00475 nchars = snprintf (spare, spaceLeft, "%s", key) ;
00476 if (nchars < 0) {
00477 lastError = KVP_E_SYSTEM ;
00478 return (lastError) ;
00479 }
00480
00481
00482 if (strcspn (key, "=;,#") != (size_t)nchars) {
00483 lastError = KVP_E_BADKEY ;
00484 return (lastError) ;
00485 }
00486
00487
00488 nchars++ ;
00489 valueSpace = spaceLeft - nchars ;
00490
00491 valPtrs[nkeys] = spare + nchars ;
00492
00493 switch (type) {
00494 case KT_INT:
00495 iPtr = (int*) value ;
00496 for (element = 0 ; element < count ; element++) {
00497 if (element > 0) {
00498 spare[nchars++] = ',' ;
00499 }
00500 nchars += snprintf (spare+nchars, valueSpace,
00501 "%i", iPtr[element]) ;
00502 valueSpace = spaceLeft - nchars ;
00503 if (valueSpace < 1) {
00504
00505 lastError = KVP_E_TOOLONG ;
00506 return (lastError) ;
00507 }
00508 }
00509 break ;
00510 case KT_FLOAT:
00511 fPtr = (float*) value ;
00512 for (element = 0 ; element < count ; element++) {
00513 if (element > 0) {
00514 spare[nchars++] = ',' ;
00515 }
00516 nchars += snprintf (spare+nchars, valueSpace,
00517 "%g", fPtr[element]) ;
00518 valueSpace = spaceLeft - nchars ;
00519 if (valueSpace < 1) {
00520
00521 lastError = KVP_E_TOOLONG ;
00522 return (lastError) ;
00523 }
00524 }
00525 break ;
00526 case KT_STRING:
00527 count = snprintf (spare+nchars, valueSpace,
00528 "%s", (char *) value) ;
00529 if (count > valueSpace) {
00530
00531 lastError = KVP_E_TOOLONG ;
00532 return (lastError) ;
00533 }
00534 nchars += count ;
00535 break ;
00536 default:
00537 lastError = KVP_E_BADTYPE ;
00538 return (lastError) ;
00539 break ;
00540 }
00541 if (nchars < 0) {
00542 lastError = KVP_E_SYSTEM ;
00543 return (lastError) ;
00544 }
00545
00546 valTypes[nkeys] = type ;
00547 nelements[nkeys] = count ;
00548 nkeys++ ;
00549
00550 nchars++ ;
00551 spare += nchars ;
00552 spaceLeft -= nchars ;
00553
00554 lastError = KVP_E_OK ;
00555 return (lastError) ;
00556 }
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 static KvpErrorCode kvpUpdate (
00570 const char *key,
00571 const void *value,
00572 KeyType type,
00573 int count
00574 )
00575 {
00576 int nchars ;
00577 int element ;
00578 int* iPtr ;
00579 float* fPtr ;
00580 int entry ;
00581 int requiredSpace ;
00582
00583
00584 entry = kvpFindKey (key) ;
00585 if (entry < 0) {
00586 lastError = KVP_E_NOTFOUND ;
00587 return (lastError) ;
00588 }
00589
00590 if (valTypes[entry] != type) {
00591 lastError = KVP_E_BADVALUE ;
00592 return (lastError) ;
00593 }
00594
00595 switch (type) {
00596 case KT_INT:
00597 requiredSpace = count * MAX_INT_LENGTH;
00598 break;
00599 case KT_FLOAT:
00600 requiredSpace = count * MAX_FLOAT_LENGTH;
00601 break;
00602 case KT_STRING:
00603 requiredSpace = strlen (value) ;
00604 break;
00605 default:
00606 lastError = KVP_E_BADTYPE ;
00607 return (lastError) ;
00608 break ;
00609 }
00610
00611 if (spaceLeft < requiredSpace) {
00612 kvpRealloc (requiredSpace) ;
00613 }
00614
00615
00616
00617 nchars = 0 ;
00618 valPtrs[entry] = spare ;
00619 switch (type) {
00620 case KT_INT:
00621 iPtr = (int*) value ;
00622 for (element = 0 ; element < count ; element++) {
00623 if (element > 0) {
00624 spare[nchars++] = ',' ;
00625 }
00626 nchars += snprintf (spare+nchars, spaceLeft-nchars,
00627 "%i", iPtr[element]) ;
00628 }
00629 break ;
00630 case KT_FLOAT:
00631 fPtr = (float*) value ;
00632 for (element = 0 ; element < count ; element++) {
00633 if (element > 0) {
00634 spare[nchars++] = ',' ;
00635 }
00636 nchars += snprintf (spare+nchars, spaceLeft-nchars,
00637 "%g", fPtr[element]) ;
00638 }
00639 break ;
00640 case KT_STRING:
00641 count = snprintf (spare+nchars, spaceLeft-nchars,
00642 "%s", (char *) value) ;
00643 nchars += count ;
00644 break ;
00645 default:
00646 lastError = KVP_E_BADTYPE ;
00647 return (lastError) ;
00648 }
00649 if (nchars < 0) {
00650 lastError = KVP_E_SYSTEM ;
00651 return (lastError) ;
00652 }
00653
00654 nelements[entry] = count ;
00655
00656 nchars++ ;
00657 spare += nchars ;
00658 spaceLeft -= nchars ;
00659
00660 lastError = KVP_E_OK ;
00661 return (lastError) ;
00662 }
00663 #endif
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 int kvpParse (
00675 const char* record
00676 )
00677 {
00678 char* myPtr ;
00679 char* key ;
00680 char* value ;
00681 char typeChar ;
00682 int count ;
00683 int reclen ;
00684 int oldKeyNumber ;
00685
00686
00687 reclen = strlen (record) + 1 ;
00688
00689 if (spare == NULL) {
00690 kvpInit (reclen) ;
00691 }
00692
00693 if (reclen > spaceLeft) {
00694 kvpRealloc (reclen) ;
00695 }
00696
00697
00698 strncpy (spare, record, reclen) ;
00699
00700 myPtr = spare;
00701 while (isspace(*myPtr)) {
00702 myPtr++ ;
00703 }
00704
00705
00706 do {
00707 key = myPtr ;
00708 myPtr = strchr (myPtr, '#') ;
00709
00710
00711 if (myPtr != NULL) {
00712 if (nkeys >= MAXKEYS) {
00713 lastError = KVP_E_TOOMANY ;
00714 return (-1) ;
00715 }
00716
00717 *myPtr++ = 0 ;
00718
00719 key = stripSpaces (key) ;
00720
00721 if ((key[0] == '/') && (key[1] == '/')) {
00722 myPtr = NULL ;
00723 break ;
00724 }
00725 keyPtrs[nkeys] = key ;
00726
00727
00728 oldKeyNumber = kvpFindKey (key) ;
00729 if (oldKeyNumber >= 0) {
00730 valTypes[oldKeyNumber] = KT_INVALID ;
00731 }
00732
00733
00734 typeChar = *myPtr++ ;
00735 switch (typeChar) {
00736 case 'I':
00737 valTypes[nkeys] = KT_INT ;
00738 break ;
00739 case 'F':
00740 valTypes[nkeys] = KT_FLOAT ;
00741 break ;
00742 case 'S':
00743 valTypes[nkeys] = KT_STRING ;
00744 break ;
00745 }
00746
00747
00748 if (*myPtr == '=') {
00749 nelements[nkeys] = 0 ;
00750 }
00751 else {
00752
00753 nelements[nkeys] = strtol (myPtr, &myPtr, 10) ;
00754 }
00755
00756
00757 if (*myPtr == '=') {
00758 myPtr++ ;
00759 value = myPtr ;
00760
00761 myPtr = strchr (myPtr, ';') ;
00762 if (myPtr == NULL) {
00763 lastError = KVP_E_TERMINATOR ;
00764 reclen++ ;
00765 }
00766 else {
00767
00768 *myPtr++ = 0 ;
00769 }
00770 valPtrs[nkeys] = value ;
00771
00772
00773
00774 count = validateValue (value, valTypes[nkeys]) ;
00775 if (count < 0) {
00776 return (count) ;
00777 }
00778 if (nelements[nkeys] == 0) {
00779 nelements[nkeys] = count ;
00780 }
00781 else if (nelements[nkeys] != count) {
00782 lastError = KVP_E_WRONGCOUNT ;
00783 return (-1) ;
00784 }
00785 nkeys++ ;
00786 }
00787 else {
00788 lastError = KVP_E_BADINPUT ;
00789 return (-1) ;
00790 }
00791 }
00792 } while (myPtr != NULL) ;
00793
00794 spare += reclen ;
00795 spaceLeft -= reclen ;
00796
00797 lastError = KVP_E_OK ;
00798 return (nkeys) ;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 void kvpReset (void)
00811 {
00812 if (kvpBuffer != NULL) {
00813 free (kvpBuffer) ;
00814 }
00815 spare = kvpBuffer = NULL ;
00816 spaceLeft = 0 ;
00817 nkeys = 0 ;
00818 }
00819
00820 void kvpInit (
00821 int bufferSize
00822 )
00823 {
00824 if (bufferSize > KVP_MIN_BUFFER_SIZE) {
00825 kvpBufferSize = bufferSize ;
00826 }
00827 else {
00828 kvpBufferSize = KVP_MIN_BUFFER_SIZE ;
00829 }
00830
00831 kvpBuffer = malloc(kvpBufferSize) ;
00832 spare = kvpBuffer ;
00833 spaceLeft = kvpBufferSize ;
00834 }
00835
00836 int kvpQueryLength (const char* key) {
00837 int keynum ;
00838
00839 keynum = kvpFindKey (key) ;
00840 if (keynum >= 0) {
00841 lastError = KVP_E_OK ;
00842 return (nelements[keynum]) ;
00843 }
00844 else {
00845 lastError = KVP_E_NOTFOUND ;
00846 return (0) ;
00847 }
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 KvpErrorCode kvpGetEntry (
00861 int entry,
00862 char** key,
00863 KeyType* type,
00864 int* size,
00865 char** value
00866 )
00867 {
00868 if (entry < nkeys) {
00869 *key = keyPtrs[entry] ;
00870 *type = valTypes[entry] ;
00871 *value = valPtrs[entry] ;
00872 *size = nelements[entry] ;
00873 return (KVP_E_OK) ;
00874 }
00875 else {
00876 return (KVP_E_NOTFOUND) ;
00877 }
00878 }
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889 char* kvpGetString (
00890 const char* key
00891 )
00892 {
00893 int keynum ;
00894
00895 keynum = kvpFindKey (key) ;
00896 if (keynum >= 0) {
00897 lastError = KVP_E_OK ;
00898 return (valPtrs[keynum]) ;
00899 }
00900 else {
00901 lastError = KVP_E_NOTFOUND ;
00902 return (NULL) ;
00903 }
00904 }
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915 KvpErrorCode kvpGetStringArray (
00916 const char* key,
00917 char* values,
00918 int maxlen,
00919 int* entries
00920 )
00921 {
00922 char* valString ;
00923 int index ;
00924 int element ;
00925 int length ;
00926 int end ;
00927
00928 lastError = KVP_E_OK ;
00929 index = kvpFindKey (key) ;
00930 if (index >= 0) {
00931 if (valTypes[index] == KT_STRING) {
00932 valString = valPtrs[index] ;
00933 }
00934 element = 0 ;
00935 length = 0 ;
00936 lastError = KVP_E_OK ;
00937 end = 0 ;
00938
00939 do {
00940 if (*valString == 0) {
00941 end = 1 ;
00942 }
00943
00944 if (*valString == ',') {
00945 values[element*maxlen+length] = 0 ;
00946 element++ ;
00947 length = 0 ;
00948 if (element == *entries) {
00949 lastError = KVP_E_TRUNCATE ;
00950 }
00951 }
00952 else {
00953 values[element*maxlen+length] = *valString ;
00954 length++ ;
00955 if (length == maxlen) {
00956 lastError = KVP_E_TRUNCATE ;
00957 }
00958 }
00959 valString++ ;
00960 } while (!end && (lastError == KVP_E_OK)) ;
00961
00962
00963 *entries = element + 1 ;
00964 }
00965 else {
00966 lastError = KVP_E_NOTFOUND ;
00967 }
00968 return (lastError) ;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 int kvpGetHex (
00981 const char* key,
00982 int defaultValue
00983 )
00984 {
00985 return (kvpGetBase (key, defaultValue, 16)) ;
00986 }
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 int kvpGetDec (
00998 const char* key,
00999 int defaultValue
01000 )
01001 {
01002 return (kvpGetBase (key, defaultValue, 10)) ;
01003 }
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016 int kvpGetInt (
01017 const char* key,
01018 int defaultValue
01019 )
01020 {
01021 return (kvpGetBase (key, defaultValue, 0)) ;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 KvpErrorCode kvpGetIntArray (
01035 const char* key,
01036 int* values,
01037 int* entries
01038 )
01039 {
01040 char* valString ;
01041 char* endPtr ;
01042 int index ;
01043 int element ;
01044
01045 lastError = KVP_E_OK ;
01046 index = kvpFindKey (key) ;
01047 if (index >= 0) {
01048 if (valTypes[index] == KT_INT) {
01049 valString = valPtrs[index] ;
01050
01051 if (nelements[index] <= *entries) {
01052 *entries = nelements[index] ;
01053 }
01054 else {
01055 lastError = KVP_E_TRUNCATE ;
01056 }
01057 for (element = 0 ; element < *entries ; element++) {
01058 values[element] = strtol (valString, &endPtr, 0) ;
01059 if (valString == endPtr) {
01060 lastError = KVP_E_BADVALUE ;
01061 lastError = KVP_E_BADVALUE ;
01062 break ;
01063 }
01064 valString = endPtr + 1 ;
01065 }
01066 }
01067 else {
01068 lastError = KVP_E_BADVALUE ;
01069 }
01070 }
01071 else {
01072 lastError = KVP_E_NOTFOUND ;
01073 }
01074 return (lastError) ;
01075 }
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 KvpErrorCode kvpGetFloatArray (
01088 const char* key,
01089 float* values,
01090 int* entries
01091 )
01092 {
01093 char* valString ;
01094 char* endPtr ;
01095 int index ;
01096 int element ;
01097
01098 lastError = KVP_E_OK ;
01099 index = kvpFindKey (key) ;
01100 if (index >= 0) {
01101 if (valTypes[index] == KT_FLOAT) {
01102 valString = valPtrs[index] ;
01103
01104 if (nelements[index] <= *entries) {
01105 *entries = nelements[index] ;
01106 }
01107 else {
01108 lastError = KVP_E_TRUNCATE ;
01109 }
01110 for (element = 0 ; element < *entries ; element++) {
01111 values[element] = strtod (valString, &endPtr) ;
01112 if (valString == endPtr) {
01113 lastError = KVP_E_BADVALUE ;
01114 lastError = KVP_E_BADVALUE ;
01115 break ;
01116 }
01117 valString = endPtr + 1 ;
01118 }
01119 }
01120 else {
01121 lastError = KVP_E_BADVALUE ;
01122 }
01123 }
01124 else {
01125 lastError = KVP_E_NOTFOUND ;
01126 }
01127 return (lastError) ;
01128 }
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139 double kvpGetDouble (
01140 const char* key,
01141 double defaultValue
01142 )
01143 {
01144 double value ;
01145 double kValue ;
01146 char* valString ;
01147 char* endPtr ;
01148
01149 value = defaultValue ;
01150
01151 valString = kvpGetString (key) ;
01152 if (valString != NULL) {
01153 kValue = strtod (valString, &endPtr) ;
01154 if (valString != endPtr) {
01155 value = kValue ;
01156 lastError = KVP_E_OK ;
01157 }
01158 else {
01159 lastError = KVP_E_BADVALUE ;
01160 }
01161 }
01162 else {
01163 lastError = KVP_E_NOTFOUND ;
01164 }
01165 return (value) ;
01166 }
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178 float kvpGetFloat (
01179 const char* key,
01180 float defaultValue
01181 )
01182 {
01183 return ((float) kvpGetDouble (key, (double) defaultValue)) ;
01184 }
01185
01186
01187 #ifndef VxWorks
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 KvpErrorCode kvpSetString (
01198 const char* key,
01199 const char* value
01200 )
01201 {
01202 return (kvpSet (key, value, KT_STRING, 1)) ;
01203 }
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 KvpErrorCode kvpSetIntArray (
01215 const char* key,
01216 const int* values,
01217 int count
01218 )
01219 {
01220 return (kvpSet (key, values, KT_INT, count)) ;
01221 }
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231 KvpErrorCode kvpSetFloatArray (
01232 const char* key,
01233 const float* values,
01234 int count
01235 )
01236 {
01237 return (kvpSet (key, values, KT_FLOAT, count)) ;
01238 }
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249 KvpErrorCode kvpSetInt (
01250 const char* key,
01251 int value
01252 )
01253 {
01254 return (kvpSet (key, &value, KT_INT, 1)) ;
01255 }
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266 KvpErrorCode kvpUpdateInt (
01267 const char* key,
01268 int value
01269 )
01270 {
01271 return (kvpUpdate (key, &value, KT_INT, 1)) ;
01272 }
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284 KvpErrorCode kvpSetFloat (
01285 const char* key,
01286 float value
01287 )
01288 {
01289 return (kvpSet (key, &value, KT_FLOAT, 1)) ;
01290 }
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301 int kvpWrite (
01302 int stream
01303 )
01304 {
01305 char* buffer ;
01306 int reclen ;
01307 int lengthWritten ;
01308
01309 buffer = malloc (kvpBufferSize) ;
01310 reclen = kvpFormat (buffer, kvpBufferSize) + 1 ;
01311 lengthWritten = write (stream, buffer, reclen) ;
01312 free (buffer) ;
01313 return (lengthWritten) ;
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 int kvpFormat (
01328 char* buffer,
01329 int bufferSize
01330 )
01331 {
01332 int entry ;
01333 int offset ;
01334 int nchars ;
01335 const char* type ;
01336
01337 offset = 0 ;
01338 for (entry = 0 ; entry < nkeys ; entry++) {
01339 switch (valTypes[entry]) {
01340 case KT_INVALID:
01341
01342 continue;
01343 case KT_INT:
01344 type = "I" ;
01345 break ;
01346 case KT_FLOAT:
01347 type = "F" ;
01348 break ;
01349 case KT_STRING:
01350 default:
01351 type = "S" ;
01352 }
01353
01354 nchars = snprintf (&buffer[offset], bufferSize-offset,
01355 "%s#%s%d=%s;",
01356 keyPtrs[entry], type, nelements[entry],
01357 valPtrs[entry]) ;
01358
01359 if ((nchars > bufferSize-offset) || (nchars == -1)) {
01360 return (-1) ;
01361 }
01362 offset += nchars ;
01363 }
01364 return (offset) ;
01365 }
01366 #endif
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377 void kvpPrintError (
01378 KvpErrorCode code
01379 )
01380 {
01381 fprintf (stderr, "kvp error -- %s\n", kvpErrorString (code)) ;
01382 }
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394 const
01395 char* kvpErrorString (
01396 KvpErrorCode code
01397 )
01398 {
01399 const char* result ;
01400
01401 switch (code) {
01402 case KVP_E_OK:
01403 result = "Success" ;
01404 break ;
01405 case KVP_E_DUPLICATE:
01406 result = "Duplicate key" ;
01407 break ;
01408 case KVP_E_NOTFOUND:
01409 result = "Key not found" ;
01410 break ;
01411 case KVP_E_SYSTEM:
01412 result = "error from system function:" ;
01413 break ;
01414 case KVP_E_BADTYPE:
01415 result = "Type not supported" ;
01416 break ;
01417 case KVP_E_BADKEY:
01418 result = "Illegal characters in key" ;
01419 break ;
01420 case KVP_E_BADVALUE:
01421 result = "value not valid in requested type" ;
01422 break ;
01423 case KVP_E_TOOMANY:
01424 result = "Maximum number of keys exceeded" ;
01425 break ;
01426 case KVP_E_TOOLONG:
01427 result = "record too long to parse" ;
01428 break ;
01429 case KVP_E_BADINPUT:
01430 result = "Syntax error in input" ;
01431 break ;
01432 case KVP_E_TRUNCATE:
01433 result = "Array truncated" ;
01434 break ;
01435 case KVP_E_WRONGCOUNT:
01436 result = "inconsistent element count" ;
01437 break ;
01438 case KVP_E_ILLNUMBER:
01439 result = "illegal character in number" ;
01440 break ;
01441 case KVP_E_TERMINATOR:
01442 result = "missing terminator on input string" ;
01443 break ;
01444 default:
01445 result = "unknown error" ;
01446 }
01447 return (result) ;
01448 }
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 KvpErrorCode kvpError (void)
01461 {
01462 return (lastError) ;
01463 }