Line 0
Link Here
|
|
|
1 |
#include <stdlib.h> |
2 |
|
3 |
#include <string> |
4 |
#include "tstring.h" |
5 |
#include "tbytevector.h" |
6 |
|
7 |
#ifndef HAVE_LIBRCC |
8 |
# include <config.h> |
9 |
#endif |
10 |
|
11 |
#ifdef HAVE_LIBRCC |
12 |
# include <librcc.h> |
13 |
# include <string.h> |
14 |
#endif /* HAVE_LIBRCC */ |
15 |
|
16 |
|
17 |
#ifdef HAVE_LIBRCC |
18 |
# define ID3_CLASS 0 |
19 |
# define ID3V2_CLASS 1 |
20 |
# define UTF_CLASS 2 |
21 |
# define OUT_CLASS 3 |
22 |
static rcc_class classes[] = { |
23 |
{ "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, |
24 |
{ "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, |
25 |
{ "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, |
26 |
{ "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, |
27 |
{ NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } |
28 |
}; |
29 |
|
30 |
static int rcc_initialized = 0; |
31 |
|
32 |
static rcc_context ctx = NULL; |
33 |
#endif /* HAVE_LIBRCC */ |
34 |
|
35 |
|
36 |
void rccPatchFree() { |
37 |
#ifdef HAVE_LIBRCC |
38 |
if (rcc_initialized) { |
39 |
rccFree(); |
40 |
rcc_initialized = 0; |
41 |
} |
42 |
#endif /* HAVE_LIBRCC */ |
43 |
} |
44 |
|
45 |
void rccPatchInit() { |
46 |
#ifdef HAVE_LIBRCC |
47 |
if (rcc_initialized) return; |
48 |
rccInit(); |
49 |
rccInitDefaultContext(NULL, 0, 0, classes, 0); |
50 |
rccLoad(NULL, "xmms"); |
51 |
rccInitDb4(NULL, NULL, 0); |
52 |
rcc_initialized = 1; |
53 |
#endif /* HAVE_LIBRCC */ |
54 |
} |
55 |
|
56 |
void rccPatchSetContext(void *newctx) { |
57 |
#ifdef HAVE_LIBRCC |
58 |
if (newctx) { |
59 |
ctx = (rcc_context)newctx; |
60 |
rcc_initialized = 1; |
61 |
} |
62 |
#endif /* HAVE_LIBRCC */ |
63 |
} |
64 |
|
65 |
static void rccPatchTryInit() { |
66 |
#ifdef HAVE_LIBRCC |
67 |
if (!rcc_initialized) { |
68 |
rccPatchInit(); |
69 |
if (rcc_initialized) atexit(rccPatchFree); |
70 |
} |
71 |
#endif /* HAVE_LIBRCC */ |
72 |
} |
73 |
|
74 |
|
75 |
TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { |
76 |
TagLib::ByteVector v; |
77 |
#ifdef HAVE_LIBRCC |
78 |
size_t rlen; |
79 |
char *res; |
80 |
|
81 |
rccPatchTryInit(); |
82 |
|
83 |
res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); |
84 |
if (res) v.setData(res, rlen); |
85 |
else v.setData(s.c_str(), s.length()); |
86 |
|
87 |
return v; |
88 |
#else |
89 |
v.setData("", 0); |
90 |
|
91 |
return v; |
92 |
#endif /* HAVE_LIBRCC */ |
93 |
} |
94 |
|
95 |
TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { |
96 |
TagLib::ByteVector v; |
97 |
#ifdef HAVE_LIBRCC |
98 |
size_t rlen; |
99 |
char *res; |
100 |
|
101 |
rccPatchTryInit(); |
102 |
|
103 |
res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); |
104 |
if (res) v.setData(res, rlen); |
105 |
else v.setData(s.c_str(), s.length()); |
106 |
|
107 |
return v; |
108 |
#else |
109 |
v.setData("", 0); |
110 |
|
111 |
return v; |
112 |
#endif /* HAVE_LIBRCC */ |
113 |
} |
114 |
|
115 |
TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { |
116 |
TagLib::ByteVector v; |
117 |
#ifdef HAVE_LIBRCC |
118 |
size_t rlen; |
119 |
char *res; |
120 |
|
121 |
rccPatchTryInit(); |
122 |
|
123 |
res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); |
124 |
if (res) v.setData(res, rlen); |
125 |
else |
126 |
#endif /* HAVE_LIBRCC */ |
127 |
v.setData("", 0); |
128 |
|
129 |
return v; |
130 |
} |
131 |
|
132 |
TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { |
133 |
TagLib::ByteVector v; |
134 |
#ifdef HAVE_LIBRCC |
135 |
size_t rlen; |
136 |
char *res; |
137 |
|
138 |
rccPatchTryInit(); |
139 |
|
140 |
res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); |
141 |
if (res) v.setData(res, rlen); |
142 |
else |
143 |
#endif /* HAVE_LIBRCC */ |
144 |
v.setData("", 0); |
145 |
|
146 |
return v; |
147 |
} |
148 |
|
149 |
TagLib::String::Type rccPatchGetLocaleType() { |
150 |
#ifdef HAVE_LIBRCC |
151 |
size_t len; |
152 |
char charset[32]; |
153 |
|
154 |
rccPatchTryInit(); |
155 |
|
156 |
if (!rccLocaleGetCharset(charset, NULL, 31)) { |
157 |
if (!strncmp(charset, "UTF", 3)) { |
158 |
len = strlen(charset); |
159 |
|
160 |
if (charset[len-1]=='8') return TagLib::String::UTF8; |
161 |
if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; |
162 |
if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; |
163 |
if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; |
164 |
} |
165 |
return TagLib::String::Latin1; |
166 |
} |
167 |
#endif /* HAVE_LIBRCC */ |
168 |
return TagLib::String::UTF8; |
169 |
} |
170 |
|
171 |
TagLib::String::Type rccPatchGetID3Type() { |
172 |
#ifdef HAVE_LIBRCC |
173 |
size_t len; |
174 |
const char *charset; |
175 |
|
176 |
rccPatchTryInit(); |
177 |
|
178 |
charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); |
179 |
if (charset) { |
180 |
if (!strncmp(charset, "UTF", 3)) { |
181 |
len = strlen(charset); |
182 |
|
183 |
if (charset[len-1]=='8') return TagLib::String::UTF8; |
184 |
if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; |
185 |
if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; |
186 |
if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; |
187 |
} |
188 |
return TagLib::String::Latin1ID3V2; |
189 |
} |
190 |
#endif /* HAVE_LIBRCC */ |
191 |
return TagLib::String::Latin1; |
192 |
} |