NetServices Stack source
Dependents: HelloWorld ServoInterfaceBoardExample1 4180_Lab4
HTTPMap.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "HTTPMap.h" 00025 #include "../../util/url.h" 00026 00027 //#define __DEBUG 00028 #include "dbg/dbg.h" 00029 00030 HTTPMap::HTTPMap(const string& keyValueSep /*= "="*/, const string& pairSep /*= "&"*/) : 00031 HTTPData(), Dictionary(), m_buf(), m_len(0), m_chunked(false), m_keyValueSep(keyValueSep), m_pairSep(pairSep) 00032 { 00033 00034 } 00035 00036 HTTPMap::~HTTPMap() 00037 { 00038 00039 } 00040 00041 void HTTPMap::clear() 00042 { 00043 m_buf.clear(); 00044 } 00045 00046 int HTTPMap::read(char* buf, int len) 00047 { 00048 memcpy( (void*)buf, (void*)m_buf.data(), len ); 00049 m_buf.erase(0, len); //Erase these chars 00050 return len; 00051 } 00052 00053 int HTTPMap::write(const char* buf, int len) 00054 { 00055 m_buf.append( buf, len ); 00056 if( ( m_chunked && !len ) || 00057 ( !m_chunked && ( m_buf.length() >= m_len ) ) ) //Last chunk or EOF 00058 { 00059 parseString(); 00060 } 00061 return len; 00062 } 00063 00064 string HTTPMap::getDataType() //Internet media type for Content-Type header 00065 { 00066 return "application/x-www-form-urlencoded"; 00067 } 00068 00069 void HTTPMap::setDataType(const string& type) //Internet media type from Content-Type header 00070 { 00071 //Do not really care here 00072 } 00073 00074 int HTTPMap::getDataLen() //For Content-Length header 00075 { 00076 //This will be called before any read occurs, so let's generate our string object 00077 //Generate string 00078 generateString(); 00079 return m_len; 00080 } 00081 00082 bool HTTPMap::getIsChunked() //For Transfer-Encoding header 00083 { 00084 return false; //We don't want to chunk this 00085 } 00086 00087 void HTTPMap::setIsChunked(bool chunked) //From Transfer-Encoding header 00088 { 00089 m_chunked = chunked; 00090 } 00091 00092 void HTTPMap::setDataLen(int len) //From Content-Length header, or if the transfer is chunked, next chunk length 00093 { 00094 m_len += len; //Useful so that we can parse string when last byte is written if not chunked 00095 m_buf.reserve( m_len ); 00096 } 00097 00098 void HTTPMap::generateString() 00099 { 00100 Dictionary::iterator it; 00101 bool first = true; 00102 while( !Dictionary::empty() ) 00103 { 00104 if(!first) 00105 { 00106 m_buf.append( m_pairSep ); 00107 } 00108 else 00109 { 00110 first = false; 00111 } 00112 it = Dictionary::begin(); 00113 m_buf.append( Url::encode( (*it).first ) ); 00114 m_buf.append( m_keyValueSep ); 00115 m_buf.append( Url::encode( (*it).second ) ); 00116 Dictionary::erase(it); //Free memory as we process data 00117 } 00118 m_len = m_buf.length(); 00119 DBG("\r\nData [len %d]:\r\n%s\r\n", m_len, m_buf.c_str()); 00120 } 00121 00122 void HTTPMap::parseString() 00123 { 00124 string key; 00125 string value; 00126 00127 int pos = 0; 00128 00129 int key_pos; 00130 int key_len; 00131 00132 int value_pos; 00133 int value_len; 00134 00135 bool eof = false; 00136 while(!eof) 00137 { 00138 key_pos = pos; 00139 value_pos = m_buf.find(m_keyValueSep, pos); 00140 if(value_pos < 0) 00141 { 00142 //Parse error, break 00143 break; 00144 } 00145 00146 key_len = value_pos - key_pos; 00147 00148 value_pos+= m_keyValueSep.length(); 00149 00150 pos = m_buf.find( m_pairSep, value_pos ); 00151 if(pos < 0) //Not found 00152 { 00153 pos = m_buf.length(); 00154 eof = true; 00155 } 00156 00157 value_len = pos - value_pos; 00158 00159 pos += m_pairSep.length(); 00160 00161 //Append elenent 00162 Dictionary::operator[]( Url::decode( m_buf.substr(key_pos, key_len) ) ) = Url::decode( m_buf.substr(value_pos, value_len) ); 00163 } 00164 00165 m_buf.clear(); //Free data 00166 00167 }
Generated on Tue Jul 12 2022 11:52:57 by 1.7.2