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>
25 #include <rtl/character.hxx>
26 #include <rtl/textcvt.h>
27 #include <sal/types.h>
29 #include "context.hxx"
30 #include "converter.hxx"
31 #include "convertsinglebytetobmpunicode.hxx"
33 sal_Size
rtl_textenc_convertSingleByteToBmpUnicode(
34 void const * data
, SAL_UNUSED_PARAMETER
void *, char const * srcBuf
,
35 sal_Size srcBytes
, sal_Unicode
* destBuf
, sal_Size destChars
,
36 sal_uInt32 flags
, sal_uInt32
* info
, sal_Size
* srcCvtBytes
)
38 sal_Unicode
const * map
= static_cast<
39 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
41 sal_uInt32 infoFlags
= 0;
42 sal_Size converted
= 0;
43 sal_Unicode
* destBufPtr
= destBuf
;
44 sal_Unicode
* destBufEnd
= destBuf
+ destChars
;
45 for (; converted
< srcBytes
; ++converted
) {
47 sal_Unicode c
= map
[static_cast< sal_uInt8
>(b
)];
51 if (destBufEnd
- destBufPtr
< 1) {
57 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
58 true/*undefined*/, false, b
, flags
, &destBufPtr
, destBufEnd
,
61 case sal::detail::textenc::BAD_INPUT_STOP
:
62 if ((flags
& RTL_TEXTTOUNICODE_FLAGS_FLUSH
) == 0) {
67 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
70 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
76 infoFlags
|= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL
;
79 if (info
!= nullptr) {
82 if (srcCvtBytes
!= nullptr) {
83 *srcCvtBytes
= converted
;
85 return destBufPtr
- destBuf
;
88 sal_Size
rtl_textenc_convertBmpUnicodeToSingleByte(
89 void const * data
, void * context
,
90 sal_Unicode
const * srcBuf
, sal_Size srcChars
, char * destBuf
,
91 sal_Size destBytes
, sal_uInt32 flags
, sal_uInt32
* info
,
92 sal_Size
* srcCvtChars
)
94 std::size_t entries
= static_cast<
95 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
96 data
)->unicodeToByteEntries
;
97 rtl::textenc::BmpUnicodeToSingleByteRange
const * ranges
= static_cast<
98 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
100 sal_Unicode highSurrogate
= 0;
101 sal_uInt32 infoFlags
= 0;
102 sal_Size converted
= 0;
103 char * destBufPtr
= destBuf
;
104 char * destBufEnd
= destBuf
+ destBytes
;
105 if (context
!= nullptr) {
106 highSurrogate
= static_cast< ImplUnicodeToTextContext
* >(context
)->
109 for (; converted
< srcChars
; ++converted
) {
110 bool undefined
= true;
111 sal_uInt32 c
= *srcBuf
++;
112 if (highSurrogate
== 0) {
113 if (rtl::isHighSurrogate(c
)) {
114 highSurrogate
= static_cast< sal_Unicode
>(c
);
117 else if (rtl::isLowSurrogate(c
))
122 } else if (rtl::isLowSurrogate(c
)) {
123 c
= rtl::combineSurrogates(highSurrogate
, c
);
128 assert(rtl::isUnicodeScalarValue(c
));
129 // Linearly searching through the ranges if probably fastest, assuming
130 // that most converted characters belong to the ASCII subset:
131 for (std::size_t i
= 0; i
< entries
; ++i
) {
132 if (c
< ranges
[i
].unicode
) {
135 if (c
<= sal::static_int_cast
< sal_uInt32
>(
136 ranges
[i
].unicode
+ ranges
[i
].range
))
138 if (destBufEnd
- destBufPtr
< 1) {
141 *destBufPtr
++ = static_cast< char >(
142 ranges
[i
].byte
+ (c
- ranges
[i
].unicode
));
151 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
152 undefined
, c
, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, nullptr,
155 case sal::detail::textenc::BAD_INPUT_STOP
:
159 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
163 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
169 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
172 if (highSurrogate
!= 0
174 & (RTL_UNICODETOTEXT_INFO_ERROR
175 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
))
178 if ((flags
& RTL_UNICODETOTEXT_FLAGS_FLUSH
) != 0) {
179 infoFlags
|= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL
;
181 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
182 false, 0, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, nullptr,
185 case sal::detail::textenc::BAD_INPUT_STOP
:
186 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
190 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
191 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
196 if (context
!= nullptr) {
197 static_cast< ImplUnicodeToTextContext
* >(context
)->m_nHighSurrogate
200 if (info
!= nullptr) {
203 if (srcCvtChars
!= nullptr) {
204 *srcCvtChars
= converted
;
206 return destBufPtr
- destBuf
;
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */