1 //******************************************************************
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
11 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "OCUtilities.h"
24 #include <boost/algorithm/string.hpp>
27 #include <uri.h> // libcoap
28 #include <option.h> // libcoap
31 // Helper function to escape special character.
32 std::string escapeString(const std::string& value)
34 std::ostringstream stringStream;
35 for (const char& c : value)
39 case '\\': stringStream << "\\\\";
41 case '"': stringStream << "\\\"";
43 case '/': stringStream << "\\/";
45 case '\b': stringStream << "\\b";
47 case '\f': stringStream << "\\f";
49 case '\n': stringStream << "\\n";
51 case '\r': stringStream << "\\r";
53 case '\t': stringStream << "\\t";
55 default: stringStream << c;
59 return stringStream.str();
62 // [TODO] remove this function
63 // this function is just a temporary patch for Sudarshan
64 // it seems that the C stack is parsing and giving out the query separately.
65 // the entire URI need not be parsed
66 static OC::Utilities::QueryParamsKeyVal tempPatch(const std::string& _uri)
68 OC::Utilities::QueryParamsKeyVal qp;
74 std::vector<std::string> queryparams;
75 boost::split(queryparams, _uri, boost::is_any_of("&"));
77 for(std::string& it: queryparams)
79 std::vector<std::string> keyval;
80 boost::split(keyval, it, boost::is_any_of("="));
81 if(2 == keyval.size())
83 qp[keyval.at(0)] = keyval.at(1);
90 // implementation can be split into two functions if needed
91 // uses do{}while(0) to avoid returning from multiple locations
92 OC::Utilities::QueryParamsKeyVal OC::Utilities::getQueryParams(const std::string& _uri)
95 // this is a temporary fix. [TODO] remove this after permanent fix
96 return tempPatch(_uri);
98 OC::Utilities::QueryParamsKeyVal qp;
99 unsigned char *bufptr = nullptr; // don't delete via bufptr
100 unsigned char *bufptrToDelete = nullptr; // bufptr may be incremented. need this one to keep track.
108 coap_uri_t coapuri = {{0}};
109 unsigned char* uristr = reinterpret_cast<unsigned char*>(const_cast<char*>(_uri.c_str()));
111 if(coap_split_uri(uristr, _uri.length(), &coapuri) < 0)
116 size_t buflen = 2048; // this is big enough buffer. [TODO] may want to downsize it. I have seen that the size may have to be greater than coap.query.length, which is counterintuitve but there may be a bug in coap uri parser.
117 bufptrToDelete = bufptr = new (std::nothrow) unsigned char[buflen](); // why heap? will need it for incrementing the pointer in the logic below
125 if((segments = coap_split_query(coapuri.query.s, coapuri.query.length, bufptr, &buflen)) < 0)
130 // coap uri parser has weird api. its not straighforward to understand what the coap function calls below do.
131 // coap uri parser lacks ability to split the key value pair in query params. that will be done in getQueryParams() function
132 std::vector<std::string> queryparams;
135 queryparams.push_back(std::string (reinterpret_cast<char*>(coap_opt_value(bufptr)), coap_opt_length(bufptr)));
136 bufptr += coap_opt_size(bufptr);
139 if(queryparams.empty())
145 for(std::string& it : queryparams)
147 std::vector<std::string> keyval;
148 boost::split(keyval, it, boost::is_any_of("="));
149 if(2 == keyval.size())
151 qp[keyval.at(0)] = keyval.at(1);
159 delete [] bufptrToDelete;