From 1ec5c4bd38990ca4fb82537e0a7099ec50b8bdf8 Mon Sep 17 00:00:00 2001 From: JAJames Date: Sat, 30 Jan 2016 03:55:17 -0500 Subject: [PATCH] Added 'HTTP::HTMLFormResponse', which provides functionality similar to 'HTTP::QueryString' --- Jupiter/HTTP_QueryString.h | 92 +++++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/Jupiter/HTTP_QueryString.h b/Jupiter/HTTP_QueryString.h index dcf2be6..8a94686 100644 --- a/Jupiter/HTTP_QueryString.h +++ b/Jupiter/HTTP_QueryString.h @@ -20,6 +20,7 @@ #define _HTTP_QUERYSTRING_H_HEADER #include "String.h" +#include "INIFile.h" /** * @file HTTP_QueryString.h @@ -37,16 +38,86 @@ namespace Jupiter { public: QueryString() = delete; - inline QueryString(const Jupiter::ReadableString ¶meters) : QueryString(parameters.ptr(), parameters.size()) {} + inline QueryString(const Jupiter::ReadableString &query_string) : QueryString(query_string.ptr(), query_string.size()) {} inline QueryString(const char *ptr, size_t str_size); }; + + /** + * @brief Provides parsing for HTML form responses. + * Note: This is essentially the same thing as QueryString, except key/value pairs are pared into 'table'. + */ + class HTMLFormResponse : public Jupiter::StringS + { + public: + HTMLFormResponse() = delete; + inline HTMLFormResponse(const Jupiter::ReadableString &query_string) : HTMLFormResponse(query_string.ptr(), query_string.size()) {} + inline HTMLFormResponse(const char *ptr, size_t str_size); + Jupiter::INIFile table; + }; } } /** Implementation */ inline Jupiter::HTTP::QueryString::QueryString(const char *ptr, size_t str_size) : Jupiter::StringS(str_size) { - if (str_size < 3) // not enough room for "%XX", therefore no parameters to parse + if (str_size < 3) // not enough room for "%XX", therefore no escaped characters to parse + { + Jupiter::StringType::length = str_size; + switch (str_size) + { + case 2: + str[1] = ptr[1]; + case 1: + *str = *ptr; + case 0: + // nothing to copy + return; + } + } + + const char *end = ptr + str_size - 2; + char *buf = str; + int val; + + while (ptr != end) + { + if (*ptr == '%') + { + if ((val = Jupiter_getHex(*++ptr)) != -1) + { + *buf = static_cast(val) << 4; + if ((val = Jupiter_getHex(*++ptr)) != -1) + *buf |= val; + + ++buf, ++ptr; + if (ptr > end) + { + if (ptr == end + 1) // copy 1 remaining character + { + *buf = *ptr; + ++buf; + } + Jupiter::StringType::length = buf - Jupiter::StringType::str; + return; + } + } + } + else // Copy character + { + *buf = *ptr; + ++buf, ++ptr; + } + } + + // copy last 2 characters + *buf = *ptr; + *++buf = *++ptr; + Jupiter::StringType::length = buf + 1 - str; +} + +inline Jupiter::HTTP::HTMLFormResponse::HTMLFormResponse(const char *ptr, size_t str_size) : Jupiter::StringS(str_size) +{ + if (str_size < 3) // not enough room for "%XX", therefore no escaped characters to parse { Jupiter::StringType::length = str_size; switch (str_size) @@ -61,9 +132,11 @@ inline Jupiter::HTTP::QueryString::QueryString(const char *ptr, size_t str_size) } } + const char *token_start = ptr; const char *end = ptr + str_size - 2; char *buf = str; int val; + Jupiter::ReferenceString key; while (ptr != end) { @@ -88,6 +161,21 @@ inline Jupiter::HTTP::QueryString::QueryString(const char *ptr, size_t str_size) } } } + else if (*ptr == '&') // End of key/value, start of key + { + if (key.isNotEmpty()) // A key was already set; end of value + Jupiter::HTTP::HTMLFormResponse::table.set(Jupiter::ReferenceString::empty, key, Jupiter::ReferenceString(token_start, ptr - token_start)); + + key.erase(); + ++buf, ++ptr; + token_start = ptr; + } + else if (*ptr == '=') // End of key, start of value + { + key.set(token_start, ptr - token_start); + ++buf, ++ptr; + token_start = ptr; + } else // Copy character { *buf = *ptr;