aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/patched/replxx/src/conversion.cxx
blob: bcdbe048ec878f130fd72a35268306a24caca9ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include <algorithm>
#include <string>
#include <cstring>
#include <cctype>
#include <locale.h>

#include "conversion.hxx"

#ifdef _WIN32
#define strdup _strdup
#endif

using namespace std;

namespace replxx {

namespace locale {

void to_lower( std::string& s_ ) {
	transform( s_.begin(), s_.end(), s_.begin(), static_cast<int(*)(int)>( &tolower ) );
}

bool is_8bit_encoding( void ) {
	bool is8BitEncoding( false );
	string origLC( setlocale( LC_CTYPE, nullptr ) );
	string lc( origLC );
	to_lower( lc );
	if ( lc == "c" ) {
		setlocale( LC_CTYPE, "" );
	}
	lc = setlocale( LC_CTYPE, nullptr );
	setlocale( LC_CTYPE, origLC.c_str() );
	to_lower( lc );
	if ( lc.find( "8859" ) != std::string::npos ) {
		is8BitEncoding = true;
	}
	return ( is8BitEncoding );
}

bool is8BitEncoding( is_8bit_encoding() );

}

ConversionResult copyString8to32(char32_t* dst, int dstSize, int& dstCount, const char* src) {
	ConversionResult res = ConversionResult::conversionOK;
	if ( ! locale::is8BitEncoding ) {
		const UTF8* sourceStart = reinterpret_cast<const UTF8*>(src);
		const UTF8* sourceEnd = sourceStart + strlen(src);
		UTF32* targetStart = reinterpret_cast<UTF32*>(dst);
		UTF32* targetEnd = targetStart + dstSize;

		res = ConvertUTF8toUTF32(
				&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion);

		if (res == conversionOK) {
			dstCount = static_cast<int>( targetStart - reinterpret_cast<UTF32*>( dst ) );

			if (dstCount < dstSize) {
				*targetStart = 0;
			}
		}
	} else {
		for ( dstCount = 0; ( dstCount < dstSize ) && src[dstCount]; ++ dstCount ) {
			dst[dstCount] = src[dstCount];
		}
	}
	return res;
}

ConversionResult copyString8to32(char32_t* dst, int dstSize, int& dstCount, const char8_t* src) {
	return copyString8to32(
		dst, dstSize, dstCount, reinterpret_cast<const char*>(src)
	);
}

int copyString32to8( char* dst, int dstSize, const char32_t* src, int srcSize ) {
	int resCount( 0 );
	if ( ! locale::is8BitEncoding ) {
		const UTF32* sourceStart = reinterpret_cast<const UTF32*>(src);
		const UTF32* sourceEnd = sourceStart + srcSize;
		UTF8* targetStart = reinterpret_cast<UTF8*>(dst);
		UTF8* targetEnd = targetStart + dstSize;

		ConversionResult res = ConvertUTF32toUTF8(
			&sourceStart, sourceEnd, &targetStart, targetEnd, lenientConversion
		);

		if ( res == conversionOK ) {
			resCount = static_cast<int>( targetStart - reinterpret_cast<UTF8*>( dst ) );
			if ( resCount < dstSize ) {
				*targetStart = 0;
			}
		}
	} else {
		int i( 0 );
		for ( i = 0; ( i < dstSize ) && ( i < srcSize ) && src[i]; ++ i ) {
			dst[i] = static_cast<char>( src[i] );
		}
		resCount = i;
		if ( i < dstSize ) {
			dst[i] = 0;
		}
	}
	return ( resCount );
}

}