1 | /*------------------------------------------------------------------------- |
2 | * |
3 | * WIN <--> UTF8 |
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/utf8_and_win/utf8_and_win.c |
10 | * |
11 | *------------------------------------------------------------------------- |
12 | */ |
13 | |
14 | #include "postgres.h" |
15 | #include "fmgr.h" |
16 | #include "mb/pg_wchar.h" |
17 | #include "../../Unicode/utf8_to_win1250.map" |
18 | #include "../../Unicode/utf8_to_win1251.map" |
19 | #include "../../Unicode/utf8_to_win1252.map" |
20 | #include "../../Unicode/utf8_to_win1253.map" |
21 | #include "../../Unicode/utf8_to_win1254.map" |
22 | #include "../../Unicode/utf8_to_win1255.map" |
23 | #include "../../Unicode/utf8_to_win1256.map" |
24 | #include "../../Unicode/utf8_to_win1257.map" |
25 | #include "../../Unicode/utf8_to_win1258.map" |
26 | #include "../../Unicode/utf8_to_win866.map" |
27 | #include "../../Unicode/utf8_to_win874.map" |
28 | #include "../../Unicode/win1250_to_utf8.map" |
29 | #include "../../Unicode/win1251_to_utf8.map" |
30 | #include "../../Unicode/win1252_to_utf8.map" |
31 | #include "../../Unicode/win1253_to_utf8.map" |
32 | #include "../../Unicode/win1254_to_utf8.map" |
33 | #include "../../Unicode/win1255_to_utf8.map" |
34 | #include "../../Unicode/win1256_to_utf8.map" |
35 | #include "../../Unicode/win1257_to_utf8.map" |
36 | #include "../../Unicode/win866_to_utf8.map" |
37 | #include "../../Unicode/win874_to_utf8.map" |
38 | #include "../../Unicode/win1258_to_utf8.map" |
39 | |
40 | PG_MODULE_MAGIC; |
41 | |
42 | PG_FUNCTION_INFO_V1(win_to_utf8); |
43 | PG_FUNCTION_INFO_V1(utf8_to_win); |
44 | |
45 | /* ---------- |
46 | * conv_proc( |
47 | * INTEGER, -- source encoding id |
48 | * INTEGER, -- destination encoding id |
49 | * CSTRING, -- source string (null terminated C string) |
50 | * CSTRING, -- destination string (null terminated C string) |
51 | * INTEGER -- source string length |
52 | * ) returns VOID; |
53 | * ---------- |
54 | */ |
55 | |
56 | typedef struct |
57 | { |
58 | pg_enc encoding; |
59 | const pg_mb_radix_tree *map1; /* to UTF8 map name */ |
60 | const pg_mb_radix_tree *map2; /* from UTF8 map name */ |
61 | } pg_conv_map; |
62 | |
63 | static const pg_conv_map maps[] = { |
64 | {PG_WIN866, &win866_to_unicode_tree, &win866_from_unicode_tree}, |
65 | {PG_WIN874, &win874_to_unicode_tree, &win874_from_unicode_tree}, |
66 | {PG_WIN1250, &win1250_to_unicode_tree, &win1250_from_unicode_tree}, |
67 | {PG_WIN1251, &win1251_to_unicode_tree, &win1251_from_unicode_tree}, |
68 | {PG_WIN1252, &win1252_to_unicode_tree, &win1252_from_unicode_tree}, |
69 | {PG_WIN1253, &win1253_to_unicode_tree, &win1253_from_unicode_tree}, |
70 | {PG_WIN1254, &win1254_to_unicode_tree, &win1254_from_unicode_tree}, |
71 | {PG_WIN1255, &win1255_to_unicode_tree, &win1255_from_unicode_tree}, |
72 | {PG_WIN1256, &win1256_to_unicode_tree, &win1256_from_unicode_tree}, |
73 | {PG_WIN1257, &win1257_to_unicode_tree, &win1257_from_unicode_tree}, |
74 | {PG_WIN1258, &win1258_to_unicode_tree, &win1258_from_unicode_tree}, |
75 | }; |
76 | |
77 | Datum |
78 | win_to_utf8(PG_FUNCTION_ARGS) |
79 | { |
80 | int encoding = PG_GETARG_INT32(0); |
81 | unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); |
82 | unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); |
83 | int len = PG_GETARG_INT32(4); |
84 | int i; |
85 | |
86 | CHECK_ENCODING_CONVERSION_ARGS(-1, PG_UTF8); |
87 | |
88 | for (i = 0; i < lengthof(maps); i++) |
89 | { |
90 | if (encoding == maps[i].encoding) |
91 | { |
92 | LocalToUtf(src, len, dest, |
93 | maps[i].map1, |
94 | NULL, 0, |
95 | NULL, |
96 | encoding); |
97 | PG_RETURN_VOID(); |
98 | } |
99 | } |
100 | |
101 | ereport(ERROR, |
102 | (errcode(ERRCODE_INTERNAL_ERROR), |
103 | errmsg("unexpected encoding ID %d for WIN character sets" , |
104 | encoding))); |
105 | |
106 | PG_RETURN_VOID(); |
107 | } |
108 | |
109 | Datum |
110 | utf8_to_win(PG_FUNCTION_ARGS) |
111 | { |
112 | int encoding = PG_GETARG_INT32(1); |
113 | unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2); |
114 | unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3); |
115 | int len = PG_GETARG_INT32(4); |
116 | int i; |
117 | |
118 | CHECK_ENCODING_CONVERSION_ARGS(PG_UTF8, -1); |
119 | |
120 | for (i = 0; i < lengthof(maps); i++) |
121 | { |
122 | if (encoding == maps[i].encoding) |
123 | { |
124 | UtfToLocal(src, len, dest, |
125 | maps[i].map2, |
126 | NULL, 0, |
127 | NULL, |
128 | encoding); |
129 | PG_RETURN_VOID(); |
130 | } |
131 | } |
132 | |
133 | ereport(ERROR, |
134 | (errcode(ERRCODE_INTERNAL_ERROR), |
135 | errmsg("unexpected encoding ID %d for WIN character sets" , |
136 | encoding))); |
137 | |
138 | PG_RETURN_VOID(); |
139 | } |
140 | |