forked from giggls/mapnik-german-l10n
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathosml10n_translit.cpp
84 lines (63 loc) · 2.06 KB
/
osml10n_translit.cpp
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
/*
Load using the following command:
CREATE FUNCTION osml10n_translit(text) RETURNS text
AS '/path/to/osml10n_translit.so', 'osml10n_translit' LANGUAGE C STRICT;
(c) 2013 Sven Geggus <[email protected]>
Licence AGPL http://www.gnu.org/licenses/agpl-3.0.de.html
*/
/* needed in icu >= 62 */
#define U_USING_ICU_NAMESPACE 1
#include <iostream>
#include <unicode/unistr.h>
#include <unicode/translit.h>
extern "C" {
#include <postgres.h>
#include <stdlib.h>
#include <string.h>
#include <mb/pg_wchar.h>
#include <fmgr.h>
#include "varatt.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(osml10n_translit);
Datum osml10n_translit(PG_FUNCTION_ARGS) {
Transliterator *latin_tl;
UErrorCode status = U_ZERO_ERROR;
char *inbuf,*outbuf;
if (GetDatabaseEncoding() != PG_UTF8) {
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("requires UTF8 database encoding")));
}
text *t = PG_GETARG_TEXT_P(0);
inbuf=(char *) malloc((VARSIZE(t) - VARHDRSZ +1)*sizeof(char));
memcpy(inbuf, (void *) VARDATA(t), VARSIZE(t) - VARHDRSZ);
inbuf[VARSIZE(t) - VARHDRSZ]='\0';
UnicodeString ustr(inbuf);
latin_tl = Transliterator::createInstance("Any-Latin", UTRANS_FORWARD, status);
if (latin_tl == 0) {
ereport(ERROR,(errcode(ERRCODE_SYSTEM_ERROR),
errmsg("ERROR: Transliterator::createInstance() failed")));
PG_RETURN_TEXT_P("");
}
latin_tl->transliterate(ustr);
int32_t bufLen = 100;
outbuf = (char *) malloc((bufLen + 1)*sizeof(char));
status=U_ZERO_ERROR;
bufLen = ustr.extract(outbuf,bufLen,NULL,status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
status=U_ZERO_ERROR;
outbuf = (char *) realloc(outbuf, bufLen + 1);
bufLen = ustr.extract(outbuf,bufLen,NULL,status);
}
outbuf[bufLen] = '\0';
text *new_text = (text *) palloc(VARHDRSZ + bufLen);
SET_VARSIZE(new_text, VARHDRSZ + bufLen);
memcpy((void *) VARDATA(new_text), /* destination */
(void *) outbuf,bufLen);
free(inbuf);
free(outbuf);
delete latin_tl;
PG_RETURN_TEXT_P(new_text);
}
} /* extern "C" */