Merge branch 'tizen_2.1' of ssh://tizendev.org:29418/framework/osp/appfw into tizen_2.1
[platform/framework/native/appfw.git] / src / text / FText_EncodingImpl.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_EncodingImpl.cpp
19  * @brief               This is the implementation file for _EncodingImpl class.
20  */
21
22 #include <FBaseResult.h>
23 #include "FText_EncodingCore.h"
24 #include <FBaseSysLog.h>
25 #include "FText_EncodingImpl.h"
26
27 using namespace Tizen::Base;
28 using namespace Tizen::Base::Collection;
29 using namespace Tizen::Base::Utility;
30
31 #define AVAILABLE_ENCODING_COUNT 45
32 static String availableEncodings[] =
33 {
34 L"ASCII",
35 L"GSM",
36 L"KSC5601",
37 L"Big5",
38 L"GB2312",
39 L"UTF-8",
40 L"UTF-16",
41 L"UTF-16BE",
42 L"UTF-16LE",
43 L"UTF-32",
44 L"UTF-32BE",
45 L"UTF-32LE",
46 L"UCS-2",
47 L"UCS-2BE",
48 L"UCS-2LE",
49 L"UCS-4",
50 L"UCS-4BE",
51 L"UCS-4LE",
52 L"ISO-8859-1",
53 L"ISO-8859-2",
54 L"ISO-8859-3",
55 L"ISO-8859-4",
56 L"ISO-8859-5",
57 L"ISO-8859-6",
58 L"ISO-8859-7",
59 L"ISO-8859-8",
60 L"ISO-8859-9",
61 L"ISO-8859-10",
62 L"ISO-8859-11",
63 L"ISO-8859-13",
64 L"ISO-8859-14",
65 L"ISO-8859-15",
66 L"ISO-8859-16",
67 L"Windows-874",
68 L"Windows-1250",
69 L"Windows-1251",
70 L"Windows-1252",
71 L"Windows-1253",
72 L"Windows-1254",
73 L"Windows-1255",
74 L"Windows-1256",
75 L"Windows-1257",
76 L"Windows-1258",
77 L"Shift-JIS",
78 L"ISO-2022-JP",
79 };
80
81 namespace Tizen { namespace Text
82 {
83
84 _EncodingImpl::_EncodingImpl(void)
85         : Encoding()
86         , __encodingType()
87         , __pEncodingCore(null)
88 {
89 }
90
91 _EncodingImpl::~_EncodingImpl(void)
92 {
93
94 }
95
96 result
97 _EncodingImpl::Construct(const String& encodingType)
98 {
99         // Object is not allowed to construct twice
100         SysAssertf(__pEncodingCore == null,
101                 "Already constructed! Calling Construct() twice or more on a same instance is not allowed for this class");
102
103         SysTryReturnResult(NID_TEXT, IsEncodingSupported(encodingType),
104                           E_UNSUPPORTED_TYPE, "[%s] encodingType[%ls] is not supported", GetErrorMessage(E_UNSUPPORTED_TYPE), encodingType.GetPointer());
105
106         __pEncodingCore.reset(_EncodingCore::GetEncodingCoreN(encodingType, L"WCHAR_T"));
107
108         result r = GetLastResult();
109         SysTryReturnResult(NID_TEXT, (__pEncodingCore != null), r, "[%s] Failed to open encoder/decoder.", GetErrorMessage(r));
110
111         __encodingType = encodingType;
112         _pEncodingImpl = this;
113
114         return E_SUCCESS;
115 }
116
117 result
118 _EncodingImpl::Encode(const wchar_t* pSrc, int srcLength, ByteBuffer*& pByteBuffer, int index) const
119 {
120         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
121
122         SysTryReturnResult(NID_TEXT, (pSrc != null), E_INVALID_ARG, "[%s] Invalid argument is used. pSrc can not be null.", GetErrorMessage(E_INVALID_ARG));
123         SysTryReturnResult(NID_TEXT, (srcLength >= 0), E_INVALID_ARG,
124                                 "[%s] Invalid argument is used. srcLength(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
125         SysTryReturnResult(NID_TEXT, (index >= 0), E_INVALID_ARG,
126                                 "[%s] Invalid argument is used. index(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), index);
127
128         result r = E_SUCCESS;
129         int currPosition = 0;
130         int retLength = 0;
131         bool isMemAllocReq = false;
132
133         std::unique_ptr<byte[]> pDst(__pEncodingCore->EncodeN(pSrc, srcLength, retLength));
134         r = GetLastResult();
135         SysTryReturnResult(NID_TEXT, (pDst != null), r, "[%s] Encoding failed", GetErrorMessage(r));
136
137         ByteBuffer* pOutBuffer = pByteBuffer;
138         if (retLength > 0)
139         {
140                 if (pOutBuffer == null)
141                 {
142                         isMemAllocReq = true;
143                         pOutBuffer = new (std::nothrow) ByteBuffer;
144                         SysTryCatch(NID_TEXT, (pOutBuffer != null), , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
145
146                         r = pOutBuffer->Construct(retLength + 1);
147                         SysTryCatch(NID_TEXT, !IsFailed(r), , r, "[%s] Unable to Construct Byte buffer", GetErrorMessage(r));
148
149                         pByteBuffer = pOutBuffer;
150                 }
151                 else
152                 {
153                         currPosition = pOutBuffer->GetPosition();
154
155                         r = pOutBuffer->SetPosition(index);
156                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
157                 }
158                 r = pOutBuffer->SetArray(pDst.get(), 0, retLength);
159                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
160
161                 r = pOutBuffer->SetPosition(currPosition);
162                 SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
163
164                 return r;
165         }
166
167 CATCH:
168         if (isMemAllocReq)
169         {
170                 delete pByteBuffer;
171                 pByteBuffer = null;
172         }
173         return r;
174 }
175
176 result
177 _EncodingImpl::Decode(const byte* pSrc, int srcLength, WcharBuffer*& pWcharBuffer, int index) const
178 {
179         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
180
181         SysTryReturnResult(NID_TEXT, (pSrc != null), E_INVALID_ARG, "[%s] Invalid argument is used. pSrc can not be null.", GetErrorMessage(E_INVALID_ARG));
182         SysTryReturnResult(NID_TEXT, (srcLength >= 0), E_INVALID_ARG,
183                                 "[%s] Invalid argument is used. srcLength(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
184         SysTryReturnResult(NID_TEXT, (index >= 0), E_INVALID_ARG,
185                                 "[%s] Invalid argument is used. index(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), index);
186
187         result r = E_SUCCESS;
188         int currPosition = 0;
189         int retLength = 0;
190         bool isMemAllocReq = false;
191
192         std::unique_ptr<wchar_t[]> pDst(__pEncodingCore->DecodeN(pSrc, srcLength, retLength));
193         r = GetLastResult();
194         SysTryReturnResult(NID_TEXT, (pDst != null), r, "[%s] Decoding failed", GetErrorMessage(r));
195
196         WcharBuffer* pOutBuffer = pWcharBuffer;
197         if (retLength > 0)
198         {
199                 if (pOutBuffer == null)
200                 {
201                         isMemAllocReq = true;
202                         pOutBuffer = new (std::nothrow) WcharBuffer;
203                         SysTryCatch(NID_TEXT, (pOutBuffer != null), , E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
204
205                         r = pOutBuffer->Construct(retLength + 1);
206                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to Construct Byte buffer", GetErrorMessage(r));
207
208                         r = pOutBuffer->SetArray(pDst.get(), 0, retLength);
209                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
210
211                         r = pOutBuffer->Set(L'\0');
212                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set null Byte", GetErrorMessage(r));
213
214                         pOutBuffer->Rewind();
215                         pWcharBuffer = pOutBuffer;
216                 }
217                 else
218                 {
219                         currPosition = pOutBuffer->GetPosition();
220
221                         r = pOutBuffer->SetPosition(index);
222                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
223
224                         r = pOutBuffer->SetArray(pDst.get(), 0, retLength);
225                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
226
227                         r = pOutBuffer->SetPosition(currPosition);
228                         SysTryCatch(NID_TEXT, (!IsFailed(r)), , r, "[%s] Unable to set Byte buffer position", GetErrorMessage(r));
229                 }
230                 return r;
231         }
232
233 CATCH:
234         if (isMemAllocReq)
235         {
236                 delete pWcharBuffer;
237                 pWcharBuffer = null;
238         }
239         return r;
240 }
241
242 result
243 _EncodingImpl::Decode(const byte* pSrc, int srcLength, String& outStr, int index) const
244 {
245         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
246
247         SysTryReturnResult(NID_TEXT, (pSrc != null), E_INVALID_ARG, "[%s] Invalid argument is used. pSrc can not be null.", GetErrorMessage(E_INVALID_ARG));
248         SysTryReturnResult(NID_TEXT, (srcLength >= 0), E_INVALID_ARG,
249                                 "[%s] Invalid argument is used. srcLength(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), srcLength);
250         SysTryReturnResult(NID_TEXT, (index >= 0), E_INVALID_ARG,
251                                 "[%s] Invalid argument is used. index(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), index);
252
253         result r = E_SUCCESS;
254         int retLength = 0;
255
256         std::unique_ptr<wchar_t[]> pDst(__pEncodingCore->DecodeN(pSrc, srcLength, retLength));
257         r = GetLastResult();
258         SysTryReturnResult(NID_TEXT, (pDst != null), r, "[%s] Decoding failed", GetErrorMessage(r));
259
260         outStr = pDst.get();
261
262         return E_SUCCESS;
263 }
264
265 result
266 _EncodingImpl::GetByteCount(const String& str, int& byteCount) const
267 {
268         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
269
270         byteCount = -1;
271         int srcLength = str.GetLength();
272         SysTryReturnResult(NID_TEXT, (srcLength > 0), E_INVALID_ARG,
273                         "[%s] Invalid argument is used. Input string is empty.", GetErrorMessage(E_INVALID_ARG));
274
275         return __pEncodingCore->GetByteCount(str.GetPointer(), srcLength, byteCount);
276 }
277
278 result
279 _EncodingImpl::GetByteCount(const WcharBuffer& chars, int& byteCount) const
280 {
281         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
282
283         byteCount = -1;
284         int srcLength = 0;
285         result r = GetBufferSize(chars, srcLength);
286         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
287
288         return __pEncodingCore->GetByteCount(chars.GetPointer(), srcLength, byteCount);
289 }
290
291 result
292 _EncodingImpl::GetByteCount(const WcharBuffer& chars, int charIndex, int charCount, int& byteCount) const
293 {
294         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
295
296         byteCount = -1;
297         int inBufSize = chars.GetLimit();
298         result r = CheckBufferInput(inBufSize, charIndex, charCount);
299         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
300
301         return __pEncodingCore->GetByteCount((chars.GetPointer() + charIndex), charCount, byteCount);
302 }
303
304 result
305 _EncodingImpl::GetCharCount(const ByteBuffer& bytes, int& charCount) const
306 {
307         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
308
309         charCount = -1;
310         int srcLength = 0;
311         result r = GetBufferSize(bytes, srcLength);
312         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
313
314         return __pEncodingCore->GetCharCount(bytes.GetPointer(), srcLength, charCount);
315 }
316
317 result
318 _EncodingImpl::GetCharCount(const ByteBuffer& bytes, int byteIndex, int byteCount, int& charCount) const
319 {
320         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
321
322         charCount = -1;
323         int inBufSize = bytes.GetLimit();
324         result r = CheckBufferInput(inBufSize, byteIndex, byteCount);
325         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
326
327         return __pEncodingCore->GetCharCount((bytes.GetPointer() + byteIndex), byteCount, charCount);
328 }
329
330 ByteBuffer*
331 _EncodingImpl::GetBytesN(const WcharBuffer& chars) const
332 {
333         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
334
335         ByteBuffer* pBuffer = null;
336         int srcLength = 0;
337         result r = GetBufferSize(chars, srcLength);
338         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
339
340         r = Encode(chars.GetPointer(), srcLength, pBuffer, 0);
341
342         SetLastResult(r);
343         return pBuffer;
344 }
345
346 ByteBuffer*
347 _EncodingImpl::GetBytesN(const String& str) const
348 {
349         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
350
351         ByteBuffer* pBuffer = null;
352         int srcLength = str.GetLength();
353         SysTryReturn(NID_TEXT, (srcLength > 0), null, E_INVALID_ARG,
354                         "[%s] Invalid argument is used. Input string is empty.", GetErrorMessage(E_INVALID_ARG));
355
356         result r = Encode(str.GetPointer(), srcLength, pBuffer, 0);
357
358         SetLastResult(r);
359         return pBuffer;
360 }
361
362 result
363 _EncodingImpl::GetBytes(const WcharBuffer& chars, int charIndex, int charCount, ByteBuffer& bytes, int byteIndex) const
364 {
365         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
366
367         ByteBuffer* pBuffer = &bytes;
368         int srcLen = chars.GetLimit();
369         int destLen = bytes.GetLimit();
370
371         result r = CheckBufferInput(srcLen, charIndex, charCount, destLen, byteIndex);
372         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
373
374         return Encode((chars.GetPointer() + charIndex), charCount, pBuffer, byteIndex);
375 }
376
377 result
378 _EncodingImpl::GetBytes(const String& str, int charIndex, int charCount, ByteBuffer& bytes, int byteIndex) const
379 {
380         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
381
382         ByteBuffer* pBuffer = &bytes;
383         int srcLen = str.GetLength();
384         int destLen = bytes.GetLimit();
385
386         result r = CheckBufferInput(srcLen, charIndex, charCount, destLen, byteIndex);
387         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
388
389         return Encode((str.GetPointer() + charIndex), charCount, pBuffer, byteIndex);
390 }
391
392 WcharBuffer*
393 _EncodingImpl::GetCharsN(const ByteBuffer& bytes) const
394 {
395         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
396
397         WcharBuffer* pBuffer = null;
398         int srcLength = 0;
399         result r = GetBufferSize(bytes, srcLength);
400         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Input validation failed", GetErrorMessage(r));
401
402         r = Decode(bytes.GetPointer(), srcLength, pBuffer, 0);
403
404         SetLastResult(r);
405         return pBuffer;
406 }
407
408 result
409 _EncodingImpl::GetChars(const ByteBuffer& bytes, int byteIndex, int byteCount, WcharBuffer& chars, int charIndex) const
410 {
411         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
412
413         WcharBuffer* pBuffer = &chars;
414         int srcLen = bytes.GetLimit();
415         int destLen = chars.GetLimit();
416
417         result r = CheckBufferInput(srcLen, byteIndex, byteCount, destLen, charIndex);
418         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
419
420         return Decode((bytes.GetPointer() + byteIndex), byteCount, pBuffer, charIndex);
421 }
422
423 result
424 _EncodingImpl::GetString(const ByteBuffer& bytes, Tizen::Base::String& str) const
425 {
426         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
427
428         int srcLength = 0;
429         result r = GetBufferSize(bytes, srcLength);
430         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
431
432         return Decode(bytes.GetPointer(), srcLength, str, 0);
433 }
434
435 result
436 _EncodingImpl::GetString(const ByteBuffer& bytes, int index, int count, String& str) const
437 {
438         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
439
440         int srcLen = bytes.GetLimit();
441         result r = CheckBufferInput(srcLen, index, count);
442         SysTryReturn(NID_TEXT, (!IsFailed(r)), r, r, "[%s] Input validation failed", GetErrorMessage(r));
443
444         if (count == 0)
445         {
446                 str = "";
447                 return E_SUCCESS;
448         }
449
450         return Decode((bytes.GetPointer() + index), count, str, 0);
451 }
452
453 ByteBuffer*
454 _EncodingImpl::ConvertImplN(const Encoding& src, const Encoding& dst, const ByteBuffer& srcBytes)
455 {
456         const _EncodingImpl* pSrcEncodingImpl = src._pEncodingImpl;
457         SysTryReturn(NID_TEXT, (pSrcEncodingImpl != null), null, E_INVALID_ARG, "[E_INVALID_ARG] Unable to get encoder object");
458
459         int inBufSize = -1;
460         result r = pSrcEncodingImpl->GetBufferSize(srcBytes, inBufSize);
461         SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to get byte buffer size", GetErrorMessage(r));
462
463         return ConvertN(src, dst, srcBytes, 0, inBufSize);
464 }
465
466 ByteBuffer*
467 _EncodingImpl::ConvertImplN(const Encoding& src, const Encoding& dst, const ByteBuffer& srcBytes, int index, int count)
468 {
469         const _EncodingImpl* pSrcEncodingImpl = src._pEncodingImpl;
470         SysTryReturn(NID_TEXT, (pSrcEncodingImpl != null), null, E_INVALID_ARG, "[%s] Unable to get encoder object", GetErrorMessage(E_INVALID_ARG));
471
472         _EncodingCore* pSrcConverter = pSrcEncodingImpl->__pEncodingCore.get();
473         SysTryReturn(NID_TEXT, (pSrcConverter != null), null, E_INVALID_ARG, "[%s] Unable to get encoder decoder object", GetErrorMessage(E_INVALID_ARG));
474
475         const _EncodingImpl* pDstEncodingImpl = dst._pEncodingImpl;
476         SysTryReturn(NID_TEXT, (pDstEncodingImpl != null), null, E_INVALID_ARG, "[%s] Unable to get encoder object", GetErrorMessage(E_INVALID_ARG));
477
478         _EncodingCore* pDstConverter = pDstEncodingImpl->__pEncodingCore.get();
479         SysTryReturn(NID_TEXT, (pDstConverter != null), null, E_INVALID_ARG, "[%s] Unable to get encoder decoder object", GetErrorMessage(E_INVALID_ARG));
480
481         int inBufSize = srcBytes.GetLimit();
482
483         result r = pSrcEncodingImpl->CheckBufferInput(inBufSize, index, count);
484         SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to get byte buffer size", GetErrorMessage(r));
485
486         int retLength = -1;
487
488         std::unique_ptr<byte[]> pByte(pSrcConverter->ConvertN(pDstConverter, srcBytes.GetPointer() + index, count, retLength));
489         r = GetLastResult();
490         SysTryReturn(NID_TEXT, (pByte != null), null, r, "[%s] Unable to get encoder object", GetErrorMessage(r));
491
492         std::unique_ptr<ByteBuffer> pOutBuffer(new (std::nothrow) ByteBuffer);
493         SysTryReturn(NID_TEXT, pOutBuffer != null, null,
494                            E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
495
496         r = pOutBuffer->Construct(retLength + 1);
497         SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to Construct Byte buffer", GetErrorMessage(r));
498
499         r = pOutBuffer->SetArray(pByte.get(), 0, retLength);
500         SysTryReturn(NID_TEXT, (!IsFailed(r)), null, r, "[%s] Unable to fill Byte buffer", GetErrorMessage(r));
501
502         pOutBuffer->Rewind();
503
504         SetLastResult(E_SUCCESS);
505         return pOutBuffer.release();
506 }
507
508 int
509 _EncodingImpl::GetMaxByteCount(int charCount) const
510 {
511         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
512         return __pEncodingCore->GetMaxByteCount(charCount);
513 }
514
515 int
516 _EncodingImpl::GetMaxCharCount(int byteCount) const
517 {
518         SysAssertf(__pEncodingCore != null, "Not yet constructed! Construct() should be called before use.");
519         return __pEncodingCore->GetMaxCharCount(byteCount);
520 }
521
522 Encoder*
523 _EncodingImpl::GetEncoderN(void) const
524 {
525         return null;
526 }
527
528 Decoder*
529 _EncodingImpl::GetDecoderN(void) const
530 {
531         return null;
532 }
533
534 IList*
535 _EncodingImpl::GetAvailableEncodingsImplN(void)
536 {
537         ClearLastResult();
538         result r = E_SUCCESS;
539
540         std::unique_ptr<LinkedList, AllElementsDeleter> pList(new (std::nothrow) LinkedList());
541
542         SysTryReturn(NID_TEXT, pList != null, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
543
544         for (int i = 0; i < AVAILABLE_ENCODING_COUNT; i++)
545         {
546                 String* pEncodingStr = new (std::nothrow) String(availableEncodings[i]);
547                 SysTryReturn(NID_TEXT, pEncodingStr, null, E_OUT_OF_MEMORY, "[%s] Memory allocation failed", GetErrorMessage(E_OUT_OF_MEMORY));
548
549                 r = pList->Add(*pEncodingStr);
550                 if(IsFailed(r))
551                 {
552                         delete pEncodingStr;
553                         SysTryReturn(NID_TEXT, !IsFailed(r), null, r, "[%s] Unable to add encoding to list", GetErrorMessage(r));
554                 }
555         }
556
557         return pList.release();
558 }
559
560 result
561 _EncodingImpl::GetBufferSize(const WcharBuffer& chars, int& charBufSize) const
562 {
563         charBufSize = StringUtil::GetStringLengthInMb(chars);
564
565         // This check is to correct tmpSize if chars does not contain null char
566         if (charBufSize == -1)
567         {
568                 charBufSize = chars.GetLimit();
569         }
570
571         SysTryReturnResult(NID_TEXT, (charBufSize > 0), E_INVALID_ARG,
572                         "[%s] Invalid argument is used. charBufSize(%d) is less than 0.", GetErrorMessage(E_INVALID_ARG), charBufSize);
573         return E_SUCCESS;
574 }
575
576 result
577 _EncodingImpl::GetBufferSize(const ByteBuffer& bytes, int& byteBufSize) const
578 {
579         // It is assumed that user has set limit properly
580         byteBufSize = bytes.GetLimit();
581
582         int minByteCountForEncoding = 1;
583         if (__pEncodingCore)
584         {
585                 minByteCountForEncoding = 4 / __pEncodingCore->GetMaxCharCount(4);
586         }
587
588         byte lastByte = '\0';
589         bool nullAtTheEnd = false;
590         result r = bytes.GetByte(byteBufSize - 1, lastByte);
591         SysTryReturnResult(NID_TEXT, (!IsFailed(r)), E_INVALID_ARG, "[%s] Last byte check failed", GetErrorMessage(r));
592
593         if ((lastByte == '\0')and(byteBufSize > 1))
594         {
595                 nullAtTheEnd = true;
596                 if ((byteBufSize % minByteCountForEncoding) == 0)
597                 {
598                         for (int i = 0; i < minByteCountForEncoding; i++)
599                         {
600                                 byte lastByte = 0;
601                                 result r = bytes.GetByte(byteBufSize - i - 1, lastByte);
602                                 SysTryReturnResult(NID_TEXT, (!IsFailed(r)), E_INVALID_ARG, "[%s] Last byte check failed", GetErrorMessage(r));
603
604                                 if (lastByte != '\0')
605                                 {
606                                         nullAtTheEnd = false;
607                                 }
608                         }
609                 }
610
611                 if (nullAtTheEnd)
612                 {
613                         byteBufSize -= 1;
614                 }
615         }
616
617         SysTryReturnResult(NID_TEXT, (byteBufSize > 0), E_INVALID_ARG, "byteBufSize [%d] is invalid.", byteBufSize);
618         return E_SUCCESS;
619 }
620
621 result
622 _EncodingImpl::CheckBufferInput(int inBufSize, int inIndex, int inCount) const
623 {
624         SysTryReturnResult(NID_TEXT, (inIndex >= 0), E_INVALID_ARG,
625                                 "[%s] Invalid argument is used. inIndex(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inIndex);
626         SysTryReturnResult(NID_TEXT, (inCount >= 0), E_INVALID_ARG,
627                                 "[%s] Invalid argument is used. inCount(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inCount);
628         SysTryReturnResult(NID_TEXT, (inBufSize > 0), E_INVALID_ARG,
629                                 "[%s] Invalid argument is used. inBufSize(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inBufSize);
630
631         SysTryReturnResult(NID_TEXT, (inBufSize > inIndex), E_OUT_OF_RANGE,
632                                 "[%s] inIndex(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inIndex);
633         SysTryReturnResult(NID_TEXT, (inBufSize >= inCount), E_OUT_OF_RANGE,
634                                 "[%s] inCount(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inCount);
635         SysTryReturnResult(NID_TEXT, (inBufSize >= (inIndex + inCount)), E_UNDERFLOW,
636                         "[%s] sum of the length of the inIndex(%d) and inCount(%d) is greater than inBufSize(%d).",
637                         GetErrorMessage(E_UNDERFLOW), inIndex, inCount, inBufSize);
638
639         return E_SUCCESS;
640 }
641
642 result
643 _EncodingImpl::CheckBufferInput(int inBufSize, int inIndex, int inCount, int outBufSize, int outIndex) const
644 {
645         SysTryReturnResult(NID_TEXT, (inIndex >= 0), E_INVALID_ARG,
646                                 "[%s] Invalid argument is used. inIndex(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inIndex);
647         SysTryReturnResult(NID_TEXT, (inCount >= 0), E_INVALID_ARG,
648                                 "[%s] Invalid argument is used. inCount(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inCount);
649         SysTryReturnResult(NID_TEXT, (outIndex >= 0), E_INVALID_ARG,
650                                 "[%s] Invalid argument is used. outIndex(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), outIndex);
651         SysTryReturnResult(NID_TEXT, (inBufSize > 0), E_INVALID_ARG,
652                                 "[%s] Invalid argument is used. inBufSize(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), inBufSize);
653
654         SysTryReturnResult(NID_TEXT, (inBufSize > inIndex), E_OUT_OF_RANGE,
655                                 "[%s] inIndex(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inIndex);
656         SysTryReturnResult(NID_TEXT, (inBufSize >= inCount), E_OUT_OF_RANGE,
657                                 "[%s] inCount(%d) is outside the valid range.", GetErrorMessage(E_OUT_OF_RANGE), inCount);
658         SysTryReturnResult(NID_TEXT, (inBufSize >= (inIndex + inCount)), E_UNDERFLOW,
659                         "[%s] sum of the length of the inIndex(%d) and inCount(%d) is greater than inBufSize(%d).",
660                         GetErrorMessage(E_UNDERFLOW), inIndex, inCount, inBufSize);
661
662         SysTryReturnResult(NID_TEXT, (outBufSize > 0), E_INVALID_ARG,
663                                 "[%s] Invalid argument is used. outBufSize(%d) cannot be negative.", GetErrorMessage(E_INVALID_ARG), outBufSize);
664         SysTryReturnResult(NID_TEXT, (outBufSize > outIndex), E_OVERFLOW, "[%s] outIndex [%d] is outside the valid range.", GetErrorMessage(E_OVERFLOW), outIndex);
665
666         return E_SUCCESS;
667 }
668
669 String
670 _EncodingImpl::GetEncodingType(void) const
671 {
672         return __encodingType;
673 }
674
675 bool
676 _EncodingImpl::IsEncodingSupported(const Tizen::Base::String& encodingStr) const
677 {
678         SysTryReturn(NID_TEXT, !encodingStr.IsEmpty(), false, E_INVALID_ARG, "[%s] Invalid argument is used. Input string is empty", GetErrorMessage(E_INVALID_ARG));
679
680         bool retValue = false;
681         for (int i = 0; i < AVAILABLE_ENCODING_COUNT; i++)
682         {
683                 if (encodingStr.Equals(availableEncodings[i], false))
684                 {
685                         retValue = true;
686                         break;
687                 }
688         }
689         return retValue;
690 }
691
692 } } // Tizen::Text