u-blox modem HTTP client test

Dependencies:   UbloxUSBModem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPMap.cpp Source File

HTTPMap.cpp

00001 /* HTTPMap.cpp */
00002 /* Copyright (C) 2012 mbed.org, MIT License
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00005  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00006  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00007  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00008  * furnished to do so, subject to the following conditions:
00009  *
00010  * The above copyright notice and this permission notice shall be included in all copies or
00011  * substantial portions of the Software.
00012  *
00013  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00014  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00015  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00016  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00017  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00018  */
00019 
00020 #include "HTTPMap.h"
00021 
00022 #include <cstring>
00023 
00024 #include <cctype>
00025 
00026 #define OK 0
00027 
00028 using std::strncpy;
00029 
00030 HTTPMap::HTTPMap() : m_pos(0), m_count(0)
00031 {
00032 
00033 }
00034 
00035 void HTTPMap::put(const char* key, const char* value)
00036 {
00037   if(m_count >= HTTPMAP_TABLE_SIZE)
00038   {
00039     return;
00040   }
00041   m_keys[m_count] = key;
00042   m_values[m_count] = value;
00043   m_count++;
00044 }
00045 
00046 void HTTPMap::clear()
00047 {
00048   m_count = 0;
00049   m_pos = 0;
00050 }
00051 
00052 /*virtual*/ void HTTPMap::readReset()
00053 {
00054   m_pos = 0;
00055 }
00056 
00057 /*virtual*/ int HTTPMap::read(char* buf, size_t len, size_t* pReadLen)
00058 {
00059   if(m_pos >= m_count)
00060   {
00061     *pReadLen = 0;
00062     m_pos = 0;
00063     return OK;
00064   }
00065 
00066   //URL encode
00067   char* out = buf;
00068   const char* in = m_keys[m_pos];
00069   if( (m_pos != 0) && (out - buf < len - 1) )
00070   {
00071     *out='&';
00072     out++;
00073   }
00074 
00075   while( (*in != '\0') && (out - buf < len - 3) )
00076   {
00077     if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
00078     {
00079       *out = *in;
00080       out++;
00081     }
00082     else if( *in == ' ' )
00083     {
00084       *out='+';
00085       out++;
00086     }
00087     else
00088     {
00089       char hex[] = "0123456789abcdef";
00090       *out='%';
00091       out++;
00092       *out=hex[(*in>>4)&0xf];
00093       out++;
00094       *out=hex[(*in)&0xf];
00095       out++;
00096     }
00097     in++;
00098   }
00099 
00100   if( out - buf < len - 1 )
00101   {
00102     *out='=';
00103     out++;
00104   }
00105 
00106   in = m_values[m_pos];
00107   while( (*in != '\0') && (out - buf < len - 3) )
00108   {
00109     if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
00110     {
00111       *out = *in;
00112       out++;
00113     }
00114     else if( *in == ' ' )
00115     {
00116       *out='+';
00117       out++;
00118     }
00119     else
00120     {
00121       char hex[] = "0123456789abcdef";
00122       *out='%';
00123       out++;
00124       *out=hex[(*in>>4)&0xf];
00125       out++;
00126       *out=hex[(*in)&0xf];
00127       out++;
00128     }
00129     in++;
00130   }
00131 
00132   *pReadLen = out - buf;
00133 
00134   m_pos++;
00135   return OK;
00136 }
00137 
00138 /*virtual*/ int HTTPMap::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header
00139 {
00140   strncpy(type, "application/x-www-form-urlencoded", maxTypeLen-1);
00141   type[maxTypeLen-1] = '\0';
00142   return OK;
00143 }
00144 
00145 /*virtual*/ bool HTTPMap::getIsChunked() //For Transfer-Encoding header
00146 {
00147   return false; ////Data is computed one key/value pair at a time
00148 }
00149 
00150 /*virtual*/ size_t HTTPMap::getDataLen() //For Content-Length header
00151 {
00152   size_t count = 0;
00153   for(size_t i = 0; i< m_count; i++)
00154   {
00155     //URL encode
00156     const char* in = m_keys[i];
00157     if( i != 0 )
00158     {
00159       count++;
00160     }
00161 
00162     while( (*in != '\0') )
00163     {
00164       if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
00165       {
00166         count++;
00167       }
00168       else if( *in == ' ' )
00169       {
00170         count++;
00171       }
00172       else
00173       {
00174         count+=3;
00175       }
00176       in++;
00177     }
00178 
00179     count ++;
00180 
00181     in = m_values[i];
00182     while( (*in != '\0') )
00183     {
00184       if (std::isalnum(*in) || *in == '-' || *in == '_' || *in == '.' || *in == '~')
00185       {
00186         count++;
00187       }
00188       else if( *in == ' ' )
00189       {
00190         count++;
00191       }
00192       else
00193       {
00194         count+=3;
00195       }
00196       in++;
00197     }
00198   }
00199   return count;
00200 }