1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
24 #include <rtl/textcvt.h>
25 #include <sal/types.h>
27 #include "context.hxx"
28 #include "converter.hxx"
29 #include "convertsinglebytetobmpunicode.hxx"
30 #include "unichars.hxx"
32 sal_Size
rtl_textenc_convertSingleByteToBmpUnicode(
33 void const * data
, SAL_UNUSED_PARAMETER
void *, sal_Char
const * srcBuf
,
34 sal_Size srcBytes
, sal_Unicode
* destBuf
, sal_Size destChars
,
35 sal_uInt32 flags
, sal_uInt32
* info
, sal_Size
* srcCvtBytes
)
37 sal_Unicode
const * map
= static_cast<
38 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
40 sal_uInt32 infoFlags
= 0;
41 sal_Size converted
= 0;
42 sal_Unicode
* destBufPtr
= destBuf
;
43 sal_Unicode
* destBufEnd
= destBuf
+ destChars
;
44 for (; converted
< srcBytes
; ++converted
) {
45 sal_Char b
= *srcBuf
++;
46 sal_Unicode c
= map
[static_cast< sal_uInt8
>(b
)];
50 if (destBufEnd
- destBufPtr
< 1) {
56 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
57 true/*undefined*/, false, b
, flags
, &destBufPtr
, destBufEnd
,
60 case sal::detail::textenc::BAD_INPUT_STOP
:
63 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
66 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
72 infoFlags
|= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
75 if (info
!= nullptr) {
78 if (srcCvtBytes
!= nullptr) {
79 *srcCvtBytes
= converted
;
81 return destBufPtr
- destBuf
;
84 sal_Size
rtl_textenc_convertBmpUnicodeToSingleByte(
85 void const * data
, void * context
,
86 sal_Unicode
const * srcBuf
, sal_Size srcChars
, sal_Char
* destBuf
,
87 sal_Size destBytes
, sal_uInt32 flags
, sal_uInt32
* info
,
88 sal_Size
* srcCvtChars
)
90 std::size_t entries
= static_cast<
91 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
92 data
)->unicodeToByteEntries
;
93 rtl::textenc::BmpUnicodeToSingleByteRange
const * ranges
= static_cast<
94 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
96 sal_Unicode highSurrogate
= 0;
97 sal_uInt32 infoFlags
= 0;
98 sal_Size converted
= 0;
99 sal_Char
* destBufPtr
= destBuf
;
100 sal_Char
* destBufEnd
= destBuf
+ destBytes
;
101 if (context
!= nullptr) {
102 highSurrogate
= static_cast< ImplUnicodeToTextContext
* >(context
)->
105 for (; converted
< srcChars
; ++converted
) {
106 bool undefined
= true;
107 sal_uInt32 c
= *srcBuf
++;
108 if (highSurrogate
== 0) {
109 if (ImplIsHighSurrogate(c
)) {
110 highSurrogate
= static_cast< sal_Unicode
>(c
);
113 } else if (ImplIsLowSurrogate(c
)) {
114 c
= ImplCombineSurrogates(highSurrogate
, c
);
119 if (ImplIsLowSurrogate(c
) || ImplIsNoncharacter(c
)) {
123 // Linearly searching through the ranges if probably fastest, assuming
124 // that most converted characters belong to the ASCII subset:
125 for (std::size_t i
= 0; i
< entries
; ++i
) {
126 if (c
< ranges
[i
].unicode
) {
129 if (c
<= sal::static_int_cast
< sal_uInt32
>(
130 ranges
[i
].unicode
+ ranges
[i
].range
))
132 if (destBufEnd
- destBufPtr
< 1) {
135 *destBufPtr
++ = static_cast< sal_Char
>(
136 ranges
[i
].byte
+ (c
- ranges
[i
].unicode
));
145 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
146 undefined
, c
, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, nullptr,
149 case sal::detail::textenc::BAD_INPUT_STOP
:
153 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
157 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
163 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
166 if (highSurrogate
!= 0
168 & (RTL_UNICODETOTEXT_INFO_ERROR
169 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
))
172 if ((flags
& RTL_UNICODETOTEXT_FLAGS_FLUSH
) != 0) {
173 infoFlags
|= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL
;
175 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
176 false, 0, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, nullptr,
179 case sal::detail::textenc::BAD_INPUT_STOP
:
180 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
184 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
185 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
190 if (context
!= nullptr) {
191 static_cast< ImplUnicodeToTextContext
* >(context
)->m_nHighSurrogate
194 if (info
!= nullptr) {
197 if (srcCvtChars
!= nullptr) {
198 *srcCvtChars
= converted
;
200 return destBufPtr
- destBuf
;
203 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */