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 "osl/diagnose.h"
25 #include "rtl/textcvt.h"
26 #include "sal/types.h"
28 #include "context.hxx"
29 #include "converter.hxx"
30 #include "convertsinglebytetobmpunicode.hxx"
31 #include "unichars.hxx"
33 sal_Size
rtl_textenc_convertSingleByteToBmpUnicode(
34 void const * data
, SAL_UNUSED_PARAMETER
void *, sal_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
) {
46 bool undefined
= true;
47 sal_Char b
= *srcBuf
++;
48 sal_Unicode c
= map
[static_cast< sal_uInt8
>(b
)];
52 if (destBufEnd
- destBufPtr
< 1) {
58 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
59 undefined
, false, b
, flags
, &destBufPtr
, destBufEnd
,
62 case sal::detail::textenc::BAD_INPUT_STOP
:
65 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
68 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
74 infoFlags
|= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOSMALL
;
80 if (srcCvtBytes
!= 0) {
81 *srcCvtBytes
= converted
;
83 return destBufPtr
- destBuf
;
86 sal_Size
rtl_textenc_convertBmpUnicodeToSingleByte(
87 void const * data
, void * context
,
88 sal_Unicode
const * srcBuf
, sal_Size srcChars
, sal_Char
* destBuf
,
89 sal_Size destBytes
, sal_uInt32 flags
, sal_uInt32
* info
,
90 sal_Size
* srcCvtChars
)
92 std::size_t entries
= static_cast<
93 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
94 data
)->unicodeToByteEntries
;
95 rtl::textenc::BmpUnicodeToSingleByteRange
const * ranges
= static_cast<
96 rtl::textenc::BmpUnicodeToSingleByteConverterData
const * >(
98 sal_Unicode highSurrogate
= 0;
99 sal_uInt32 infoFlags
= 0;
100 sal_Size converted
= 0;
101 sal_Char
* destBufPtr
= destBuf
;
102 sal_Char
* destBufEnd
= destBuf
+ destBytes
;
104 highSurrogate
= static_cast< ImplUnicodeToTextContext
* >(context
)->
107 for (; converted
< srcChars
; ++converted
) {
108 bool undefined
= true;
109 sal_uInt32 c
= *srcBuf
++;
110 if (highSurrogate
== 0) {
111 if (ImplIsHighSurrogate(c
)) {
112 highSurrogate
= static_cast< sal_Unicode
>(c
);
115 } else if (ImplIsLowSurrogate(c
)) {
116 c
= ImplCombineSurrogates(highSurrogate
, c
);
121 if (ImplIsLowSurrogate(c
) || ImplIsNoncharacter(c
)) {
125 // Linearly searching through the ranges if probably fastest, assuming
126 // that most converted characters belong to the ASCII subset:
127 for (std::size_t i
= 0; i
< entries
; ++i
) {
128 if (c
< ranges
[i
].unicode
) {
130 } else if (c
<= sal::static_int_cast
< sal_uInt32
>(
131 ranges
[i
].unicode
+ ranges
[i
].range
))
133 if (destBufEnd
- destBufPtr
< 1) {
136 *destBufPtr
++ = static_cast< sal_Char
>(
137 ranges
[i
].byte
+ (c
- ranges
[i
].unicode
));
146 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
147 undefined
, c
, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, 0,
150 case sal::detail::textenc::BAD_INPUT_STOP
:
154 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
158 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
164 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
167 if (highSurrogate
!= 0
169 & (RTL_UNICODETOTEXT_INFO_ERROR
170 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
))
173 if ((flags
& RTL_UNICODETOTEXT_FLAGS_FLUSH
) != 0) {
174 infoFlags
|= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL
;
176 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
177 false, 0, flags
, &destBufPtr
, destBufEnd
, &infoFlags
, 0,
180 case sal::detail::textenc::BAD_INPUT_STOP
:
181 case sal::detail::textenc::BAD_INPUT_CONTINUE
:
185 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT
:
186 infoFlags
|= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL
;
192 static_cast< ImplUnicodeToTextContext
* >(context
)->m_nHighSurrogate
198 if (srcCvtChars
!= 0) {
199 *srcCvtChars
= converted
;
201 return destBufPtr
- destBuf
;
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */