1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
// --------------------------------------------------------------------------
//
// File
// Name: HTTPQueryDecoder.cpp
// Purpose: Utility class to decode HTTP query strings
// Created: 26/3/04
//
// --------------------------------------------------------------------------
#include "Box.h"
#include <stdlib.h>
#include "HTTPQueryDecoder.h"
#include "MemLeakFindOn.h"
// --------------------------------------------------------------------------
//
// Function
// Name: HTTPQueryDecoder::HTTPQueryDecoder(
// HTTPRequest::Query_t &)
// Purpose: Constructor. Pass in the query contents you want
// to decode the query string into.
// Created: 26/3/04
//
// --------------------------------------------------------------------------
HTTPQueryDecoder::HTTPQueryDecoder(HTTPRequest::Query_t &rDecodeInto)
: mrDecodeInto(rDecodeInto),
mInKey(true),
mEscapedState(0)
{
// Insert the terminator for escaped characters
mEscaped[2] = '\0';
}
// --------------------------------------------------------------------------
//
// Function
// Name: HTTPQueryDecoder::~HTTPQueryDecoder()
// Purpose: Destructor.
// Created: 26/3/04
//
// --------------------------------------------------------------------------
HTTPQueryDecoder::~HTTPQueryDecoder()
{
}
// --------------------------------------------------------------------------
//
// Function
// Name: HTTPQueryDecoder::Decode(const char *, int)
// Purpose: Decode a chunk of query string -- call several times with
// the bits as they are received, and then call Finish()
// Created: 26/3/04
//
// --------------------------------------------------------------------------
void HTTPQueryDecoder::DecodeChunk(const char *pQueryString, int QueryStringSize)
{
for(int l = 0; l < QueryStringSize; ++l)
{
char c = pQueryString[l];
// BEFORE unescaping, check to see if we need to flip key / value
if(mEscapedState == 0)
{
if(mInKey && c == '=')
{
// Set to store characters in the value
mInKey = false;
continue;
}
else if(!mInKey && c == '&')
{
// Need to store the current key/value pair
mrDecodeInto.insert(HTTPRequest::QueryEn_t(mCurrentKey, mCurrentValue));
// Blank the strings
mCurrentKey.erase();
mCurrentValue.erase();
// Set to store characters in the key
mInKey = true;
continue;
}
}
// Decode an escaped value?
if(mEscapedState == 1)
{
// Waiting for char one of the escaped hex value
mEscaped[0] = c;
mEscapedState = 2;
continue;
}
else if(mEscapedState == 2)
{
// Escaped value, decode it
mEscaped[1] = c; // str terminated in constructor
mEscapedState = 0; // stop being in escaped mode
long ch = ::strtol(mEscaped, NULL, 16);
if(ch <= 0 || ch > 255)
{
// Bad character, just ignore
continue;
}
// Use this instead
c = (char)ch;
}
else if(c == '+')
{
c = ' ';
}
else if(c == '%')
{
mEscapedState = 1;
continue;
}
// Store decoded value into the appropriate string
if(mInKey)
{
mCurrentKey += c;
}
else
{
mCurrentValue += c;
}
}
// Don't do anything here with left over values, DecodeChunk might be called
// again. Let Finish() clean up.
}
// --------------------------------------------------------------------------
//
// Function
// Name: HTTPQueryDecoder::Finish()
// Purpose: Finish the decoding. Necessary to get the last item!
// Created: 26/3/04
//
// --------------------------------------------------------------------------
void HTTPQueryDecoder::Finish()
{
// Insert any remaining value.
if(!mCurrentKey.empty())
{
mrDecodeInto.insert(HTTPRequest::QueryEn_t(mCurrentKey, mCurrentValue));
// Blank values, just in case
mCurrentKey.erase();
mCurrentValue.erase();
}
}
|