sync with tizen_2.0
[platform/framework/native/appfw.git] / src / text / FText_EncoderImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FText_EncoderImpl.cpp
20  * @brief               This is the implementation file for _EncoderImpl class.
21  */
22
23 #include "FText_EncodingCore.h"
24 #include <FBaseSysLog.h>
25 #include "FText_EncoderImpl.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 _EncoderImpl::_EncoderImpl(void)
35         : __pEncoder(null)
36         , __encodingType("")
37 {
38 }
39
40 _EncoderImpl::~_EncoderImpl(void)
41 {
42
43 }
44
45 _EncoderImpl*
46 _EncoderImpl::GetEncoderN(const String& encodingType)
47 {
48         SysTryReturn(NID_TEXT, (encodingType == L"UTF-8"), null, E_INVALID_ARG,
49                         "[%s] Invalid argument is used.encdoingType(%ls) is not UTF-8.Failed to open encoder.", GetErrorMessage(E_INVALID_ARG), encodingType.GetPointer());
50
51         std::unique_ptr<_EncoderImpl> pEncoderImpl( new (std::nothrow) _EncoderImpl);
52         SysTryReturn(NID_TEXT, pEncoderImpl, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
53
54         pEncoderImpl->__pEncoder.reset(_EncodingCore::GetEncodingCoreN(encodingType, L"WCHAR_T"));
55
56         result r = GetLastResult();
57         SysTryReturn(NID_TEXT, (pEncoderImpl->__pEncoder != null), null, r,
58                            "[%s] Failed to open encoder.", GetErrorMessage(r));
59
60         pEncoderImpl->__encodingType = encodingType;
61         pEncoderImpl->_pEncoderImpl = pEncoderImpl.get();
62
63         SetLastResult(E_SUCCESS);
64         return pEncoderImpl.release();
65 }
66
67 result
68 _EncoderImpl::Encode(const wchar_t* pSrc, int srcLength, ByteBuffer*& pByteBuffer, int index, bool flush) const
69 {
70         SysAssertf(__pEncoder != null, "Not yet constructed! Construct() should be called before use.");
71
72         SysTryReturnResult(NID_TEXT, (pSrc != null), E_INVALID_ARG, "[%s] Invalid argument is used. pSrc can not be null.", GetErrorMessage(E_INVALID_ARG));
73         SysTryReturnResult(NID_TEXT, (srcLength >= 0), E_INVALID_ARG,
74                                 "[%s] Invalid argument is used. srcLength(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
75         SysTryReturnResult(NID_TEXT, (index >= 0), E_INVALID_ARG,
76                                 "[%s] Invalid argument is used. index(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), index);
77
78         result r = E_SUCCESS;
79         int currPosition = 0;
80         int retLength = 0;
81         bool isMemAllocReq = false;
82
83         std::unique_ptr<byte[]> pDst(__pEncoder->EncodeExN(pSrc, srcLength, retLength, flush));
84         r = GetLastResult();
85         SysTryReturnResult(NID_TEXT, (pDst != null), r, "[%s] Decoding failed", GetErrorMessage(r));
86
87         ByteBuffer* pOutBuffer = pByteBuffer;
88         if (retLength > 0)
89         {
90                 if (pOutBuffer == null)
91                 {
92                         isMemAllocReq = true;
93                         pOutBuffer = new (std::nothrow) ByteBuffer;
94                         SysTryCatch(NID_TEXT, (pOutBuffer != null), ,
95                                            E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Byte Buffer allocation failed");
96
97                         r = pOutBuffer->Construct(retLength);
98                         SysTryCatch(NID_TEXT, !IsFailed(r), , r, "[%s] Unable to Construct Byte buffer", GetErrorMessage(r));
99
100                         pByteBuffer = pOutBuffer;
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
111                 r = pOutBuffer->SetArray(pDst.get(), 0, retLength);
112                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
113
114                 r = pOutBuffer->SetPosition(currPosition);
115                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
116
117                 return r;
118         }
119
120 CATCH:
121         if (isMemAllocReq)
122         {
123                 delete pByteBuffer;
124                 pByteBuffer = null;
125         }
126         return r;
127 }
128
129 result
130 _EncoderImpl::GetByteCount(const WcharBuffer& chars, int charIndex, int charCount, int& byteCount, bool flush) const
131 {
132         SysAssertf(__pEncoder != null, "Not yet constructed! Construct() should be called before use.");
133
134         byteCount = 0;
135         int inBufSize = chars.GetLimit();
136         result r = CheckBufferInput(inBufSize, charIndex, charCount);
137         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
138
139         return __pEncoder->GetByteCount((chars.GetPointer() + charIndex), charCount, byteCount);
140 }
141
142 ByteBuffer*
143 _EncoderImpl::GetBytesN(const WcharBuffer& chars, bool flush) const
144 {
145         SysAssertf(__pEncoder != null, "Not yet constructed! Construct() should be called before use.");
146
147         ByteBuffer* pBuffer = null;
148         int srcLength = 0;
149         result r = GetBufferSize(chars, srcLength);
150         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
151
152         r = Encode(chars.GetPointer(), srcLength, pBuffer, 0, flush);
153
154         SetLastResult(r);
155         return pBuffer;
156 }
157
158 ByteBuffer*
159 _EncoderImpl::GetBytesN(const WcharBuffer& chars, int charIndex, int charCount, bool flush) const
160 {
161         SysAssertf(__pEncoder != null, "Not yet constructed! Construct() should be called before use.");
162
163         ByteBuffer* pBuffer = null;
164         int srcLength = chars.GetLimit();
165         result r = CheckBufferInput(srcLength, charIndex, charCount);
166         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
167
168         r = Encode(chars.GetPointer() + charIndex, charCount, pBuffer, 0, flush);
169
170         SetLastResult(r);
171         return pBuffer;
172 }
173
174 result
175 _EncoderImpl::GetBufferSize(const WcharBuffer& chars, int& charBufSize) const
176 {
177         // It is assumed that user has set limit properly
178         charBufSize = chars.GetLimit();
179
180         // Adjusting byteBufSize if bytes has null char at the end
181         wchar_t lastChar = -1;
182         result r = chars.Get(charBufSize - 1, lastChar);
183         SysTryReturnResult(NID_TEXT, (!IsFailed(r)), E_INVALID_ARG, "[%s] Last byte check failed", GetErrorMessage(r));
184
185         if ((lastChar == '\0')and(charBufSize > 1))
186         {
187                 charBufSize -= 1;
188         }
189         SysTryReturnResult(NID_TEXT, (charBufSize > 0), E_INVALID_ARG,
190                         "[%s] Invalid argument is used. charBufSize [%d] is invalid.", GetErrorMessage(E_INVALID_ARG), charBufSize);
191
192         return E_SUCCESS;
193 }
194
195 result
196 _EncoderImpl::CheckBufferInput(int inBufSize, int inIndex, int inCount) const
197 {
198         SysTryReturnResult(NID_TEXT, (inIndex >= 0), E_INVALID_ARG,
199                                 "[%s] Invalid argument is used. inIndex(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inIndex);
200         SysTryReturnResult(NID_TEXT, (inCount >= 0), E_INVALID_ARG,
201                                 "[%s] Invalid argument is used. inCount(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inCount);
202         SysTryReturnResult(NID_TEXT, (inBufSize > 0), E_INVALID_ARG,
203                                 "[%s] Invalid argument is used. inBufSize(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inBufSize);
204
205         SysTryReturnResult(NID_TEXT, (inBufSize > inIndex), E_OUT_OF_RANGE,
206                                 "[%s] inIndex(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inIndex);
207         SysTryReturnResult(NID_TEXT, (inBufSize >= inCount), E_OUT_OF_RANGE,
208                                 "[%s] inCount(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inCount);
209         SysTryReturnResult(NID_TEXT, (inBufSize >= (inIndex + inCount)), E_UNDERFLOW,
210                         "[%s] sum of the length of the inIndex(%d) and inCount(%d) is greater than inBufSize(%d).",
211                         GetErrorMessage(E_UNDERFLOW), inIndex, inCount, inBufSize);
212
213         return E_SUCCESS;
214 }
215
216 } } // Tizen::Text