Merge "Update PowerManager [dep:osp-common-service, osp-appfw, osp-appservice]" into...
[platform/framework/native/appfw.git] / src / text / FText_DecoderImpl.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                FText_DecoderImpl.cpp
19  * @brief               This is the implementation file for _DecoderImpl class.
20  */
21
22 #include <unique_ptr.h>
23 #include "FText_EncodingCore.h"
24 #include <FBaseSysLog.h>
25 #include "FText_DecoderImpl.h"
26
27 using namespace Tizen::Base;
28 using namespace Tizen::Base::Collection;
29 using namespace Tizen::Base::Utility;
30
31 namespace Tizen { namespace Text
32 {
33
34 _DecoderImpl::_DecoderImpl(void)
35         : __pDecoder(null)
36         , __encodingType("")
37 {
38 }
39
40 _DecoderImpl::~_DecoderImpl(void)
41 {
42 }
43
44 _DecoderImpl*
45 _DecoderImpl::GetDecoderN(const String& encodingType)
46 {
47         SysTryReturn(NID_TEXT, (encodingType == L"UTF-8"), null, E_INVALID_ARG,
48                         "[%s] Invalid argument is used.encdoingType(%ls) is not UTF-8.Failed to open decoder.", GetErrorMessage(E_INVALID_ARG), encodingType.GetPointer());
49
50         std::unique_ptr<_DecoderImpl> pDecoderImpl(new (std::nothrow) _DecoderImpl);
51         SysTryReturn(NID_TEXT, pDecoderImpl, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
52
53         pDecoderImpl->__pDecoder.reset(_EncodingCore::GetEncodingCoreN(encodingType, L"WCHAR_T"));
54
55         result r = GetLastResult();
56         SysTryReturn(NID_TEXT, (pDecoderImpl->__pDecoder != null), null, r,
57                            "[%s] Failed to open decoder.", GetErrorMessage(r));
58
59         pDecoderImpl->__encodingType = encodingType;
60         pDecoderImpl->_pDecoderImpl = pDecoderImpl.get();
61
62         SetLastResult(E_SUCCESS);
63         return pDecoderImpl.release();
64 }
65
66 result
67 _DecoderImpl::Decode(const byte* pSrc, int srcLength, WcharBuffer*& pWcharBuffer, int index, bool flush) const
68 {
69         SysAssertf(__pDecoder != null, "Not yet constructed! Construct() should be called before use.");
70
71         SysTryReturnResult(NID_TEXT, (pSrc != null), E_INVALID_ARG, "[%s] Invalid argument is used. pSrc can not be null.", GetErrorMessage(E_INVALID_ARG));
72         SysTryReturnResult(NID_TEXT, (srcLength >= 0), E_INVALID_ARG,
73                                 "[%s] Invalid argument is used. srcLength(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
74         SysTryReturnResult(NID_TEXT, (index >= 0), E_INVALID_ARG,
75                                 "[%s] Invalid argument is used. index(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), index);
76
77         result r = E_SUCCESS;
78         int currPosition = 0;
79         int retLength = 0;
80         bool isMemAllocReq = false;
81
82         std::unique_ptr<wchar_t[]> pDst(__pDecoder->DecodeExN(pSrc, srcLength, retLength, flush));
83         r = GetLastResult();
84         SysTryReturnResult(NID_TEXT, (pDst != null), r, "[%s] Decoding failed", GetErrorMessage(r));
85
86         WcharBuffer* pOutBuffer = pWcharBuffer;
87         if (retLength > 0)
88         {
89                 if (pOutBuffer == null)
90                 {
91                         isMemAllocReq = true;
92                         pOutBuffer = new (std::nothrow) WcharBuffer;
93                         SysTryCatch(NID_TEXT, (pOutBuffer != null), ,
94                                            E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Byte Buffer allocation failed");
95
96                         r = pOutBuffer->Construct(retLength);
97                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to Construct Byte buffer", GetErrorMessage(r));
98
99                         pWcharBuffer = pOutBuffer;
100
101                 }
102                 else
103                 {
104                         currPosition = pOutBuffer->GetPosition();
105
106                         r = pOutBuffer->SetPosition(index);
107                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
108                 }
109
110                 r = pOutBuffer->SetArray(pDst.get(), 0, retLength);
111                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
112
113                 r = pOutBuffer->SetPosition(currPosition);
114                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
115
116                 return r;
117         }
118
119 CATCH:
120         if (isMemAllocReq)
121         {
122                 delete pWcharBuffer;
123                 pWcharBuffer = null;
124         }
125         return r;
126 }
127
128 result
129 _DecoderImpl::GetCharCount(const ByteBuffer& bytes, int byteIndex, int byteCount, int& charCount, bool flush) const
130 {
131         SysAssertf(__pDecoder != null, "Not yet constructed! Construct() should be called before use.");
132
133         charCount = 0;
134         int inBufSize = bytes.GetLimit();
135         result r = CheckBufferInput(inBufSize, byteIndex, byteCount);
136         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
137
138         byte lastByte = 0;
139         r = bytes.GetByte(byteIndex + byteCount - 1, lastByte);
140         if (!IsFailed(r))
141         {
142                 if (lastByte == '\0')
143                 {
144                         byteCount--;
145                 }
146         }
147
148         r = __pDecoder->GetCharCount((bytes.GetPointer() + byteIndex), byteCount, charCount);
149
150         if (charCount < 0)
151         {
152                 charCount = 0;
153         }
154
155         return r;
156 }
157
158 WcharBuffer*
159 _DecoderImpl::GetCharsN(const ByteBuffer& bytes, bool flush) const
160 {
161         SysAssertf(__pDecoder != null, "Not yet constructed! Construct() should be called before use.");
162
163         WcharBuffer* pBuffer = null;
164         int srcLength = 0;
165         result r = GetBufferSize(bytes, srcLength);
166         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
167
168         r = Decode(bytes.GetPointer(), srcLength, pBuffer, 0, flush);
169
170         SetLastResult(r);
171         return pBuffer;
172 }
173
174 WcharBuffer*
175 _DecoderImpl::GetCharsN(const ByteBuffer& bytes, int byteIndex, int byteCount, bool flush) const
176 {
177         SysAssertf(__pDecoder != null, "Not yet constructed! Construct() should be called before use.");
178
179         WcharBuffer* pBuffer = null;
180         int srcLength = bytes.GetLimit();
181         result r = CheckBufferInput(srcLength, byteIndex, byteCount);
182         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
183
184         r = Decode(bytes.GetPointer() + byteIndex, byteCount, pBuffer, 0, flush);
185
186         SetLastResult(r);
187         return pBuffer;
188 }
189
190 result
191 _DecoderImpl::GetBufferSize(const ByteBuffer& bytes, int& byteBufSize) const
192 {
193         // It is assumed that user has set limit properly
194         byteBufSize = bytes.GetLimit();
195
196         // Adjusting byteBufSize if bytes has null char at the end
197         byte lastByte = 0;
198         result r = bytes.GetByte(byteBufSize - 1, lastByte);
199         SysTryReturnResult(NID_TEXT, (!IsFailed(r)), E_INVALID_ARG, "[%s] Last byte check failed", GetErrorMessage(r));
200
201         if ((lastByte == '\0')and(byteBufSize > 1))
202         {
203                 byteBufSize -= 1;
204         }
205         SysTryReturnResult(NID_TEXT, (byteBufSize > 0), E_INVALID_ARG,
206                         "[%s] Invalid argument is used. byteBufSize [%d] is invalid.", GetErrorMessage(E_INVALID_ARG), byteBufSize);
207
208         return E_SUCCESS;
209 }
210
211 result
212 _DecoderImpl::CheckBufferInput(int inBufSize, int inIndex, int inCount) const
213 {
214         SysTryReturnResult(NID_TEXT, (inIndex >= 0), E_INVALID_ARG,
215                                 "[%s] Invalid argument is used. inIndex(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inIndex);
216         SysTryReturnResult(NID_TEXT, (inCount >= 0), E_INVALID_ARG,
217                                 "[%s] Invalid argument is used. inCount(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inCount);
218         SysTryReturnResult(NID_TEXT, (inBufSize > 0), E_INVALID_ARG,
219                                 "[%s] Invalid argument is used. inBufSize(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inBufSize);
220
221         SysTryReturnResult(NID_TEXT, (inBufSize > inIndex), E_OUT_OF_RANGE,
222                                 "[%s] inIndex(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inIndex);
223         SysTryReturnResult(NID_TEXT, (inBufSize >= inCount), E_OUT_OF_RANGE,
224                                 "[%s] inCount(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inCount);
225         SysTryReturnResult(NID_TEXT, (inBufSize >= (inIndex + inCount)), E_UNDERFLOW,
226                         "[%s] sum of the length of the inIndex(%d) and inCount(%d) is greater than inBufSize(%d).",
227                         GetErrorMessage(E_UNDERFLOW), inIndex, inCount, inBufSize);
228         return E_SUCCESS;
229 }
230
231 } } // Tizen::Text