diff --git a/EvidenceBase.cpp b/EvidenceBase.cpp index f665c5c2..902b6539 100644 --- a/EvidenceBase.cpp +++ b/EvidenceBase.cpp @@ -47,7 +47,7 @@ fiftyoneDegreesEvidenceKeyValuePairArray* EvidenceBase::get() { for (map::const_iterator iterator = begin(); iterator != end(); iterator++) { - EvidencePrefixMap *map = + EvidencePrefixMap* map = EvidenceMapPrefix(iterator->first.c_str()); if (map != NULL && isRelevant(map->prefixEnum)) { EvidenceAddString( diff --git a/EvidenceBase.hpp b/EvidenceBase.hpp index c523ae62..dad5cea6 100644 --- a/EvidenceBase.hpp +++ b/EvidenceBase.hpp @@ -71,9 +71,9 @@ namespace FiftyoneDegrees { * @{ */ - /** - * Construct a new instance containing no evidence. - */ + /** + * Construct a new instance containing no evidence. + */ EvidenceBase(); /** @@ -87,12 +87,12 @@ namespace FiftyoneDegrees { * @{ */ - /** - * Get the underlying C structure containing the evidence. This - * only includes evidence which is relevant to the engine. Any - * evidence which is irrelevant will not be included in the result. - * @return pointer to a populated C evidence structure - */ + /** + * Get the underlying C structure containing the evidence. This + * only includes evidence which is relevant to the engine. Any + * evidence which is irrelevant will not be included in the result. + * @return pointer to a populated C evidence structure + */ fiftyoneDegreesEvidenceKeyValuePairArray* get(); /** @@ -101,9 +101,9 @@ namespace FiftyoneDegrees { * @{ */ - /** - * Clear all evidence items from the instance. - */ + /** + * Clear all evidence items from the instance. + */ void clear(); /** @@ -118,7 +118,7 @@ namespace FiftyoneDegrees { * @param last item to remove */ void erase(iterator first, iterator last); - + /** * @} */ @@ -133,7 +133,7 @@ namespace FiftyoneDegrees { virtual bool isRelevant(fiftyoneDegreesEvidencePrefix prefix); private: /** The underlying evidence structure. */ - fiftyoneDegreesEvidenceKeyValuePairArray *evidence; + fiftyoneDegreesEvidenceKeyValuePairArray* evidence; }; } } diff --git a/evidence.c b/evidence.c index c53539b6..ca415233 100644 --- a/evidence.c +++ b/evidence.c @@ -24,15 +24,22 @@ #include "fiftyone.h" typedef struct evidence_iterate_state_t { - fiftyoneDegreesEvidenceKeyValuePairArray *evidence; + EvidenceKeyValuePairArray *evidence; EvidencePrefix prefix; void *state; - fiftyoneDegreesEvidenceIterateMethod callback; + EvidenceIterateMethod callback; } evidenceIterateState; +typedef struct evidence_find_state_t { + Header* header; // Header to find + EvidenceKeyValuePair* pair; // Pair found that matches the header +} evidenceFindState; + static EvidencePrefixMap _map[] = { - { "server.", sizeof("server.") - 1, FIFTYONE_DEGREES_EVIDENCE_SERVER }, - { "header.", sizeof("header.") - 1, FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING }, + { "server.", sizeof("server.") - 1, + FIFTYONE_DEGREES_EVIDENCE_SERVER }, + { "header.", sizeof("header.") - 1, + FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING }, { "query.", sizeof("query.") - 1, FIFTYONE_DEGREES_EVIDENCE_QUERY }, { "cookie.", sizeof("cookie.") - 1, FIFTYONE_DEGREES_EVIDENCE_COOKIE } }; @@ -45,8 +52,9 @@ static void parsePair(EvidenceKeyValuePair *pair) { case FIFTYONE_DEGREES_EVIDENCE_QUERY: case FIFTYONE_DEGREES_EVIDENCE_COOKIE: default: - pair->parsedValue = pair->originalValue; - pair->parsedLength = strlen(pair->parsedValue); + // These are string prefixes so just copy over the original values. + pair->parsedValue = pair->item.value; + pair->parsedLength = pair->item.valueLength; break; } } @@ -54,15 +62,19 @@ static void parsePair(EvidenceKeyValuePair *pair) { // If a string comparison of the pair field and the header indicates a match // then set the header to avoid a string comparison in future iterations. static void setPairHeader(EvidenceKeyValuePair* pair, Header* header) { - if (pair->fieldLength == header->length && - StringCompareLength(pair->field, header->name, header->length) == 0) { + if (pair->item.keyLength == header->nameLength && + StringCompareLength( + pair->item.key, + header->name, + header->nameLength) == 0) { pair->header = header; } } /** * Iterate through an evidence collection and perform callback on the evidence - * whose prefix matches the input prefixes. + * whose prefix matches the input prefixes. Checks the linked list of evidence + * arrays to ensure these are also processed. * * @param evidence the evidence collection to process * @param prefixes the accepted evidence prefixes @@ -75,12 +87,14 @@ static uint32_t evidenceIterate( int prefixes, void* state, EvidenceIterateMethod callback) { - uint32_t i = 0, iterations = 0; - const uint32_t count = evidence->count; + uint32_t index = 0, iterations = 0; EvidenceKeyValuePair* pair; bool cont = true; - while (cont && i < count) { - pair = &evidence->items[i++]; + while (cont && evidence != NULL) { + + // Check the current evidence item and call back if the right prefix + // after parsing the pair if not done so already. + pair = &evidence->items[index++]; if ((pair->prefix & prefixes) == pair->prefix) { if (pair->parsedValue == NULL) { parsePair(pair); @@ -88,10 +102,36 @@ static uint32_t evidenceIterate( cont = callback(state, pair); iterations++; } + + // Check if the next evidence array needs to be moved to. + if (index >= evidence->count) { + evidence = evidence->next; + index = 0; + } } return iterations; } +/** + * If the header name and pair key match then stop iterating having set the + * found pair, otherwise return false. + */ +static bool findHeaderEvidenceCallback( + void* state, + EvidenceKeyValuePair* pair) { + evidenceFindState* findState = (evidenceFindState*)state; + if (findState->header == pair->header || ( + findState->header->nameLength == pair->item.keyLength && + StringCompareLength( + findState->header->name, + pair->item.key, + pair->item.keyLength) == 0)) { + findState->pair = pair; + return false; + } + return true; +} + /** * Finds the evidence pair that matches the header. Returns null if a pair does * not exist. @@ -100,39 +140,20 @@ static EvidenceKeyValuePair* findHeaderEvidence( EvidenceKeyValuePairArray* evidence, int prefixes, Header* header) { - EvidenceKeyValuePair* pair; - - // For each of the evidence pairs available. - for (uint32_t i = 0; i < evidence->count; i++) { - pair = &evidence->items[i]; - - // Check that the prefix is one that is being considered. - if ((pair->prefix & prefixes) == pair->prefix) { - - // If the header has been assigned to the pair check to see if this - // one is a match. - if (pair->header == NULL) { - setPairHeader(pair, header); - } - - // If the pair's header and the required header are the same. - if (pair->header == header) { - - // Ensure the parsed value is populated before returning. - if (pair->parsedValue == NULL) { - parsePair(pair); - } - return pair; - } - } - } - return NULL; + evidenceFindState state = { header, NULL }; + evidenceIterate(evidence, prefixes, &state, findHeaderEvidenceCallback); + return state.pair; } // Safe-copies the pair parsed value to the buffer checking that there are // sufficient bytes remaining in the buffer for the parsed value. -static void addPairValueToBuffer(StringBuilder* builder, EvidenceKeyValuePair* pair) { - StringBuilderAddChars(builder, (char*)pair->parsedValue, pair->parsedLength); +static void addPairValueToBuffer( + StringBuilder* builder, + EvidenceKeyValuePair* pair) { + StringBuilderAddChars( + builder, + (char*)pair->parsedValue, + pair->parsedLength); } // For the header finds the corresponding evidence in the array of evidence. If @@ -166,8 +187,8 @@ static bool addHeaderValueToBuilder( // current character in the buffer. addPairValueToBuffer(builder, pair); - // return false if we have overfilled the buffer - return !builder->full; + // Return false if we have overfilled the buffer. + return builder->full == false; } // Assembles a pseudo header in the buffer. If this can not be achieved returns @@ -180,11 +201,13 @@ static bool processPseudoHeader( Header* header, StringBuilder* builder, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { + EvidenceKeyValuePair pair; // For each of the headers that form the pseudo header. for (uint32_t i = 0; i < header->segmentHeaders->count; i++) { - //if this is a subsequent segment - we prepend the separator + + // if this is a subsequent segment - we prepend the separator bool prependSeparator = i > 0; // Add the header evidence that forms the segment if available updating @@ -207,9 +230,17 @@ static bool processPseudoHeader( // character. StringBuilderComplete(builder); - // A full header has been formed so call the callback with the buffer and - // the number of characters populated. - return callback(state, header, builder->ptr, builder->added); + // A full header has been formed so call the callback with an evidence pair + // containing the parsed value. + pair.item.key = NULL; + pair.item.keyLength = 0; + pair.header = header; + pair.item.value = builder->ptr; + pair.item.valueLength = builder->added; + pair.parsedValue = builder->ptr; + pair.parsedLength = builder->added; + pair.prefix = 0; + return callback(state, &pair); } // Finds the header in the evidence, and if available calls the callback. @@ -220,7 +251,7 @@ static bool processHeader( int prefixes, Header* header, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { // Get the evidence that corresponds to the header. If it doesn't exist // then there is no evidence for the header and a call back will not be @@ -233,27 +264,26 @@ static bool processHeader( return true; } - // A full header has been formed so call the callback with the buffer and - // the number of characters populated. - return callback( - state, - header, - (const char*)pair->parsedValue, - pair->parsedLength); + // A full header has been formed so call the callback with the pair. + return callback(state, pair); } fiftyoneDegreesEvidenceKeyValuePairArray* fiftyoneDegreesEvidenceCreate(uint32_t capacity) { - EvidenceKeyValuePairArray *evidence; + fiftyoneDegreesEvidenceKeyValuePairArray *evidence; uint32_t i; FIFTYONE_DEGREES_ARRAY_CREATE(EvidenceKeyValuePair, evidence, capacity); if (evidence != NULL) { + evidence->next = NULL; + evidence->prev = NULL; for (i = 0; i < evidence->capacity; i++) { - evidence->items[i].field = NULL; - evidence->items[i].fieldLength = 0; + evidence->items[i].item.key = NULL; + evidence->items[i].item.keyLength = 0; + evidence->items[i].item.value = NULL; + evidence->items[i].item.valueLength = 0; evidence->items[i].header = NULL; - evidence->items[i].originalValue = NULL; evidence->items[i].parsedValue = NULL; + evidence->items[i].parsedLength = 0; evidence->items[i].prefix = FIFTYONE_DEGREES_EVIDENCE_IGNORE; } } @@ -262,27 +292,58 @@ fiftyoneDegreesEvidenceCreate(uint32_t capacity) { void fiftyoneDegreesEvidenceFree( fiftyoneDegreesEvidenceKeyValuePairArray *evidence) { - Free(evidence); + if (evidence == NULL) { + return; + } + EvidenceKeyValuePairArray* current = evidence; + while (current->next != NULL) { + current = current->next; + } + while (current != NULL) { + evidence = current->prev; + Free(current); + current = evidence; + } } -fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( +fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddPair( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue) { + fiftyoneDegreesKeyValuePair value) { EvidenceKeyValuePair *pair = NULL; - if (evidence->count < evidence->capacity) { - pair = &evidence->items[evidence->count++]; - pair->prefix = prefix; - pair->field = field; - pair->fieldLength = strlen(field); - pair->originalValue = (void*)originalValue; - pair->parsedValue = NULL; - pair->header = NULL; + while (pair == NULL) { + if (evidence->count < evidence->capacity) { + // Use the next item in the allocated array. + pair = &evidence->items[evidence->count++]; + pair->prefix = prefix; + pair->item = value; + pair->parsedValue = NULL; + pair->header = NULL; + } + else { + // If there is insufficient capacity in the evidence array then add + // a new array. + if (evidence->next == NULL) { + evidence->next = EvidenceCreate( + evidence->capacity == 0 ? 1 : evidence->capacity); + evidence->next->prev = evidence; + } + // Move to the next evidence array. + evidence = evidence->next; + } } return pair; } +fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( + fiftyoneDegreesEvidenceKeyValuePairArray* evidence, + fiftyoneDegreesEvidencePrefix prefix, + const char* key, + const char* value) { + KeyValuePair pair = { key, strlen(key), value, strlen(value) }; + return EvidenceAddPair(evidence, prefix, pair); +} + uint32_t fiftyoneDegreesEvidenceIterate( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, int prefixes, @@ -312,7 +373,7 @@ fiftyoneDegreesEvidencePrefixMap* fiftyoneDegreesEvidenceMapPrefix( return result; } -EXTERNAL const char* fiftyoneDegreesEvidencePrefixString( +const char* fiftyoneDegreesEvidencePrefixString( fiftyoneDegreesEvidencePrefix prefix) { uint32_t i; EvidencePrefixMap* map; @@ -334,7 +395,7 @@ bool fiftyoneDegreesEvidenceIterateForHeaders( char* const buffer, size_t const length, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback) { + fiftyoneDegreesEvidenceIterateMethod callback) { Header* header; StringBuilder builder = { buffer, length }; diff --git a/evidence.h b/evidence.h index 70eda75d..eecdd772 100644 --- a/evidence.h +++ b/evidence.h @@ -124,6 +124,7 @@ #include "string.h" #include "array.h" #include "common.h" +#include "pair.h" #include "headers.h" /** @@ -159,18 +160,35 @@ typedef struct fiftyone_degrees_evidence_prefix_map_t { */ typedef struct fiftyone_degrees_evidence_key_value_pair_t { fiftyoneDegreesEvidencePrefix prefix; /**< e.g. #FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING */ - const char *field; /**< e.g. User-Agent or ScreenPixelsWidth */ - size_t fieldLength; /**< length of field */ - const void *originalValue; /**< original unparsed value */ + fiftyoneDegreesKeyValuePair item; /**< the field key and original value */ const void *parsedValue; /**< parsed value which may not be a string */ size_t parsedLength; /**< length of parsedValue string */ fiftyoneDegreesHeader* header; /**< Unique header in the data set, or null if not related to a header */ } fiftyoneDegreesEvidenceKeyValuePair; +/** + * Forward declaration of the array so that it can point to an instance of the + * same type. + */ +typedef struct fiftyone_degrees_array_fiftyoneDegreesEvidenceKeyValuePair_t + fiftyoneDegreesEvidenceKeyValuePairArray; + +/** + * Pointers to the next and previous array of evidence key value pairs or + * NULL if not present. + */ +#define FIFTYONE_DEGREES_ARRAY_EVIDENCE_MEMBER \ + fiftyoneDegreesEvidenceKeyValuePairArray *next; \ + fiftyoneDegreesEvidenceKeyValuePairArray *prev; + +/** + * Array of evidence key value pairs and a pointer to the next array if present + * or NULL of not present. + */ FIFTYONE_DEGREES_ARRAY_TYPE( fiftyoneDegreesEvidenceKeyValuePair, - ) + FIFTYONE_DEGREES_ARRAY_EVIDENCE_MEMBER) /** * Callback method used to iterate evidence key value pairs. @@ -182,31 +200,17 @@ typedef bool(*fiftyoneDegreesEvidenceIterateMethod)( void *state, fiftyoneDegreesEvidenceKeyValuePair *pair); -/** - * Callback method used to iterate evidence key value pairs for an array of - * headers. - * @param state pointer provided to the iterator - * @param header that the value is related to - * @param value from the evidence for the header - * @param length of the value - * @return true if the iteration should continue otherwise false - */ -typedef bool(*fiftyoneDegreesEvidenceIterateForHeadersMethod)( - void* state, - fiftyoneDegreesHeader* header, - const char* value, - size_t length); - /** * Creates a new evidence array with the capacity requested. * @param capacity maximum number of evidence items * @return pointer to the newly created array */ EXTERNAL fiftyoneDegreesEvidenceKeyValuePairArray* -fiftyoneDegreesEvidenceCreate(uint32_t capacity); + fiftyoneDegreesEvidenceCreate(uint32_t capacity); /** - * Frees the memory used by an evidence array. + * Frees the memory used by an evidence array and any other arrays pointed to + * by the instance passed via the next member. * @param evidence pointer to the array to be freed */ EXTERNAL void fiftyoneDegreesEvidenceFree( @@ -216,16 +220,37 @@ EXTERNAL void fiftyoneDegreesEvidenceFree( * Adds a new entry to the evidence. The memory associated with the * field and original value parameters must not be freed until after the * evidence collection has been freed. This method will NOT copy the values. + * If there is insufficient capacity in the evidence array then another array + * will be created and will be pointed to by the next member of the evidence + * array passed. * @param evidence pointer to the evidence array to add the entry to * @param prefix enum indicating the category the entry belongs to - * @param field used as the key for the entry within its prefix - * @param originalValue the value to be parsed + * @param key string with null terminator + * @param value string with null terminator + * @returns the new evidence key value pair instance */ EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddString( fiftyoneDegreesEvidenceKeyValuePairArray *evidence, fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue); + const char *key, + const char *value); + +/** + * Adds a new entry to the evidence. The memory associated with the + * field and original value parameters must not be freed until after the + * evidence collection has been freed. This method will NOT copy the values. + * If there is insufficient capacity in the evidence array then another array + * will be created and will be pointed to by the next member of the evidence + * array passed. + * @param evidence pointer to the evidence array to add the entry to + * @param prefix enum indicating the category the entry belongs to + * @param pair used as the key and value for the new entry + * @returns the new evidence key value pair instance + */ +EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddPair( + fiftyoneDegreesEvidenceKeyValuePairArray* evidence, + fiftyoneDegreesEvidencePrefix prefix, + fiftyoneDegreesKeyValuePair pair); /** * Determines the evidence map prefix from the key. @@ -260,22 +285,6 @@ EXTERNAL uint32_t fiftyoneDegreesEvidenceIterate( void *state, fiftyoneDegreesEvidenceIterateMethod callback); - -/** - * First checks if provided prefix+field are not already part of the - * evidence array with the same parameters. - * If not calls fiftyoneDegreesEvidenceAddString. - * @param evidence pointer to the evidence array to add the entry to - * @param prefix enum indicating the category the entry belongs to - * @param field used as the key for the entry within its prefix - * @param originalValue the value to be parsed - */ -EXTERNAL fiftyoneDegreesEvidenceKeyValuePair* fiftyoneDegreesEvidenceAddStringUnique( - fiftyoneDegreesEvidenceKeyValuePairArray *evidence, - fiftyoneDegreesEvidencePrefix prefix, - const char *field, - const char *originalValue); - /** * Iterates over the headers assembling the evidence values, considering the * prefixes, in the buffer if available. The call back method is called for @@ -300,7 +309,7 @@ EXTERNAL bool fiftyoneDegreesEvidenceIterateForHeaders( char* const buffer, size_t const length, void* state, - fiftyoneDegreesEvidenceIterateForHeadersMethod callback); + fiftyoneDegreesEvidenceIterateMethod callback); /** * @} diff --git a/fiftyone.h b/fiftyone.h index 92ec4a16..cf120ce5 100644 --- a/fiftyone.h +++ b/fiftyone.h @@ -287,6 +287,7 @@ MAP_TYPE(KeyValuePairArray) #define EvidenceCreate fiftyoneDegreesEvidenceCreate /**< Synonym for #fiftyoneDegreesEvidenceCreate function. */ #define EvidenceMapPrefix fiftyoneDegreesEvidenceMapPrefix /**< Synonym for #fiftyoneDegreesEvidenceMapPrefix function. */ #define EvidencePrefixString fiftyoneDegreesEvidencePrefixString /**< Synonym for #fiftyoneDegreesEvidencePrefixString function. */ +#define EvidenceAddPair fiftyoneDegreesEvidenceAddPair /**< Synonym for #fiftyoneDegreesEvidenceAddPair function. */ #define EvidenceAddString fiftyoneDegreesEvidenceAddString /**< Synonym for #fiftyoneDegreesEvidenceAddString function. */ #define PropertiesGetRequiredPropertyIndexFromName fiftyoneDegreesPropertiesGetRequiredPropertyIndexFromName /**< Synonym for #fiftyoneDegreesPropertiesGetRequiredPropertyIndexFromName function. */ #define PropertiesGetNameFromRequiredIndex fiftyoneDegreesPropertiesGetNameFromRequiredIndex /**< Synonym for #fiftyoneDegreesPropertiesGetNameFromRequiredIndex function. */ @@ -358,6 +359,7 @@ MAP_TYPE(KeyValuePairArray) #define StringBuilderAddChars fiftyoneDegreesStringBuilderAddChars /**< Synonym for fiftyoneDegreesStringBuilderAddChars */ #define StringBuilderComplete fiftyoneDegreesStringBuilderComplete /**< Synonym for fiftyoneDegreesStringBuilderComplete */ #define EvidenceIterateMethod fiftyoneDegreesEvidenceIterateMethod /**< Synonym for fiftyoneDegreesEvidenceIterateMethod */ +#define OverrideHasValueForRequiredPropertyIndex fiftyoneDegreesOverrideHasValueForRequiredPropertyIndex /**< Synonym for fiftyoneDegreesOverrideHasValueForRequiredPropertyIndex */ /* <-- only one asterisk to avoid inclusion in documentation * Shortened macros. diff --git a/headers.c b/headers.c index a02bfe70..dbaafc80 100644 --- a/headers.c +++ b/headers.c @@ -77,7 +77,7 @@ static void initHeaders(Headers* headers) { h->index = i; h->headerId = 0; h->isDataSet = false; - h->length = 0; + h->nameLength = 0; h->name = NULL; h->pseudoHeaders = NULL; h->segmentHeaders = NULL; @@ -181,7 +181,7 @@ static bool setHeaderName( return false; } name[length] = '\0'; - header->length = length; + header->nameLength = length; return true; } @@ -246,7 +246,7 @@ static Header* getHeader(Headers* headers, const char* name, size_t length) { Header* item; for (uint32_t i = 0; i < headers->count; i++) { item = &headers->items[i]; - if (item->length == length && + if (item->nameLength == length && StringCompareLength(name, item->name, length) == 0) { return item; } @@ -337,7 +337,7 @@ static Header* copyHeader( if (setHeaderName( copied, source->name, - source->length, + source->nameLength, exception) == false) { return NULL; } @@ -401,7 +401,7 @@ static bool addHeadersFromHeader( uint32_t start = 0; uint32_t end = 0; bool separatorEncountered = false; - for (;end < pseudoHeader->length; end++) { + for (;end < pseudoHeader->nameLength; end++) { // If a header has been found then either get the existing header with // this name, or add a new header. @@ -583,7 +583,7 @@ int fiftyoneDegreesHeaderGetIndex( // Perform a case insensitive compare of the remaining characters. for (i = 0; i < headers->count; i++) { header = &headers->items[i]; - if (header->length == length && + if (header->nameLength == length && StringCompareLength( httpHeaderName, header->name, diff --git a/headers.h b/headers.h index fe8bacd3..c3e22220 100644 --- a/headers.h +++ b/headers.h @@ -138,7 +138,7 @@ struct fiftyone_degrees_header_t { uint32_t index; /**< Index of the header in the array of all headers */ const char* name; /**< Name of the header or pseudo header field as a null terminated string */ - size_t length; /**< Length of the name string excluding the terminating + size_t nameLength; /**< Length of the name string excluding the terminating null */ fiftyoneDegreesHeaderID headerId; /**< Unique id in the data set for this full header */ @@ -183,13 +183,6 @@ typedef long(*fiftyoneDegreesHeadersGetMethod)( uint32_t index, fiftyoneDegreesCollectionItem *nameItem); -/** - * Check if a header is a pseudo header. - * @param headerName name of the header - * @return whether a header is a pseudo header. - */ -EXTERNAL bool fiftyoneDegreesHeadersIsPseudo(const char *headerName); - /** * Creates a new headers instance configured with the unique HTTP names needed * from evidence. If the useUpperPrefixedHeaders flag is true then checks for diff --git a/overrides.c b/overrides.c index 75559292..ccef8e51 100644 --- a/overrides.c +++ b/overrides.c @@ -57,7 +57,8 @@ static void collectionRelease(Item *item) { * characters. Take 1 from the t to compare length. */ #define IS_HEADER_MATCH(t,p) \ - (StringCompareLength(skipPrefix(true, (char*)pair->field), t, sizeof(t)) == 0) + (StringCompareLength(\ + skipPrefix(true, (char*)pair->item.key), t, sizeof(t)) == 0) static const Collection dummyCollection = { NULL, @@ -183,7 +184,7 @@ static bool addOverrideToResults(void *state, EvidenceKeyValuePair *pair) { // Find the required property index, if any for the field. int requiredPropertyIndex = getRequiredPropertyIndexFromName( add->properties, - pair->field); + pair->item.key); return fiftyoneDegreesOverridesAdd( add->values, diff --git a/pair.h b/pair.h index bb6a4c55..c66c4baa 100644 --- a/pair.h +++ b/pair.h @@ -27,10 +27,10 @@ #include typedef struct fiftyone_degrees_key_value_pair_t { - char* key; - size_t keyLength; - char* value; - size_t valueLength; + const char* key; /**< pointer to the key string */ + size_t keyLength; /**< number of characters in key */ + const char* value; /**< pointer to the value string */ + size_t valueLength; /**< number of characters in value */ } fiftyoneDegreesKeyValuePair; FIFTYONE_DEGREES_ARRAY_TYPE(fiftyoneDegreesKeyValuePair, ) diff --git a/tests/EvidenceTests.cpp b/tests/EvidenceTests.cpp index 18b89857..f1fa9697 100644 --- a/tests/EvidenceTests.cpp +++ b/tests/EvidenceTests.cpp @@ -30,10 +30,10 @@ void assertStringHeaderAdded( const char *expectedValue) { EXPECT_EQ((int)pair->prefix, (int)FIFTYONE_DEGREES_EVIDENCE_HTTP_HEADER_STRING) << L"Expected 'header' prefix."; - EXPECT_STREQ(pair->field, expectedField) << - L"Expected name '" << expectedField << "' not '" << pair->field << "'"; - EXPECT_TRUE(strcmp((const char*)pair->originalValue, expectedValue) == 0) << - L"Expected value '" << expectedValue << "' not '" << pair->originalValue << "'"; + EXPECT_STREQ(pair->item.key, expectedField) << + L"Expected name '" << expectedField << "' not '" << pair->item.key << "'"; + EXPECT_TRUE(strcmp((const char*)pair->item.value, expectedValue) == 0) << + L"Expected value '" << expectedValue << "' not '" << pair->item.value << "'"; } TEST_F(Evidence, Get_PrefixString) { @@ -99,9 +99,9 @@ TEST_F(Evidence, Add_MultipleStrings) #endif bool onMatchIterateString(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { - if (strcmp((const char*)pair->field, "some-header-name") == 0) { - EXPECT_TRUE(strcmp((const char*)pair->originalValue, (const char*)pair->parsedValue) == 0) << - L"Expected parsed value to be '" << (const char*)pair->originalValue << "' not '" << + if (strcmp((const char*)pair->item.key, "some-header-name") == 0) { + EXPECT_TRUE(strcmp((const char*)pair->item.value, (const char*)pair->parsedValue) == 0) << + L"Expected parsed value to be '" << (const char*)pair->item.value << "' not '" << (const char*)pair->parsedValue << "'"; } return true; @@ -203,9 +203,9 @@ TEST_F(Evidence, Iterate_String_without_pseudo_evidence) { "Number of evidence should be 1\n"; } -bool callback1(void* state, fiftyoneDegreesHeader*, const char* value, size_t) { +bool callback1(void* state, fiftyoneDegreesEvidenceKeyValuePair* pair) { std::vector *results = (std::vector *) state; - results->push_back(value); + results->push_back(pair->item.value); return true; } @@ -361,9 +361,9 @@ TEST_F(Evidence, IterateForHeaders_ConstructPseudoHeader_Missing_or_Empty) { EXPECT_EQ(results[1], "\x1FGreen\x1F""Apple"); } -bool callback2(void* state, fiftyoneDegreesHeader* , const char* value, size_t ) { +bool callback2(void* state, fiftyoneDegreesEvidenceKeyValuePair *pair) { std::vector *results = (std::vector *) state; - results->push_back(value); + results->push_back(pair->item.value); return results->size() <= 1; // on the second header we signal early exit by returning false } @@ -388,7 +388,7 @@ TEST_F(Evidence, IterateForHeaders_CallbackSignalsEarlyExit) { EXPECT_EQ(results[1], "Big\x1FGreen"); } -bool callback_false(void* , fiftyoneDegreesHeader* , const char* , size_t ) { +bool callback_false(void*, fiftyoneDegreesEvidenceKeyValuePair*) { return false; } @@ -438,4 +438,7 @@ TEST_F(Evidence, IterateForHeaders_SmallBuffer) { fiftyoneDegreesFree(buf); } - +TEST_F(Evidence, freeNullEvidence) { + fiftyoneDegreesEvidenceKeyValuePairArray *evidence2 = NULL; + EvidenceFree(evidence2); +} diff --git a/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp b/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp index 77233a9b..97c220b2 100644 --- a/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp +++ b/tests/EvidenceWithHeadersTests_MultipleHeaders.cpp @@ -114,8 +114,8 @@ TEST_F(EvidenceWithHeadersTest_MultipleHeaders, Intersection_mh_se_sm) { evidenceHeaderIntersection_mh_se_sm); ASSERT_EQ(1, result); - ASSERT_STREQ("Black", intersection_mh_se_sm[0].field); - ASSERT_STREQ("Value", (char*)intersection_mh_se_sm[0].originalValue); + ASSERT_STREQ("Black", intersection_mh_se_sm[0].item.key); + ASSERT_STREQ("Value", (char*)intersection_mh_se_sm[0].item.value); } @@ -160,10 +160,10 @@ TEST_F(EvidenceWithHeadersTest_MultipleHeaders, Intersection_mh_me_mm) { evidenceHeaderIntersection_mh_me_mm); ASSERT_EQ(2, result); - EXPECT_STREQ("Black", intersection_mh_me_mm[0].field); - EXPECT_STREQ("Value", (char*)intersection_mh_me_mm[0].originalValue); - EXPECT_STREQ("Red", intersection_mh_me_mm[1].field); - EXPECT_STREQ("Value2", (char*)intersection_mh_me_mm[1].originalValue); + EXPECT_STREQ("Black", intersection_mh_me_mm[0].item.key); + EXPECT_STREQ("Value", (char*)intersection_mh_me_mm[0].item.value); + EXPECT_STREQ("Red", intersection_mh_me_mm[1].item.key); + EXPECT_STREQ("Value2", (char*)intersection_mh_me_mm[1].item.value); } //------------------------------------------------------------------ @@ -177,8 +177,8 @@ bool evidenceHeaderIntersection_mh_me_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_mh_me_nm[intersection_mh_me_nm_count] = *pair; intersection_mh_me_nm_count++; } diff --git a/tests/EvidenceWithHeadersTests_NoHeaders.cpp b/tests/EvidenceWithHeadersTests_NoHeaders.cpp index 3f8e16bc..44729763 100644 --- a/tests/EvidenceWithHeadersTests_NoHeaders.cpp +++ b/tests/EvidenceWithHeadersTests_NoHeaders.cpp @@ -81,8 +81,8 @@ bool evidenceHeaderIntersection_nh_se_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_nh_se_nm[intersection_nh_se_nm_count] = *pair; intersection_nh_se_nm_count++; } @@ -118,8 +118,8 @@ bool evidenceHeaderIntersection_nh_me_mm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_nh_me_nm[intersection_multiple_nh_me_mm_count] = *pair; intersection_multiple_nh_me_mm_count++; } diff --git a/tests/EvidenceWithHeadersTests_SingleHeader.cpp b/tests/EvidenceWithHeadersTests_SingleHeader.cpp index f34376ae..a706d02d 100644 --- a/tests/EvidenceWithHeadersTests_SingleHeader.cpp +++ b/tests/EvidenceWithHeadersTests_SingleHeader.cpp @@ -111,8 +111,8 @@ TEST_F(EvidenceWithHeadersTest_SingleHeader, Intersection_sh_se_sm) { evidenceHeaderIntersection_sh_se_sm); ASSERT_EQ(1, result); - ASSERT_STREQ("Red", intersection_sh_se_sm[0].field); - ASSERT_STREQ("Value", (char*)intersection_sh_se_sm[0].originalValue); + ASSERT_STREQ("Red", intersection_sh_se_sm[0].item.key); + ASSERT_STREQ("Value", (char*)intersection_sh_se_sm[0].item.value); } @@ -130,8 +130,8 @@ bool evidenceHeaderIntersection_sh_me_mm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_sh_me_sm[intersection_multiple_sh_me_mm_count] = *pair; intersection_multiple_sh_me_mm_count++; } @@ -162,8 +162,8 @@ TEST_F(EvidenceWithHeadersTest_SingleHeader, Intersection_sh_me_sm) { ASSERT_EQ(2, result); ASSERT_EQ(1, intersection_multiple_sh_me_mm_count); - EXPECT_STREQ("Red", intersection_sh_me_sm[0].field); - EXPECT_STREQ("Value2", (char*)intersection_sh_me_sm[0].originalValue); + EXPECT_STREQ("Red", intersection_sh_me_sm[0].item.key); + EXPECT_STREQ("Value2", (char*)intersection_sh_me_sm[0].item.value); } //------------------------------------------------------------------ @@ -181,8 +181,8 @@ bool evidenceHeaderIntersection_sh_me_nm(void *state, fiftyoneDegreesEvidenceKeyValuePair *pair) { if (fiftyoneDegreesHeaderGetIndex( (fiftyoneDegreesHeaders*)state, - pair->field, - strlen(pair->field)) >= 0) { + pair->item.key, + pair->item.keyLength) >= 0) { intersection_sh_me_nm[intersection_sh_me_nm_count] = *pair; intersection_sh_me_nm_count++; } diff --git a/tests/HeadersTests.cpp b/tests/HeadersTests.cpp index 41644c85..7601bfba 100644 --- a/tests/HeadersTests.cpp +++ b/tests/HeadersTests.cpp @@ -371,8 +371,8 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header1\x1Fheader2", headers->items[3].name); EXPECT_EQ(2, headers->items[3].segmentHeaders->count); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[3].segmentHeaders->items[0]->name, @@ -387,8 +387,8 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header2\x1Fheader3", headers->items[4].name); EXPECT_EQ(2, headers->items[4].segmentHeaders->count); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header2", headers->items[4].segmentHeaders->items[0]->name, @@ -403,9 +403,9 @@ TEST_F(HeadersTests, PseudoHeadersPositive) { EXPECT_STREQ("header1\x1Fheader2\x1Fheader3", headers->items[5].name); EXPECT_EQ(3, headers->items[5].segmentHeaders->count); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[1]->length); - EXPECT_EQ(7, headers->items[5].segmentHeaders->items[2]->length); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[1]->nameLength); + EXPECT_EQ(7, headers->items[5].segmentHeaders->items[2]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", @@ -445,11 +445,11 @@ TEST_F(HeadersTests, PseudoHeadersMissing) { EXPECT_STREQ("header1\x1Fheader2", headers->items[0].name); EXPECT_EQ(true, headers->items[0].isDataSet); EXPECT_EQ(2, headers->items[0].segmentHeaders->count); - EXPECT_EQ(7, headers->items[0].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[0].segmentHeaders->items[0]->nameLength); EXPECT_EQ(1, headers->items[0].segmentHeaders->items[0]->pseudoHeaders->count); EXPECT_EQ(&headers->items[0], headers->items[0].segmentHeaders->items[0]->pseudoHeaders->items[0]); - EXPECT_EQ(7, headers->items[0].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[0].segmentHeaders->items[1]->nameLength); EXPECT_EQ(1, headers->items[0].segmentHeaders->items[1]->pseudoHeaders->count); EXPECT_EQ(&headers->items[0], headers->items[0].segmentHeaders->items[1]->pseudoHeaders->items[0]); @@ -510,7 +510,7 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("\x1Fheader1", headers->items[2].name); EXPECT_EQ(1, headers->items[2].segmentHeaders->count); - EXPECT_EQ(7, headers->items[2].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[2].segmentHeaders->items[0]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[2].segmentHeaders->items[0]->name, @@ -522,7 +522,7 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("header1\x1F", headers->items[3].name); EXPECT_EQ(1, headers->items[3].segmentHeaders->count); - EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->length); + EXPECT_EQ(7, headers->items[3].segmentHeaders->items[0]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[3].segmentHeaders->items[0]->name, @@ -534,8 +534,8 @@ TEST_F(HeadersTests, PseudoHeadersSpecialCases) { EXPECT_STREQ("header1\x1F\x1Fheader2", headers->items[4].name); EXPECT_EQ(2, headers->items[4].segmentHeaders->count); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->length); - EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->length); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[0]->nameLength); + EXPECT_EQ(7, headers->items[4].segmentHeaders->items[1]->nameLength); EXPECT_EQ(0, StringCompareLength( "header1", headers->items[4].segmentHeaders->items[0]->name, diff --git a/yamlfile.c b/yamlfile.c index 0fc5bae0..cfae8be9 100644 --- a/yamlfile.c +++ b/yamlfile.c @@ -85,15 +85,15 @@ static char* readNext(FileState* fileState) { // Sets the current and end pointers to the current key. static void setCurrentKey(PairState* state) { KeyValuePair* current = state->pairs + state->index; - state->current = current->key; - state->end = current->key + current->keyLength - 1; + state->current = (char*)current->key; + state->end = (char*)(current->key + current->keyLength - 1); } // Sets the current and end pointers to the current value. static void setCurrentValue(PairState* state) { KeyValuePair* current = state->pairs + state->index; - state->current = current->value; - state->end = current->value + current->valueLength - 1; + state->current = (char*)current->value; + state->end = (char*)current->value + current->valueLength - 1; } // Switches from writing to the current key to the current value. Ensures that @@ -185,8 +185,8 @@ StatusCode fiftyoneDegreesYamlFileIterateWithLimit( keyValuePairs, collectionSize, 0, - keyValuePairs[0].key, - keyValuePairs[0].key + keyValuePairs[0].keyLength - 1 }; + (char*)keyValuePairs[0].key, + (char*)(keyValuePairs[0].key + keyValuePairs[0].keyLength - 1) }; // If there is no limit then set the limit to the largest value to // avoid checking for negative values in the loop. @@ -301,6 +301,5 @@ StatusCode fiftyoneDegreesYamlFileIterate( collectionSize, -1, state, - callback - ); + callback); } \ No newline at end of file