aboutsummaryrefslogtreecommitdiffstats
path: root/include/query_string.h
diff options
context:
space:
mode:
authoripknHama <ipknhama@gmail.com>2016-09-21 23:11:06 +0900
committeripknHama <ipknhama@gmail.com>2016-09-21 23:11:06 +0900
commit3081e4e1a82a4efd8feff68850c4cc04af230cd7 (patch)
tree3ad16ef2e940abd2d47c4ac3ca224365387b7f37 /include/query_string.h
parent8b04940d2f28290451db439ad29155a0b8771ba3 (diff)
downloadcrow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.tar.gz
crow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.zip
Cleanup include folder into crow subfolder
- only crow.h is exposed now
Diffstat (limited to 'include/query_string.h')
-rw-r--r--include/query_string.h342
1 files changed, 0 insertions, 342 deletions
diff --git a/include/query_string.h b/include/query_string.h
deleted file mode 100644
index 03e5cfd..0000000
--- a/include/query_string.h
+++ /dev/null
@@ -1,342 +0,0 @@
-#pragma once
-
-#include <stdio.h>
-#include <string.h>
-#include <string>
-#include <vector>
-#include <iostream>
-
-// ----------------------------------------------------------------------------
-// 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, 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 <ctype.h>, but let's avoid another header instead
-#define CROW_QS_ISHEX(x) ((((x)>='0'&&(x)<='9') || ((x)>='A'&&(x)<='F') || ((x)>='a'&&(x)<='f')) ? 1 : 0)
-#define CROW_QS_HEX2DEC(x) (((x)>='0'&&(x)<='9') ? (x)-48 : ((x)>='A'&&(x)<='F') ? (x)-55 : ((x)>='a'&&(x)<='f') ? (x)-87 : 0)
-#define CROW_QS_ISQSCHR(x) ((((x)=='=')||((x)=='#')||((x)=='&')||((x)=='\0')) ? 0 : 1)
-
-inline int qs_strncmp(const char * s, const char * qs, size_t n)
-{
- int i=0;
- unsigned char u1, u2, unyb, lnyb;
-
- while(n-- > 0)
- {
- u1 = (unsigned char) *s++;
- u2 = (unsigned char) *qs++;
-
- if ( ! CROW_QS_ISQSCHR(u1) ) { u1 = '\0'; }
- if ( ! CROW_QS_ISQSCHR(u2) ) { u2 = '\0'; }
-
- if ( u1 == '+' ) { u1 = ' '; }
- if ( u1 == '%' ) // easier/safer than scanf
- {
- unyb = (unsigned char) *s++;
- lnyb = (unsigned char) *s++;
- if ( CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb) )
- u1 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
- else
- u1 = '\0';
- }
-
- if ( u2 == '+' ) { u2 = ' '; }
- if ( u2 == '%' ) // easier/safer than scanf
- {
- unyb = (unsigned char) *qs++;
- lnyb = (unsigned char) *qs++;
- if ( CROW_QS_ISHEX(unyb) && CROW_QS_ISHEX(lnyb) )
- u2 = (CROW_QS_HEX2DEC(unyb) * 16) + CROW_QS_HEX2DEC(lnyb);
- else
- u2 = '\0';
- }
-
- if ( u1 != u2 )
- return u1 - u2;
- if ( u1 == '\0' )
- return 0;
- i++;
- }
- if ( CROW_QS_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<qs_kv_size; i++) qs_kv[i] = NULL;
-
- // find the beginning of the k/v substrings or the fragment
- substr_ptr = qs + strcspn(qs, "?#");
- if (substr_ptr[0] != '\0')
- substr_ptr++;
- else
- return 0; // no query or fragment
-
- i=0;
- while(i<qs_kv_size)
- {
- qs_kv[i] = substr_ptr;
- j = strcspn(substr_ptr, "&");
- if ( substr_ptr[j] == '\0' ) { break; }
- substr_ptr += j + 1;
- i++;
- }
- i++; // x &'s -> 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<i; j++)
- {
- substr_ptr = qs_kv[j] + strcspn(qs_kv[j], "=&#");
- if ( substr_ptr[0] == '&' || substr_ptr[0] == '\0') // blank value: skip decoding
- substr_ptr[0] = '\0';
- else
- qs_decode(++substr_ptr);
- }
-
-#ifdef _qsSORTING
-// TODO: qsort qs_kv, using qs_strncmp() for the comparison
-#endif
-
- return i;
-}
-
-
-inline int qs_decode(char * qs)
-{
- int i=0, j=0;
-
- while( CROW_QS_ISQSCHR(qs[j]) )
- {
- if ( qs[j] == '+' ) { qs[i] = ' '; }
- else if ( qs[j] == '%' ) // easier/safer than scanf
- {
- if ( ! CROW_QS_ISHEX(qs[j+1]) || ! CROW_QS_ISHEX(qs[j+2]) )
- {
- qs[i] = '\0';
- return i;
- }
- qs[i] = (CROW_QS_HEX2DEC(qs[j+1]) * 16) + CROW_QS_HEX2DEC(qs[j+2]);
- j+=2;
- }
- else
- {
- qs[i] = qs[j];
- }
- i++; j++;
- }
- qs[i] = '\0';
-
- return i;
-}
-
-
-inline char * qs_k2v(const char * key, char * const * qs_kv, int qs_kv_size, int nth = 0)
-{
- int i;
- size_t key_len, skip;
-
- key_len = strlen(key);
-
-#ifdef _qsSORTING
-// TODO: binary search for key in the sorted qs_kv
-#else // _qsSORTING
- for(i=0; i<qs_kv_size; i++)
- {
- // we rely on the unambiguous '=' to find the value in our k/v pair
- if ( qs_strncmp(key, qs_kv[i], key_len) == 0 )
- {
- skip = strcspn(qs_kv[i], "=");
- if ( qs_kv[i][skip] == '=' )
- skip++;
- // return (zero-char value) ? ptr to trailing '\0' : ptr to value
- if(nth == 0)
- return qs_kv[i] + skip;
- else
- --nth;
- }
- }
-#endif // _qsSORTING
-
- return NULL;
-}
-
-
-inline char * qs_scanvalue(const char * key, const char * qs, char * val, size_t val_len)
-{
- size_t i, key_len;
- const char * tmp;
-
- // find the beginning of the k/v substrings
- if ( (tmp = strchr(qs, '?')) != NULL )
- qs = tmp + 1;
-
- key_len = strlen(key);
- while(qs[0] != '#' && qs[0] != '\0')
- {
- if ( qs_strncmp(key, qs, key_len) == 0 )
- break;
- qs += strcspn(qs, "&") + 1;
- }
-
- if ( qs[0] == '\0' ) return NULL;
-
- qs += strcspn(qs, "=&#");
- if ( qs[0] == '=' )
- {
- qs++;
- i = strcspn(qs, "&=#");
- strncpy(val, qs, (val_len-1)<(i+1) ? (val_len-1) : (i+1));
- qs_decode(val);
- }
- else
- {
- if ( val_len > 0 )
- val[0] = '\0';
- }
-
- return val;
-}
-// ----------------------------------------------------------------------------
-
-
-namespace crow
-{
- class query_string
- {
- public:
- static const int MAX_KEY_VALUE_PAIRS_COUNT = 256;
-
- query_string()
- {
-
- }
-
- query_string(const query_string& qs)
- : url_(qs.url_)
- {
- for(auto p:qs.key_value_pairs_)
- {
- key_value_pairs_.push_back((char*)(p-qs.url_.c_str()+url_.c_str()));
- }
- }
-
- query_string& operator = (const query_string& qs)
- {
- url_ = qs.url_;
- key_value_pairs_.clear();
- for(auto p:qs.key_value_pairs_)
- {
- key_value_pairs_.push_back((char*)(p-qs.url_.c_str()+url_.c_str()));
- }
- return *this;
- }
-
- query_string& operator = (query_string&& qs)
- {
- key_value_pairs_ = std::move(qs.key_value_pairs_);
- char* old_data = (char*)qs.url_.c_str();
- url_ = std::move(qs.url_);
- for(auto& p:key_value_pairs_)
- {
- p += (char*)url_.c_str() - old_data;
- }
- return *this;
- }
-
-
- query_string(std::string url)
- : url_(std::move(url))
- {
- if (url_.empty())
- return;
-
- key_value_pairs_.resize(MAX_KEY_VALUE_PAIRS_COUNT);
-
- int count = qs_parse(&url_[0], &key_value_pairs_[0], MAX_KEY_VALUE_PAIRS_COUNT);
- key_value_pairs_.resize(count);
- }
-
- void clear()
- {
- key_value_pairs_.clear();
- url_.clear();
- }
-
- friend std::ostream& operator<<(std::ostream& os, const query_string& qs)
- {
- os << "[ ";
- for(size_t i = 0; i < qs.key_value_pairs_.size(); ++i) {
- if (i)
- os << ", ";
- os << qs.key_value_pairs_[i];
- }
- os << " ]";
- return os;
-
- }
-
- char* get (const std::string& name) const
- {
- char* ret = qs_k2v(name.c_str(), key_value_pairs_.data(), key_value_pairs_.size());
- return ret;
- }
-
- std::vector<char*> get_list (const std::string& name) const
- {
- std::vector<char*> ret;
- std::string plus = name + "[]";
- char* element = nullptr;
-
- int count = 0;
- while(1)
- {
- element = qs_k2v(plus.c_str(), key_value_pairs_.data(), key_value_pairs_.size(), count++);
- if (!element)
- break;
- ret.push_back(element);
- }
- return ret;
- }
-
-
- private:
- std::string url_;
- std::vector<char*> key_value_pairs_;
- };
-
-} // end namespace