Remove unused variable
[platform/upstream/iotivity.git] / src / OCUtilities.cpp
1 //******************************************************************
2 //
3 // Copyright 2014 Intel Mobile Communications GmbH All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "OCUtilities.h"
22 #include <algorithm>
23 #include <iterator>
24 #include <boost/algorithm/string.hpp>
25 #include <sstream>
26 extern "C" {
27 #include <uri.h>    // libcoap
28 #include <option.h> // libcoap
29 }
30 namespace OC{
31     // Helper function to escape special character.
32     std::string escapeString(const std::string& value)
33     {
34         std::ostringstream stringStream;
35         for (const char& c : value)
36         {
37             switch (c)
38             {
39                 case '\\': stringStream << "\\\\";
40                     break;
41                 case '"': stringStream << "\\\"";
42                     break;
43                 case '/': stringStream << "\\/";
44                     break;
45                 case '\b': stringStream << "\\b";
46                     break;
47                 case '\f': stringStream << "\\f";
48                     break;
49                 case '\n': stringStream << "\\n";
50                     break;
51                 case '\r': stringStream << "\\r";
52                     break;
53                 case '\t': stringStream << "\\t";
54                     break;
55                 default: stringStream << c;
56                     break;
57            }
58         }
59         return stringStream.str();
60     }
61 }
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)
67 {
68     OC::Utilities::QueryParamsKeyVal qp;
69     if(_uri.empty())
70     {
71         return qp;
72     }
73
74     std::vector<std::string> queryparams;
75     boost::split(queryparams, _uri, boost::is_any_of("&"));
76
77     for(std::string& it: queryparams)
78     {
79         std::vector<std::string> keyval;
80         boost::split(keyval, it, boost::is_any_of("="));
81         if(2 == keyval.size())
82         {
83             qp[keyval.at(0)] = keyval.at(1);
84         }
85     }
86
87     return qp;
88 }
89
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)
93 {
94
95     // this is a temporary fix. [TODO] remove this after permanent fix
96     return tempPatch(_uri);
97
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.
101     do // while(0)
102     {
103         if(_uri.empty())
104         {
105             break;
106         }
107
108         coap_uri_t coapuri = {{0}};
109         unsigned char* uristr = reinterpret_cast<unsigned char*>(const_cast<char*>(_uri.c_str()));
110
111         if(coap_split_uri(uristr, _uri.length(), &coapuri) < 0)
112         {
113             break;
114         }
115
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
118
119         if(!bufptr)
120         {
121             break;
122         }
123
124         int segments = -1;
125         if((segments = coap_split_query(coapuri.query.s, coapuri.query.length, bufptr, &buflen)) < 0)
126         {
127             break;
128         }
129
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;
133         while(segments--)
134         {
135             queryparams.push_back(std::string (reinterpret_cast<char*>(coap_opt_value(bufptr)), coap_opt_length(bufptr)));
136             bufptr += coap_opt_size(bufptr);
137         }
138
139         if(queryparams.empty())
140         {
141             break;
142         }
143
144         //[TODO] use foreach
145         for(std::string& it : queryparams)
146         {
147             std::vector<std::string> keyval;
148             boost::split(keyval, it, boost::is_any_of("="));
149             if(2 == keyval.size())
150             {
151                 qp[keyval.at(0)] = keyval.at(1);
152             }
153         }
154     }
155     while(0);
156
157     if(bufptrToDelete)
158     {
159         delete [] bufptrToDelete;
160     }
161     return qp;
162 }