Merge "Update deprecated libprivilege-control API functions." into tizen
[platform/framework/native/appfw.git] / src / base / utility / FBaseUtilUrlDecoder.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Apache License, Version 2.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 /**
18  * @file                FBaseUtilUrlDecoder.cpp
19  * @brief               This is the implementation file for UrlDecoder class.
20  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <wchar.h>
24 #include <string.h>
25 #include <new>
26 #include <unique_ptr.h>
27 #include <unicode/ustring.h>
28 #include <unicode/utypes.h>
29 #include <unicode/ucnv.h>
30 #include <FBaseUtilUrlDecoder.h>
31 #include <FBaseResult.h>
32 #include <FBaseSysLog.h>
33 #include "FBase_StringConverter.h"
34 #include "FBase_NativeError.h"
35 #include "FBaseUtil_IcuConverter.h"
36
37 namespace Tizen { namespace Base { namespace Utility
38 {
39
40 UrlDecoder::UrlDecoder(void)
41 {
42
43 }
44
45 UrlDecoder::~UrlDecoder(void)
46 {
47
48 }
49
50 result
51 UrlDecoder::Decode(const Tizen::Base::String& str, const Tizen::Base::String& encodingScheme, Tizen::Base::String& decodedStr)
52 {
53         SysTryReturnResult(NID_BASE_UTIL, str.GetLength() > 0, E_INVALID_ARG, "String to be encoded is empty.");
54         SysTryReturnResult(NID_BASE_UTIL, encodingScheme.GetLength() > 0, E_INVALID_ARG, "Invalid encoding scheme.");
55
56         _ICUConverter converter;
57         bool converted = converter.OpenConverter(encodingScheme);
58         result r = GetLastResult();
59         SysTryReturnResult(NID_BASE_UTIL, converted, r, "Propagating.");
60
61         const wchar_t* pMchar = null;
62         int index = 0;
63         bool found = false;
64         int numChars = 0;
65         int charCount = 0;
66         wchar_t* pIn = null;
67
68         numChars = str.GetLength();
69         pMchar = str.GetPointer();
70         pIn = const_cast< wchar_t* >(&pMchar[0]);
71
72         std::unique_ptr< char[] > pUrlDecodedBuf(new (std::nothrow) char[numChars + 1]);
73         SysTryReturnResult(NID_BASE_UTIL, pUrlDecodedBuf != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
74
75         memset(pUrlDecodedBuf.get(), 0x00, numChars + 1);
76
77         charCount = numChars;
78         decodedStr.Clear();
79
80         //Decode url-encoded string
81         while (charCount > 0 && (*pIn != '\0'))
82         {
83                 if (*pIn == '%')
84                 {
85                         char hexChar[3];
86                         int decimal = 0;
87
88                         hexChar[0] = *(pIn + 1);
89                         hexChar[1] = *(pIn + 2);
90                         hexChar[2] = '\0';
91                         pIn += 3;
92
93                         //Converting %ab type substring to corresponing decimal value
94                         sscanf(hexChar, "%X", &decimal);
95                         pUrlDecodedBuf[index] = decimal;
96                         index++;
97                         charCount -= 3;
98                         found = true;
99                 }
100                 else
101                 {
102                         if (found)
103                         {
104                                 std::unique_ptr< wchar_t[] > pDst(converter.ConvertToUcharN(reinterpret_cast< const char* >(pUrlDecodedBuf.get()), index));
105                                 SysTryReturnResult(NID_BASE_UTIL, pDst != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
106                                 decodedStr.Append(pDst.get());
107                                 memset(pUrlDecodedBuf.get(), 0x00, numChars + 1);
108                                 index = 0;
109                                 found = false;
110                         }
111
112                         (*pIn == '+') ? decodedStr.Append(' ') : decodedStr.Append(*pIn);
113                         pIn++;
114                         charCount--;
115                 }
116         }
117
118         // if %XX is the last substring or all the substrings in input string are in form of %XX (e.g. %D7%91%D7%93%D7)
119         if (found)
120         {
121                 std::unique_ptr< wchar_t[] > pDst(converter.ConvertToUcharN(reinterpret_cast< const char* >(pUrlDecodedBuf.get()), index));
122                 r = GetLastResult();
123                 SysTryReturnResult(NID_BASE_UTIL, pDst != null, r, "Propagating.");
124                 decodedStr.Append(pDst.get());
125         }
126
127         converter.CloseConverter();
128         return r;
129 }
130 }}} // Tizen::Base::Utility