Fix GNU C++ version check
[LibreOffice.git] / sal / textenc / convertsinglebytetobmpunicode.cxx
blob1fa9be11dab5ca56201f2eaa885b97202b239857
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
22 #include <cassert>
23 #include <cstddef>
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 * >(
40 data)->byteToUnicode;
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 char b = *srcBuf++;
47 sal_Unicode c = map[static_cast< sal_uInt8 >(b)];
48 if (c == 0xFFFF) {
49 goto bad_input;
51 if (destBufEnd - destBufPtr < 1) {
52 goto no_output;
54 *destBufPtr++ = c;
55 continue;
56 bad_input:
57 switch (sal::detail::textenc::handleBadInputTextToUnicodeConversion(
58 true/*undefined*/, false, b, flags, &destBufPtr, destBufEnd,
59 &infoFlags))
61 case sal::detail::textenc::BAD_INPUT_STOP:
62 if ((flags & RTL_TEXTTOUNICODE_FLAGS_FLUSH) == 0) {
63 ++converted;
65 break;
67 case sal::detail::textenc::BAD_INPUT_CONTINUE:
68 continue;
70 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
71 goto no_output;
73 break;
74 no_output:
75 --srcBuf;
76 infoFlags |= RTL_TEXTTOUNICODE_INFO_DESTBUFFERTOOSMALL;
77 break;
79 if (info != nullptr) {
80 *info = infoFlags;
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 * >(
99 data)->unicodeToByte;
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)->
107 m_nHighSurrogate;
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);
115 continue;
117 else if (rtl::isLowSurrogate(c))
119 undefined = false;
120 goto bad_input;
122 } else if (rtl::isLowSurrogate(c)) {
123 c = rtl::combineSurrogates(highSurrogate, c);
124 } else {
125 undefined = false;
126 goto bad_input;
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) {
133 break;
135 if (c <= sal::static_int_cast< sal_uInt32 >(
136 ranges[i].unicode + ranges[i].range))
138 if (destBufEnd - destBufPtr < 1) {
139 goto no_output;
141 *destBufPtr++ = static_cast< char >(
142 ranges[i].byte + (c - ranges[i].unicode));
143 goto done;
146 goto bad_input;
147 done:
148 highSurrogate = 0;
149 continue;
150 bad_input:
151 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
152 undefined, c, flags, &destBufPtr, destBufEnd, &infoFlags, nullptr,
153 0, nullptr))
155 case sal::detail::textenc::BAD_INPUT_STOP:
156 highSurrogate = 0;
157 break;
159 case sal::detail::textenc::BAD_INPUT_CONTINUE:
160 highSurrogate = 0;
161 continue;
163 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
164 goto no_output;
166 break;
167 no_output:
168 --srcBuf;
169 infoFlags |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
170 break;
172 if (highSurrogate != 0
173 && ((infoFlags
174 & (RTL_UNICODETOTEXT_INFO_ERROR
175 | RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL))
176 == 0))
178 if ((flags & RTL_UNICODETOTEXT_FLAGS_FLUSH) != 0) {
179 infoFlags |= RTL_UNICODETOTEXT_INFO_SRCBUFFERTOSMALL;
180 } else {
181 switch (sal::detail::textenc::handleBadInputUnicodeToTextConversion(
182 false, 0, flags, &destBufPtr, destBufEnd, &infoFlags, nullptr,
183 0, nullptr))
185 case sal::detail::textenc::BAD_INPUT_STOP:
186 case sal::detail::textenc::BAD_INPUT_CONTINUE:
187 highSurrogate = 0;
188 break;
190 case sal::detail::textenc::BAD_INPUT_NO_OUTPUT:
191 infoFlags |= RTL_UNICODETOTEXT_INFO_DESTBUFFERTOSMALL;
192 break;
196 if (context != nullptr) {
197 static_cast< ImplUnicodeToTextContext * >(context)->m_nHighSurrogate
198 = highSurrogate;
200 if (info != nullptr) {
201 *info = infoFlags;
203 if (srcCvtChars != nullptr) {
204 *srcCvtChars = converted;
206 return destBufPtr - destBuf;
209 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */