keyValuePair.c File Reference

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include "keyValuePair.h"

Go to the source code of this file.

Functions

static void kvpRealloc (int minExtension)
void kvpDumpInternals (void)
static char * stripSpaces (char *string)
static int validateValue (char *value, KeyType valType)
int kvpFindKey (const char *key)
static int kvpGetBase (const char *key, int defaultValue, int radix)
static KvpErrorCode kvpSet (const char *key, const void *value, KeyType type, int count)
static KvpErrorCode kvpUpdate (const char *key, const void *value, KeyType type, int count)
int kvpParse (const char *record)
void kvpReset (void)
void kvpInit (int bufferSize)
int kvpQueryLength (const char *key)
KvpErrorCode kvpGetEntry (int entry, char **key, KeyType *type, int *size, char **value)
char * kvpGetString (const char *key)
KvpErrorCode kvpGetStringArray (const char *key, char *values, int maxlen, int *entries)
int kvpGetHex (const char *key, int defaultValue)
int kvpGetDec (const char *key, int defaultValue)
int kvpGetInt (const char *key, int defaultValue)
KvpErrorCode kvpGetIntArray (const char *key, int *values, int *entries)
KvpErrorCode kvpGetFloatArray (const char *key, float *values, int *entries)
double kvpGetDouble (const char *key, double defaultValue)
float kvpGetFloat (const char *key, float defaultValue)
KvpErrorCode kvpSetString (const char *key, const char *value)
KvpErrorCode kvpSetIntArray (const char *key, const int *values, int count)
KvpErrorCode kvpSetFloatArray (const char *key, const float *values, int count)
KvpErrorCode kvpSetInt (const char *key, int value)
KvpErrorCode kvpUpdateInt (const char *key, int value)
KvpErrorCode kvpSetFloat (const char *key, float value)
int kvpWrite (int stream)
int kvpFormat (char *buffer, int bufferSize)
void kvpPrintError (KvpErrorCode code)
const char * kvpErrorString (KvpErrorCode code)
KvpErrorCode kvpError (void)

Variables

static char * keyPtrs [MAXKEYS]
static char * valPtrs [MAXKEYS]
static KeyType valTypes [MAXKEYS]
static int nelements [MAXKEYS]
static int nkeys = 0
static char * kvpBuffer = NULL
static int kvpBufferSize
static char * spare = NULL
static int spaceLeft = 0
static KvpErrorCode lastError = KVP_E_OK

Function Documentation

void kvpDumpInternals ( void   ) 

Definition at line 175 of file keyValuePair.c.

Referenced by main().

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 }

KvpErrorCode kvpError ( void   ) 

Definition at line 1460 of file keyValuePair.c.

Referenced by KeyRing::error(), KeyRing::errorString(), and main().

01461 {
01462    return (lastError) ;
01463 }

const char* kvpErrorString ( KvpErrorCode  code  ) 

Definition at line 1395 of file keyValuePair.c.

Referenced by KeyRing::errorString(), and kvpPrintError().

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 }

int kvpFindKey ( const char *  key  ) 

Definition at line 339 of file keyValuePair.c.

References keyPtrs, and nkeys.

Referenced by kvpGetFloatArray(), kvpGetIntArray(), kvpGetString(), kvpGetStringArray(), kvpParse(), kvpQueryLength(), kvpSet(), and kvpUpdate().

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 }

int kvpFormat ( char *  buffer,
int  bufferSize 
)

Definition at line 1327 of file keyValuePair.c.

Referenced by kvpWrite().

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          /* skip it */
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 }

static int kvpGetBase ( const char *  key,
int  defaultValue,
int  radix 
) [static]

Definition at line 377 of file keyValuePair.c.

References KVP_E_BADVALUE, KVP_E_NOTFOUND, KVP_E_OK, kvpGetString(), and lastError.

Referenced by kvpGetDec(), kvpGetHex(), and kvpGetInt().

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 }

int kvpGetDec ( const char *  key,
int  defaultValue 
)

Definition at line 997 of file keyValuePair.c.

Referenced by main().

01001 {
01002    return (kvpGetBase (key, defaultValue, 10)) ;
01003 }

double kvpGetDouble ( const char *  key,
double  defaultValue 
)

Definition at line 1139 of file keyValuePair.c.

Referenced by kvpGetFloat(), and main().

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 }

KvpErrorCode kvpGetEntry ( int  entry,
char **  key,
KeyType type,
int *  size,
char **  value 
)

Definition at line 860 of file keyValuePair.c.

Referenced by KeyRing::KeyRing().

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 }

float kvpGetFloat ( const char *  key,
float  defaultValue 
)

Definition at line 1178 of file keyValuePair.c.

Referenced by KeyRing::KeyRing(), and main().

01182 {
01183    return ((float) kvpGetDouble (key, (double) defaultValue)) ;
01184 }

KvpErrorCode kvpGetFloatArray ( const char *  key,
float *  values,
int *  entries 
)

Definition at line 1087 of file keyValuePair.c.

Referenced by main().

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 }

int kvpGetHex ( const char *  key,
int  defaultValue 
)

Definition at line 980 of file keyValuePair.c.

Referenced by main().

00984 {
00985    return (kvpGetBase (key, defaultValue, 16)) ;
00986 }

int kvpGetInt ( const char *  key,
int  defaultValue 
)

Definition at line 1016 of file keyValuePair.c.

Referenced by main().

01020 {
01021    return (kvpGetBase (key, defaultValue, 0)) ;
01022 }

KvpErrorCode kvpGetIntArray ( const char *  key,
int *  values,
int *  entries 
)

Definition at line 1034 of file keyValuePair.c.

Referenced by KeyRing::KeyRing(), and main().

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 }

char* kvpGetString ( const char *  key  ) 

Definition at line 889 of file keyValuePair.c.

Referenced by kvpGetBase(), kvpGetDouble(), and main().

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 }

KvpErrorCode kvpGetStringArray ( const char *  key,
char *  values,
int  maxlen,
int *  entries 
)

Definition at line 915 of file keyValuePair.c.

Referenced by main().

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 }

void kvpInit ( int  bufferSize  ) 

Definition at line 820 of file keyValuePair.c.

Referenced by kvpParse(), and kvpSet().

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 }

int kvpParse ( const char *  record  ) 

Definition at line 674 of file keyValuePair.c.

Referenced by KeyRing::KeyRing(), and main().

00677 {
00678    char* myPtr ;
00679    char* key ;
00680    char* value ;
00681    char typeChar ;
00682    int count ;
00683    int reclen ;
00684    int oldKeyNumber ;
00685 
00686    /* Make sure things have been initialised properly */
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    /* Take a local copy of the input record */
00698    strncpy (spare, record, reclen) ;
00699 
00700    myPtr = spare;
00701    while (isspace(*myPtr)) {
00702       myPtr++ ;
00703    }
00704 
00705    /* Find the Key Value pairs in our copy and remember where they are */
00706    do {
00707       key = myPtr ;
00708       myPtr = strchr (myPtr, '#') ;
00709       /* Simplistic test if there isn't a hash sign there isn't
00710          another key/value pair. */
00711       if (myPtr != NULL) {
00712          if (nkeys >= MAXKEYS) {
00713             lastError = KVP_E_TOOMANY ;
00714             return (-1) ;
00715          }
00716          /* terminate key string excluding # */
00717          *myPtr++ = 0 ;
00718          /* Save key without surrounding whitespace */
00719          key = stripSpaces (key) ;
00720          /* Ignore comments introduced by // */
00721          if ((key[0] == '/') && (key[1] == '/')) {
00722             myPtr = NULL ;
00723             break ;
00724          }
00725          keyPtrs[nkeys] = key ;
00726 
00727          /* Invalidate old entry for this key if we have one */
00728          oldKeyNumber = kvpFindKey (key) ;
00729          if (oldKeyNumber >= 0) {
00730             valTypes[oldKeyNumber] = KT_INVALID ;
00731          }
00732 
00733          /* extract type info */
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          /* Check for specification of number of elements */
00748          if (*myPtr == '=') {
00749             nelements[nkeys] = 0 ;
00750          }
00751          else {
00752             /* Read array length from folowing chars */
00753             nelements[nkeys] = strtol (myPtr, &myPtr, 10) ;
00754          }
00755 
00756          /* Save the value */
00757          if (*myPtr == '=') {
00758             myPtr++ ;
00759             value = myPtr ;
00760             /* The value ends at the next semicolon */
00761             myPtr = strchr (myPtr, ';') ;
00762             if (myPtr == NULL) {
00763                lastError = KVP_E_TERMINATOR ;
00764                reclen++ ;
00765             }
00766             else {
00767                /* strip the semicolon */
00768                *myPtr++ = 0 ;
00769             }
00770             valPtrs[nkeys] = value ;
00771 
00772             /* Count the number of elements in the value and check
00773                validity of numbers */
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 }

void kvpPrintError ( KvpErrorCode  code  ) 

Definition at line 1377 of file keyValuePair.c.

Referenced by main().

01380 {
01381    fprintf (stderr, "kvp error -- %s\n", kvpErrorString (code)) ;
01382 }

int kvpQueryLength ( const char *  key  ) 

Definition at line 836 of file keyValuePair.c.

Referenced by main().

00836                                      {
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 }

static void kvpRealloc ( int  minExtension  )  [static]

Definition at line 133 of file keyValuePair.c.

References keyPtrs, KVP_MIN_BUFFER_SIZE, kvpBuffer, kvpBufferSize, nkeys, spaceLeft, spare, and valPtrs.

Referenced by kvpParse(), kvpSet(), and kvpUpdate().

00136 {
00137    char* newBuffer ;
00138    int newSize;
00139    int item ;
00140    int length ;
00141    int extension ;
00142 
00143    /* Allocate new buffer */
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    /* Copy from old buffer, updating pointers as we go */
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    /* Drop old buffer */
00170    free (kvpBuffer) ;
00171    kvpBuffer = newBuffer ;
00172    kvpBufferSize = newSize ;
00173 }

void kvpReset ( void   ) 

Definition at line 810 of file keyValuePair.c.

Referenced by KeyRing::write().

00811 {
00812    if (kvpBuffer != NULL) {
00813       free (kvpBuffer) ;
00814    }
00815    spare = kvpBuffer = NULL ;
00816    spaceLeft = 0 ;
00817    nkeys = 0 ;
00818 }

static KvpErrorCode kvpSet ( const char *  key,
const void *  value,
KeyType  type,
int  count 
) [static]

Definition at line 417 of file keyValuePair.c.

References keyPtrs, KT_FLOAT, KT_INT, KT_STRING, KVP_E_BADKEY, KVP_E_BADTYPE, KVP_E_DUPLICATE, KVP_E_OK, KVP_E_SYSTEM, KVP_E_TOOLONG, KVP_E_TOOMANY, kvpFindKey(), kvpInit(), kvpRealloc(), lastError, MAX_FLOAT_LENGTH, MAX_INT_LENGTH, MAXKEYS, nelements, nkeys, spaceLeft, spare, valPtrs, and valTypes.

Referenced by kvpSetFloat(), kvpSetFloatArray(), kvpSetInt(), kvpSetIntArray(), and kvpSetString().

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    /* Make sure things have been initialised properly */
00434    if (spare == NULL) {
00435       kvpInit (0) ;
00436    }
00437 
00438    /* Check that this key does not already exist */
00439    entry = kvpFindKey (key) ;
00440    if (entry >= 0) {
00441       lastError = KVP_E_DUPLICATE ;
00442       return (lastError) ;
00443    }
00444 
00445    /* Check that we have space in the keys array */
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    /* Store the key in the next spare space in our buffer */
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    /* Check for illegal characters in key */
00482    if (strcspn (key, "=;,#") != (size_t)nchars) {
00483       lastError = KVP_E_BADKEY ;
00484       return (lastError) ;
00485    }
00486 
00487    /* Only update buffer pointers now we know key is OK */
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             /* This should NEVER happen now */
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             /* This should NEVER happen now */
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          /* This should NEVER happen now */
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 }

KvpErrorCode kvpSetFloat ( const char *  key,
float  value 
)

Definition at line 1284 of file keyValuePair.c.

Referenced by main().

01288 {
01289    return (kvpSet (key, &value, KT_FLOAT, 1)) ;
01290 }

KvpErrorCode kvpSetFloatArray ( const char *  key,
const float *  values,
int  count 
)

Definition at line 1231 of file keyValuePair.c.

Referenced by main(), and KeyRing::write().

01236 {
01237    return (kvpSet (key, values, KT_FLOAT, count)) ;
01238 }

KvpErrorCode kvpSetInt ( const char *  key,
int  value 
)

Definition at line 1249 of file keyValuePair.c.

Referenced by main().

01253 {
01254    return (kvpSet (key, &value, KT_INT, 1)) ;
01255 }

KvpErrorCode kvpSetIntArray ( const char *  key,
const int *  values,
int  count 
)

Definition at line 1214 of file keyValuePair.c.

Referenced by main(), and KeyRing::write().

01219 {
01220    return (kvpSet (key, values, KT_INT, count)) ;
01221 }

KvpErrorCode kvpSetString ( const char *  key,
const char *  value 
)

Definition at line 1197 of file keyValuePair.c.

Referenced by main(), and KeyRing::write().

01201 {
01202    return (kvpSet (key, value, KT_STRING, 1)) ;
01203 }

static KvpErrorCode kvpUpdate ( const char *  key,
const void *  value,
KeyType  type,
int  count 
) [static]

Definition at line 569 of file keyValuePair.c.

References KT_FLOAT, KT_INT, KT_STRING, KVP_E_BADTYPE, KVP_E_BADVALUE, KVP_E_NOTFOUND, KVP_E_OK, KVP_E_SYSTEM, kvpFindKey(), kvpRealloc(), lastError, MAX_FLOAT_LENGTH, MAX_INT_LENGTH, nelements, spaceLeft, spare, valPtrs, and valTypes.

Referenced by kvpUpdateInt().

00575 {
00576    int nchars ;
00577    int element ;
00578    int* iPtr ;
00579    float* fPtr ;
00580    int entry ;
00581    int requiredSpace ;
00582 
00583    /* Find the key */
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    /* Write the new value at the first spare point in our buffer.
00616       Note that we don't free up the space used by the previous value */
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 }

KvpErrorCode kvpUpdateInt ( const char *  key,
int  value 
)

Definition at line 1266 of file keyValuePair.c.

01270 {
01271    return (kvpUpdate (key, &value, KT_INT, 1)) ;
01272 }

int kvpWrite ( int  stream  ) 

Definition at line 1301 of file keyValuePair.c.

Referenced by main(), and KeyRing::write().

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 }

static char* stripSpaces ( char *  string  )  [static]

Definition at line 194 of file keyValuePair.c.

Referenced by kvpParse().

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 }

static int validateValue ( char *  value,
KeyType  valType 
) [static]

Definition at line 216 of file keyValuePair.c.

References count, digit(), KT_FLOAT, KT_INT, KT_STRING, KVP_E_ILLNUMBER, and lastError.

Referenced by kvpParse().

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                   /* It could be part of an 0x prefix */
00256                   hexCandidate = 1;
00257                }
00258                else {
00259                   hexCandidate = 0;
00260                }
00261             }
00262             else if (hexCandidate == 1) {
00263                /* Actually, surprisingly in this day and age,
00264                   it's an octal prefix */
00265                hexCandidate = 0 ;
00266                octalCandidate = 1 ;
00267                /* Better check that it's a valid octal digit */
00268                if (*value > '7') {
00269                   lastError = KVP_E_ILLNUMBER ;
00270                   return (-1) ;
00271                }
00272             }
00273          }
00274          else { /* not a digit */
00275             if ((hexCandidate == 1) && tolower (*value) == 'x') {
00276                hexCandidate = 2 ;
00277             }
00278             else if  ((*value == '+') || (*value == '-')) {
00279                if (inNumber) {
00280                   if (exponent != 1) {
00281                      /* sign in middle of number */
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 { /* not part of '0x' and no decimal point */
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 }


Variable Documentation

char* keyPtrs[MAXKEYS] [static]

Definition at line 120 of file keyValuePair.c.

Referenced by kvpFindKey(), kvpFormat(), kvpGetEntry(), kvpParse(), kvpRealloc(), and kvpSet().

char* kvpBuffer = NULL [static]

Definition at line 125 of file keyValuePair.c.

Referenced by kvpDumpInternals(), kvpInit(), kvpRealloc(), and kvpReset().

int kvpBufferSize [static]

Definition at line 126 of file keyValuePair.c.

Referenced by kvpDumpInternals(), kvpInit(), kvpRealloc(), and kvpWrite().

KvpErrorCode lastError = KVP_E_OK [static]
int nelements[MAXKEYS] [static]
int nkeys = 0 [static]
int spaceLeft = 0 [static]
char* spare = NULL [static]
char* valPtrs[MAXKEYS] [static]
KeyType valTypes[MAXKEYS] [static]

Generated on 16 Apr 2018 for loon by  doxygen 1.6.1