#pragma once #include #include // ---------------------------------------------------------------------------- // qs_parse (modified) // https://github.com/bartgrantham/qs_parse // ---------------------------------------------------------------------------- /* Similar to strncmp, but handles URL-encoding for either string */ int qs_strncmp(const char * s, const char * qs, register size_t n); /* Finds the beginning of each key/value pair and stores a pointer in qs_kv. * Also decodes the value portion of the k/v pair *in-place*. In a future * enhancement it will also have a compile-time option of sorting qs_kv * alphabetically by key. */ int qs_parse(char * qs, char * qs_kv[], int qs_kv_size); /* Used by qs_parse to decode the value portion of a k/v pair */ int qs_decode(char * qs); /* Looks up the value according to the key on a pre-processed query string * A future enhancement will be a compile-time option to look up the key * in a pre-sorted qs_kv array via a binary search. */ //char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size); char * qs_k2v(const char * key, char * const * qs_kv, int qs_kv_size, int nth); /* Non-destructive lookup of value, based on key. User provides the * destinaton string and length. */ char * qs_scanvalue(const char * key, const char * qs, char * val, size_t val_len); // TODO: implement sorting of the qs_kv array; for now ensure it's not compiled #undef _qsSORTING // isxdigit _is_ available in , but let's avoid another header instead #define ISHEX(x) ((((x)>='0'&&(x)<='9') || ((x)>='A'&&(x)<='F') || ((x)>='a'&&(x)<='f')) ? 1 : 0) #define HEX2DEC(x) (((x)>='0'&&(x)<='9') ? (x)-48 : ((x)>='A'&&(x)<='F') ? (x)-55 : ((x)>='a'&&(x)<='f') ? (x)-87 : 0) #define ISQSCHR(x) ((((x)=='=')||((x)=='#')||((x)=='&')||((x)=='\0')) ? 0 : 1) inline int qs_strncmp(const char * s, const char * qs, register size_t n) { int i=0; register unsigned char u1, u2, unyb, lnyb; while(n-- > 0) { u1 = (unsigned char) *s++; u2 = (unsigned char) *qs++; if ( ! ISQSCHR(u1) ) { u1 = '\0'; } if ( ! ISQSCHR(u2) ) { u2 = '\0'; } if ( u1 == '+' ) { u1 = ' '; } if ( u1 == '%' ) // easier/safer than scanf { unyb = (unsigned char) *s++; lnyb = (unsigned char) *s++; if ( ISHEX(unyb) && ISHEX(lnyb) ) u1 = (HEX2DEC(unyb) * 16) + HEX2DEC(lnyb); else u1 = '\0'; } if ( u2 == '+' ) { u2 = ' '; } if ( u2 == '%' ) // easier/safer than scanf { unyb = (unsigned char) *qs++; lnyb = (unsigned char) *qs++; if ( ISHEX(unyb) && ISHEX(lnyb) ) u2 = (HEX2DEC(unyb) * 16) + HEX2DEC(lnyb); else u2 = '\0'; } if ( u1 != u2 ) return u1 - u2; if ( u1 == '\0' ) return 0; i++; } if ( ISQSCHR(*qs) ) return -1; else return 0; } inline int qs_parse(char * qs, char * qs_kv[], int qs_kv_size) { int i, j; char * substr_ptr; for(i=0; i means x iterations of this loop -> means *x+1* k/v pairs // we only decode the values in place, the keys could have '='s in them // which will hose our ability to distinguish keys from values later for(j=0; j get_list (const std::string name) const { std::vector ret; std::string plus = name + "[]"; char* tmp = nullptr; int count = 0; do { tmp = qs_k2v(plus.c_str(), _kv_pairs, _kv_size, count++); if(tmp != nullptr) { ret.push_back(tmp); } } while(tmp != nullptr); return move(ret); } private: char _url[MAX_URL_SIZE]; char* _kv_pairs[NUM_KV_PAIRS]; int _kv_size; }; } // end namespace