1/*-------------------------------------------------------------------------
2 *
3 * Cyrillic and MULE_INTERNAL
4 *
5 * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
7 *
8 * IDENTIFICATION
9 * src/backend/utils/mb/conversion_procs/cyrillic_and_mic/cyrillic_and_mic.c
10 *
11 *-------------------------------------------------------------------------
12 */
13
14#include "postgres.h"
15#include "fmgr.h"
16#include "mb/pg_wchar.h"
17
18PG_MODULE_MAGIC;
19
20PG_FUNCTION_INFO_V1(koi8r_to_mic);
21PG_FUNCTION_INFO_V1(mic_to_koi8r);
22PG_FUNCTION_INFO_V1(iso_to_mic);
23PG_FUNCTION_INFO_V1(mic_to_iso);
24PG_FUNCTION_INFO_V1(win1251_to_mic);
25PG_FUNCTION_INFO_V1(mic_to_win1251);
26PG_FUNCTION_INFO_V1(win866_to_mic);
27PG_FUNCTION_INFO_V1(mic_to_win866);
28PG_FUNCTION_INFO_V1(koi8r_to_win1251);
29PG_FUNCTION_INFO_V1(win1251_to_koi8r);
30PG_FUNCTION_INFO_V1(koi8r_to_win866);
31PG_FUNCTION_INFO_V1(win866_to_koi8r);
32PG_FUNCTION_INFO_V1(win866_to_win1251);
33PG_FUNCTION_INFO_V1(win1251_to_win866);
34PG_FUNCTION_INFO_V1(iso_to_koi8r);
35PG_FUNCTION_INFO_V1(koi8r_to_iso);
36PG_FUNCTION_INFO_V1(iso_to_win1251);
37PG_FUNCTION_INFO_V1(win1251_to_iso);
38PG_FUNCTION_INFO_V1(iso_to_win866);
39PG_FUNCTION_INFO_V1(win866_to_iso);
40
41/* ----------
42 * conv_proc(
43 * INTEGER, -- source encoding id
44 * INTEGER, -- destination encoding id
45 * CSTRING, -- source string (null terminated C string)
46 * CSTRING, -- destination string (null terminated C string)
47 * INTEGER -- source string length
48 * ) returns VOID;
49 * ----------
50 */
51
52/*
53 * Cyrillic support
54 * currently supported Cyrillic encodings:
55 *
56 * KOI8-R (this is also the charset for the mule internal code for Cyrillic)
57 * ISO-8859-5
58 * Microsoft's CP1251 (windows-1251)
59 * Alternativny Variant (MS-DOS CP866)
60 */
61
62/* ISO-8859-5 to KOI8-R */
63static const unsigned char iso2koi[] = {
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
71 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
72 0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
73 0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
74 0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
75 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
76 0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
77 0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1,
78 0x00, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
80};
81
82/* KOI8-R to ISO-8859-5 */
83static const unsigned char koi2iso[] = {
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0xA1, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0xEE, 0xD0, 0xD1, 0xE6, 0xD4, 0xD5, 0xE4, 0xD3,
93 0xE5, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,
94 0xDF, 0xEF, 0xE0, 0xE1, 0xE2, 0xE3, 0xD6, 0xD2,
95 0xEC, 0xEB, 0xD7, 0xE8, 0xED, 0xE9, 0xE7, 0xEA,
96 0xCE, 0xB0, 0xB1, 0xC6, 0xB4, 0xB5, 0xC4, 0xB3,
97 0xC5, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE,
98 0xBF, 0xCF, 0xC0, 0xC1, 0xC2, 0xC3, 0xB6, 0xB2,
99 0xCC, 0xCB, 0xB7, 0xC8, 0xCD, 0xC9, 0xC7, 0xCA
100};
101
102/* WIN1251 to KOI8-R */
103static const unsigned char win12512koi[] = {
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00,
109 0xB3, 0x00, 0xB4, 0x00, 0x00, 0x00, 0x00, 0xB7,
110 0x00, 0x00, 0xB6, 0xA6, 0xAD, 0x00, 0x00, 0x00,
111 0xA3, 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00, 0xA7,
112 0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
113 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
114 0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
115 0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
116 0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
117 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
118 0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
119 0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1
120};
121
122/* KOI8-R to WIN1251 */
123static const unsigned char koi2win1251[] = {
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0xB8, 0xBA, 0x00, 0xB3, 0xBF,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0xB4, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0xA8, 0xAA, 0x00, 0xB2, 0xAF,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00,
132 0xFE, 0xE0, 0xE1, 0xF6, 0xE4, 0xE5, 0xF4, 0xE3,
133 0xF5, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE,
134 0xEF, 0xFF, 0xF0, 0xF1, 0xF2, 0xF3, 0xE6, 0xE2,
135 0xFC, 0xFB, 0xE7, 0xF8, 0xFD, 0xF9, 0xF7, 0xFA,
136 0xDE, 0xC0, 0xC1, 0xD6, 0xC4, 0xC5, 0xD4, 0xC3,
137 0xD5, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE,
138 0xCF, 0xDF, 0xD0, 0xD1, 0xD2, 0xD3, 0xC6, 0xC2,
139 0xDC, 0xDB, 0xC7, 0xD8, 0xDD, 0xD9, 0xD7, 0xDA
140};
141
142/* WIN866 to KOI8-R */
143static const unsigned char win8662koi[] = {
144 0xE1, 0xE2, 0xF7, 0xE7, 0xE4, 0xE5, 0xF6, 0xFA,
145 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0,
146 0xF2, 0xF3, 0xF4, 0xF5, 0xE6, 0xE8, 0xE3, 0xFE,
147 0xFB, 0xFD, 0xFF, 0xF9, 0xF8, 0xFC, 0xE0, 0xF1,
148 0xC1, 0xC2, 0xD7, 0xC7, 0xC4, 0xC5, 0xD6, 0xDA,
149 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0xD2, 0xD3, 0xD4, 0xD5, 0xC6, 0xC8, 0xC3, 0xDE,
157 0xDB, 0xDD, 0xDF, 0xD9, 0xD8, 0xDC, 0xC0, 0xD1,
158 0xB3, 0xA3, 0xB4, 0xA4, 0xB7, 0xA7, 0x00, 0x00,
159 0xB6, 0xA6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
160};
161
162/* KOI8-R to WIN866 */
163static const unsigned char koi2win866[] = {
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0xF1, 0xF3, 0x00, 0xF9, 0xF5,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0xAD, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0xF0, 0xF2, 0x00, 0xF8, 0xF4,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00,
172 0xEE, 0xA0, 0xA1, 0xE6, 0xA4, 0xA5, 0xE4, 0xA3,
173 0xE5, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE,
174 0xAF, 0xEF, 0xE0, 0xE1, 0xE2, 0xE3, 0xA6, 0xA2,
175 0xEC, 0xEB, 0xA7, 0xE8, 0xED, 0xE9, 0xE7, 0xEA,
176 0x9E, 0x80, 0x81, 0x96, 0x84, 0x85, 0x94, 0x83,
177 0x95, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
178 0x8F, 0x9F, 0x90, 0x91, 0x92, 0x93, 0x86, 0x82,
179 0x9C, 0x9B, 0x87, 0x98, 0x9D, 0x99, 0x97, 0x9A
180};
181
182/* WIN866 to WIN1251 */
183static const unsigned char win8662win1251[] = {
184 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
185 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
186 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
187 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
188 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
189 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
191 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
197 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
198 0xA8, 0xB8, 0xAA, 0xBA, 0xAF, 0xBF, 0x00, 0x00,
199 0xB2, 0xB3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
200};
201
202/* WIN1251 to WIN866 */
203static const unsigned char win12512win866[] = {
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0xBD, 0x00, 0x00,
209 0xF0, 0x00, 0xF2, 0x00, 0x00, 0x00, 0x00, 0xF4,
210 0x00, 0x00, 0xF8, 0xF9, 0xAD, 0x00, 0x00, 0x00,
211 0xF1, 0x00, 0xF3, 0x00, 0x00, 0x00, 0x00, 0xF5,
212 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
213 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
214 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
215 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
216 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
217 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
218 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
219 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF
220};
221
222/* ISO-8859-5 to WIN1251 */
223static const unsigned char iso2win1251[] = {
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
231 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
232 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
233 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
234 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
235 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
236 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
237 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
238 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
240};
241
242/* WIN1251 to ISO-8859-5 */
243static const unsigned char win12512iso[] = {
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
251 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
253 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
254 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
255 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
256 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
257 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
258 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
259 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF
260};
261
262/* ISO-8859-5 to WIN866 */
263static const unsigned char iso2win866[] = {
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
271 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
272 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
273 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
274 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
275 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
276 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
277 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
278 0x00, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
280};
281
282/* WIN866 to ISO-8859-5 */
283static const unsigned char win8662iso[] = {
284 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
285 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
286 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
287 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
288 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
289 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
297 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
298 0xA1, 0xF1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
300};
301
302
303Datum
304koi8r_to_mic(PG_FUNCTION_ARGS)
305{
306 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
307 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
308 int len = PG_GETARG_INT32(4);
309
310 CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_MULE_INTERNAL);
311
312 latin2mic(src, dest, len, LC_KOI8_R, PG_KOI8R);
313
314 PG_RETURN_VOID();
315}
316
317Datum
318mic_to_koi8r(PG_FUNCTION_ARGS)
319{
320 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
321 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
322 int len = PG_GETARG_INT32(4);
323
324 CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_KOI8R);
325
326 mic2latin(src, dest, len, LC_KOI8_R, PG_KOI8R);
327
328 PG_RETURN_VOID();
329}
330
331Datum
332iso_to_mic(PG_FUNCTION_ARGS)
333{
334 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
335 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
336 int len = PG_GETARG_INT32(4);
337
338 CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_MULE_INTERNAL);
339
340 latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, iso2koi);
341
342 PG_RETURN_VOID();
343}
344
345Datum
346mic_to_iso(PG_FUNCTION_ARGS)
347{
348 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
349 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
350 int len = PG_GETARG_INT32(4);
351
352 CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_ISO_8859_5);
353
354 mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_ISO_8859_5, koi2iso);
355
356 PG_RETURN_VOID();
357}
358
359Datum
360win1251_to_mic(PG_FUNCTION_ARGS)
361{
362 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
363 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
364 int len = PG_GETARG_INT32(4);
365
366 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_MULE_INTERNAL);
367
368 latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, win12512koi);
369
370 PG_RETURN_VOID();
371}
372
373Datum
374mic_to_win1251(PG_FUNCTION_ARGS)
375{
376 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
377 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
378 int len = PG_GETARG_INT32(4);
379
380 CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN1251);
381
382 mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN1251, koi2win1251);
383
384 PG_RETURN_VOID();
385}
386
387Datum
388win866_to_mic(PG_FUNCTION_ARGS)
389{
390 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
391 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
392 int len = PG_GETARG_INT32(4);
393
394 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_MULE_INTERNAL);
395
396 latin2mic_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, win8662koi);
397
398 PG_RETURN_VOID();
399}
400
401Datum
402mic_to_win866(PG_FUNCTION_ARGS)
403{
404 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
405 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
406 int len = PG_GETARG_INT32(4);
407
408 CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_WIN866);
409
410 mic2latin_with_table(src, dest, len, LC_KOI8_R, PG_WIN866, koi2win866);
411
412 PG_RETURN_VOID();
413}
414
415Datum
416koi8r_to_win1251(PG_FUNCTION_ARGS)
417{
418 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
419 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
420 int len = PG_GETARG_INT32(4);
421
422 CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN1251);
423
424 local2local(src, dest, len, PG_KOI8R, PG_WIN1251, koi2win1251);
425
426 PG_RETURN_VOID();
427}
428
429Datum
430win1251_to_koi8r(PG_FUNCTION_ARGS)
431{
432 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
433 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
434 int len = PG_GETARG_INT32(4);
435
436 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_KOI8R);
437
438 local2local(src, dest, len, PG_WIN1251, PG_KOI8R, win12512koi);
439
440 PG_RETURN_VOID();
441}
442
443Datum
444koi8r_to_win866(PG_FUNCTION_ARGS)
445{
446 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
447 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
448 int len = PG_GETARG_INT32(4);
449
450 CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_WIN866);
451
452 local2local(src, dest, len, PG_KOI8R, PG_WIN866, koi2win866);
453
454 PG_RETURN_VOID();
455}
456
457Datum
458win866_to_koi8r(PG_FUNCTION_ARGS)
459{
460 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
461 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
462 int len = PG_GETARG_INT32(4);
463
464 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_KOI8R);
465
466 local2local(src, dest, len, PG_WIN866, PG_KOI8R, win8662koi);
467
468 PG_RETURN_VOID();
469}
470
471Datum
472win866_to_win1251(PG_FUNCTION_ARGS)
473{
474 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
475 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
476 int len = PG_GETARG_INT32(4);
477
478 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_WIN1251);
479
480 local2local(src, dest, len, PG_WIN866, PG_WIN1251, win8662win1251);
481
482 PG_RETURN_VOID();
483}
484
485Datum
486win1251_to_win866(PG_FUNCTION_ARGS)
487{
488 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
489 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
490 int len = PG_GETARG_INT32(4);
491
492 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_WIN866);
493
494 local2local(src, dest, len, PG_WIN1251, PG_WIN866, win12512win866);
495
496 PG_RETURN_VOID();
497}
498
499Datum
500iso_to_koi8r(PG_FUNCTION_ARGS)
501{
502 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
503 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
504 int len = PG_GETARG_INT32(4);
505
506 CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_KOI8R);
507
508 local2local(src, dest, len, PG_ISO_8859_5, PG_KOI8R, iso2koi);
509
510 PG_RETURN_VOID();
511}
512
513Datum
514koi8r_to_iso(PG_FUNCTION_ARGS)
515{
516 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
517 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
518 int len = PG_GETARG_INT32(4);
519
520 CHECK_ENCODING_CONVERSION_ARGS(PG_KOI8R, PG_ISO_8859_5);
521
522 local2local(src, dest, len, PG_KOI8R, PG_ISO_8859_5, koi2iso);
523
524 PG_RETURN_VOID();
525}
526
527Datum
528iso_to_win1251(PG_FUNCTION_ARGS)
529{
530 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
531 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
532 int len = PG_GETARG_INT32(4);
533
534 CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN1251);
535
536 local2local(src, dest, len, PG_ISO_8859_5, PG_WIN1251, iso2win1251);
537
538 PG_RETURN_VOID();
539}
540
541Datum
542win1251_to_iso(PG_FUNCTION_ARGS)
543{
544 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
545 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
546 int len = PG_GETARG_INT32(4);
547
548 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN1251, PG_ISO_8859_5);
549
550 local2local(src, dest, len, PG_WIN1251, PG_ISO_8859_5, win12512iso);
551
552 PG_RETURN_VOID();
553}
554
555Datum
556iso_to_win866(PG_FUNCTION_ARGS)
557{
558 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
559 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
560 int len = PG_GETARG_INT32(4);
561
562 CHECK_ENCODING_CONVERSION_ARGS(PG_ISO_8859_5, PG_WIN866);
563
564 local2local(src, dest, len, PG_ISO_8859_5, PG_WIN866, iso2win866);
565
566 PG_RETURN_VOID();
567}
568
569Datum
570win866_to_iso(PG_FUNCTION_ARGS)
571{
572 unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
573 unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
574 int len = PG_GETARG_INT32(4);
575
576 CHECK_ENCODING_CONVERSION_ARGS(PG_WIN866, PG_ISO_8859_5);
577
578 local2local(src, dest, len, PG_WIN866, PG_ISO_8859_5, win8662iso);
579
580 PG_RETURN_VOID();
581}
582