diff options
Diffstat (limited to 'src/Uri.cpp')
-rw-r--r-- | src/Uri.cpp | 141 |
1 files changed, 11 insertions, 130 deletions
diff --git a/src/Uri.cpp b/src/Uri.cpp index f122c0a..208297d 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -6,6 +6,9 @@ * © 2018 by Richard Walters */ +#include "IsCharacterInSet.hpp" +#include "PercentEncodedCharacterDecoder.hpp" + #include <functional> #include <inttypes.h> #include <memory> @@ -81,41 +84,6 @@ namespace { } /** - * This function determines whether or not the given character - * is in the given character set. - * - * @param[in] c - * This is the character to check. - * - * @param[in] characterSet - * This is the set of characters that are allowed. - * - * @return - * An indication of whether or not the given character - * is in the given character set is returned. - */ - bool IsCharacterInSet( - char c, - std::initializer_list< char > characterSet - ) { - for ( - auto charInSet = characterSet.begin(); - charInSet != characterSet.end(); - ++charInSet - ) { - const auto first = *charInSet++; - const auto last = *charInSet; - if ( - (c >= first) - && (c <= last) - ) { - return true; - } - } - return false; - } - - /** * This function returns a strategy function that * may be used with the FailsMatch function to test a scheme * to make sure it is legal according to the standard. @@ -133,9 +101,9 @@ namespace { } else { bool check; if (*isFirstCharacter) { - check = IsCharacterInSet(c, { 'a','z', 'A','Z' }); + check = Uri::IsCharacterInSet(c, { 'a','z', 'A','Z' }); } else { - check = IsCharacterInSet(c, { 'a','z', 'A','Z', '0','9', '+','+', '-','-', '.','.' }); + check = Uri::IsCharacterInSet(c, { 'a','z', 'A','Z', '0','9', '+','+', '-','-', '.','.' }); } *isFirstCharacter = false; return check; @@ -144,93 +112,6 @@ namespace { } /** - * This class can take in a percent-encoded character, - * decode it, and also detect if there are any problems in the encoding. - */ - class PercentEncodedCharacterDecoder { - // Methods - public: - /** - * This method inputs the next encoded character. - * - * @param[in] c - * This is the next encoded character to give to the decoder. - * - * @return - * An indication of whether or not the encoded character - * was accepted is returned. - */ - bool NextEncodedCharacter(char c) { - switch(decoderState_) { - case 0: { // % ... - decoderState_ = 1; - decodedCharacter_ <<= 4; - if (IsCharacterInSet(c, {'0','9'})) { - decodedCharacter_ += (int)(c - '0'); - } else if (IsCharacterInSet(c, {'A','F'})) { - decodedCharacter_ += (int)(c - 'A') + 10; - } else { - return false; - } - } break; - - case 1: { // %[0-9A-F] ... - decoderState_ = 2; - decodedCharacter_ <<= 4; - if (IsCharacterInSet(c, {'0','9'})) { - decodedCharacter_ += (int)(c - '0'); - } else if (IsCharacterInSet(c, {'A','F'})) { - decodedCharacter_ += (int)(c - 'A') + 10; - } else { - return false; - } - } break; - - default: break; - } - return true; - } - - /** - * This method checks to see if the decoder is done - * and has decoded the encoded character. - * - * @return - * An indication of whether or not the decoder is done - * and has decoded the encoded character is returned. - */ - bool Done() const { - return (decoderState_ == 2); - } - - /** - * This method returns the decoded character, once - * the decoder is done. - * - * @return - * The decoded character is returned. - */ - char GetDecodedCharacter() const { - return (char)decodedCharacter_; - } - - // Properties - private: - /** - * This is the decoded character. - */ - int decodedCharacter_ = 0; - - /** - * This is the current state of the decoder's state machine. - * - 0: we haven't yet received the first hex digit. - * - 1: we received the first hex digit but not the second. - * - 2: we received both hex digits - */ - size_t decoderState_ = 0; - }; - - /** * This method checks and decodes the given path segment. * * @param[in,out] segment @@ -246,16 +127,16 @@ namespace { segment.clear(); size_t decoderState = 0; int decodedCharacter = 0; - PercentEncodedCharacterDecoder pecDecoder; + Uri::PercentEncodedCharacterDecoder pecDecoder; for (const auto c: originalSegment) { switch(decoderState) { case 0: { // default if (c == '%') { - pecDecoder = PercentEncodedCharacterDecoder(); + pecDecoder = Uri::PercentEncodedCharacterDecoder(); decoderState = 1; } else { if ( - IsCharacterInSet( + Uri::IsCharacterInSet( c, { // unreserved @@ -309,16 +190,16 @@ namespace { queryOrFragment.clear(); size_t decoderState = 0; int decodedCharacter = 0; - PercentEncodedCharacterDecoder pecDecoder; + Uri::PercentEncodedCharacterDecoder pecDecoder; for (const auto c: originalQueryOrFragment) { switch(decoderState) { case 0: { // default if (c == '%') { - pecDecoder = PercentEncodedCharacterDecoder(); + pecDecoder = Uri::PercentEncodedCharacterDecoder(); decoderState = 1; } else { if ( - IsCharacterInSet( + Uri::IsCharacterInSet( c, { // unreserved |