View | Details | Raw Unified | Return to bug 184280
Collapse All | Expand All

(-)Makefile (+22 lines)
Lines 13-24 Link Here
13
LICENSE_COMB=	dual
13
LICENSE_COMB=	dual
14
LICENSE_FILE_MPL=	${WRKSRC}/COPYING.MPL
14
LICENSE_FILE_MPL=	${WRKSRC}/COPYING.MPL
15
15
16
OPTIONS_DEFINE=	RCC
17
RCC_DESC=	Build with RusXMMS librcc patches (experimental)
18
16
USES=		cmake
19
USES=		cmake
17
CMAKE_ARGS=	-DWITH_ASF:BOOL=ON \
20
CMAKE_ARGS=	-DWITH_ASF:BOOL=ON \
18
		-DWITH_MP4:BOOL=ON
21
		-DWITH_MP4:BOOL=ON
19
USE_LDCONFIG=	yes
22
USE_LDCONFIG=	yes
20
23
24
.include <bsd.port.options.mk>
25
26
.if ${PORT_OPTIONS:MRCC}
27
PKGNAMESUFFIX=	-rcc
28
EXTRA_PATCHES+=	${FILESDIR}/extrapatch-rcc
29
CFLAGS+=	-I${LOCALBASE}/include
30
LDFLAGS+=	-L${LOCALBASE}/lib
31
LIB_DEPENDS+=	librcc.so:${PORTSDIR}/devel/librcc
32
PLIST_SUB+=	RCC=""
33
.else
34
PLIST_SUB+=	RCC="@comment "
35
.endif
36
21
post-patch:
37
post-patch:
38
.if ${PORT_OPTIONS:MRCC}
39
	@${REINPLACE_CMD} -e 's|-ltag|-ltag -lrcc|g' \
40
		${WRKSRC}/taglib.pc.cmake ${WRKSRC}/taglib-config.cmake
41
	@${REINPLACE_CMD} -e 's|-ltag_c|-ltag_c -lrcc|g' \
42
		${WRKSRC}/bindings/c/taglib_c.pc.cmake
43
.endif
22
	${REINPLACE_CMD} -e 's|$${LIB_INSTALL_DIR}/pkgconfig|libdata/pkgconfig|' \
44
	${REINPLACE_CMD} -e 's|$${LIB_INSTALL_DIR}/pkgconfig|libdata/pkgconfig|' \
23
		${WRKSRC}/CMakeLists.txt ${WRKSRC}/bindings/c/CMakeLists.txt
45
		${WRKSRC}/CMakeLists.txt ${WRKSRC}/bindings/c/CMakeLists.txt
24
46
(-)files/extrapatch-rcc (+676 lines)
Line 0 Link Here
1
diff -dPNur ./config.h.cmake ./config.h.cmake
2
--- ./config.h.cmake	2013-10-08 17:50:01.000000000 +0200
3
+++ ./config.h.cmake	2013-11-11 13:43:48.500304915 +0100
4
@@ -31,6 +31,9 @@
5
 /* Defined if you have libz */
6
 #cmakedefine   HAVE_ZLIB 1
7
 
8
+/* Defined if you have LibRCC from RusXMMS project */
9
+#cmakedefine   HAVE_LIBRCC 1
10
+
11
 /* Indicates whether debug messages are shown even in release mode */
12
 #cmakedefine   TRACE_IN_RELEASE 1
13
 
14
diff -dPNur ./ConfigureChecks.cmake ./ConfigureChecks.cmake
15
--- ./ConfigureChecks.cmake	2013-10-08 17:50:01.000000000 +0200
16
+++ ./ConfigureChecks.cmake	2013-11-11 13:42:53.017126134 +0100
17
@@ -216,6 +216,7 @@
18
   set(HAVE_ZLIB 0)
19
 endif()
20
 
21
+SET(HAVE_LIBRCC 1)
22
 
23
 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
24
 
25
diff -dPNur ./examples/tagreader_c.c ./examples/tagreader_c.c
26
--- ./examples/tagreader_c.c	2013-10-08 17:50:01.000000000 +0200
27
+++ ./examples/tagreader_c.c	2013-11-11 13:42:53.017126134 +0100
28
@@ -38,7 +38,7 @@
29
   TagLib_Tag *tag;
30
   const TagLib_AudioProperties *properties;
31
 
32
-  taglib_set_strings_unicode(FALSE);
33
+//  taglib_set_strings_unicode(FALSE);
34
 
35
   for(i = 1; i < argc; i++) {
36
     printf("******************** \"%s\" ********************\n", argv[i]);
37
diff -dPNur ./examples/tagwriter.cpp ./examples/tagwriter.cpp
38
--- ./examples/tagwriter.cpp	2013-10-08 17:50:01.000000000 +0200
39
+++ ./examples/tagwriter.cpp	2013-11-11 13:42:53.028126368 +0100
40
@@ -92,7 +92,7 @@
41
     if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) {
42
 
43
       char field = argv[i][1];
44
-      TagLib::String value = argv[i + 1];
45
+      TagLib::String value(argv[i + 1], TagLib::String::Locale);
46
 
47
       TagLib::List<TagLib::FileRef>::Iterator it;
48
       for(it = fileList.begin(); it != fileList.end(); ++it) {
49
diff -dPNur ./taglib/CMakeLists.txt ./taglib/CMakeLists.txt
50
--- ./taglib/CMakeLists.txt	2013-10-08 17:50:01.000000000 +0200
51
+++ ./taglib/CMakeLists.txt	2013-11-11 13:42:53.042126665 +0100
52
@@ -36,6 +36,7 @@
53
   audioproperties.h
54
   taglib_export.h
55
   ${CMAKE_BINARY_DIR}/taglib_config.h
56
+  toolkit/rccpatch.h
57
   toolkit/taglib.h
58
   toolkit/tstring.h
59
   toolkit/tlist.h
60
@@ -281,6 +282,7 @@
61
 )
62
 
63
 set(toolkit_SRCS
64
+  toolkit/rccpatch.cpp
65
   toolkit/tstring.cpp
66
   toolkit/tstringlist.cpp
67
   toolkit/tbytevector.cpp
68
@@ -310,7 +312,7 @@
69
 add_library(tag ${tag_LIB_SRCS} ${tag_HDRS})
70
 
71
 if(ZLIB_FOUND)
72
-	target_link_libraries(tag ${ZLIB_LIBRARIES})
73
+	target_link_libraries(tag rcc ${ZLIB_LIBRARIES})
74
 endif()
75
 
76
 set_target_properties(tag PROPERTIES
77
diff -dPNur ./taglib/mpeg/id3v1/id3v1tag.cpp ./taglib/mpeg/id3v1/id3v1tag.cpp
78
--- ./taglib/mpeg/id3v1/id3v1tag.cpp	2013-10-08 17:50:01.000000000 +0200
79
+++ ./taglib/mpeg/id3v1/id3v1tag.cpp	2013-11-11 13:42:53.043126686 +0100
80
@@ -64,17 +64,18 @@
81
 
82
 String ID3v1::StringHandler::parse(const ByteVector &data) const
83
 {
84
-  return String(data, String::Latin1).stripWhiteSpace();
85
+  return String(data, String::Latin1ID3).stripWhiteSpace();
86
 }
87
 
88
 ByteVector ID3v1::StringHandler::render(const String &s) const
89
 {
90
   if(!s.isLatin1())
91
   {
92
+   if (String::ID3WType(String::Latin1) == String::Latin1)
93
     return ByteVector();
94
   }
95
 
96
-  return s.data(String::Latin1);
97
+  return s.data(String::Latin1ID3);
98
 }
99
 
100
 ////////////////////////////////////////////////////////////////////////////////
101
@@ -257,7 +258,7 @@
102
     d->track = uchar(data[offset + 29]);
103
   }
104
   else
105
-    d->comment = data.mid(offset, 30);
106
+    d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30));
107
 
108
   offset += 30;
109
 
110
diff -dPNur ./taglib/mpeg/id3v2/frames/commentsframe.cpp ./taglib/mpeg/id3v2/frames/commentsframe.cpp
111
--- ./taglib/mpeg/id3v2/frames/commentsframe.cpp	2013-10-08 17:50:01.000000000 +0200
112
+++ ./taglib/mpeg/id3v2/frames/commentsframe.cpp	2013-11-11 13:42:53.043126686 +0100
113
@@ -150,10 +150,10 @@
114
     return;
115
   }
116
 
117
-  d->textEncoding = String::Type(data[0]);
118
+  d->textEncoding = String::ID3Type(data[0]);
119
   d->language = data.mid(1, 3);
120
 
121
-  int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
122
+  int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
123
 
124
   ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2);
125
 
126
@@ -174,10 +174,12 @@
127
 
128
   String::Type encoding = d->textEncoding;
129
 
130
+  encoding = String::ID3WType(encoding);
131
+
132
   encoding = checkTextEncoding(d->description, encoding);
133
   encoding = checkTextEncoding(d->text, encoding);
134
 
135
-  v.append(char(encoding));
136
+  v.append(char(String::ID3RealType(encoding)));
137
   v.append(d->language.size() == 3 ? d->language : "XXX");
138
   v.append(d->description.data(encoding));
139
   v.append(textDelimiter(encoding));
140
diff -dPNur ./taglib/mpeg/id3v2/frames/textidentificationframe.cpp ./taglib/mpeg/id3v2/frames/textidentificationframe.cpp
141
--- ./taglib/mpeg/id3v2/frames/textidentificationframe.cpp	2013-10-08 17:50:01.000000000 +0200
142
+++ ./taglib/mpeg/id3v2/frames/textidentificationframe.cpp	2013-11-11 13:42:53.044126708 +0100
143
@@ -187,12 +187,12 @@
144
 
145
   // read the string data type (the first byte of the field data)
146
 
147
-  d->textEncoding = String::Type(data[0]);
148
+  d->textEncoding = String::ID3Type(data[0]);
149
 
150
   // split the byte array into chunks based on the string type (two byte delimiter
151
   // for unicode encodings)
152
 
153
-  int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
154
+  int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2;
155
 
156
   // build a small counter to strip nulls off the end of the field
157
 
158
@@ -223,11 +223,14 @@
159
 
160
 ByteVector TextIdentificationFrame::renderFields() const
161
 {
162
-  String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding);
163
+  String::Type encoding = d->textEncoding;
164
+
165
+  encoding = String::ID3WType(encoding);
166
+  encoding = checkTextEncoding(d->fieldList, encoding);
167
 
168
   ByteVector v;
169
 
170
-  v.append(char(encoding));
171
+  v.append(char(String::ID3RealType(encoding)));
172
 
173
   for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
174
 
175
diff -dPNur ./taglib/mpeg/id3v2/id3v2frame.cpp ./taglib/mpeg/id3v2/id3v2frame.cpp
176
--- ./taglib/mpeg/id3v2/id3v2frame.cpp	2013-10-08 17:50:01.000000000 +0200
177
+++ ./taglib/mpeg/id3v2/id3v2frame.cpp	2013-11-11 13:42:53.045126729 +0100
178
@@ -302,7 +302,7 @@
179
   if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4)
180
     return String::UTF16;
181
 
182
-  if(encoding != String::Latin1)
183
+  if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2))
184
     return encoding;
185
 
186
   for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
187
diff -dPNur ./taglib/toolkit/rccpatch.cpp ./taglib/toolkit/rccpatch.cpp
188
--- ./taglib/toolkit/rccpatch.cpp	1970-01-01 01:00:00.000000000 +0100
189
+++ ./taglib/toolkit/rccpatch.cpp	2013-11-11 13:42:53.045126729 +0100
190
@@ -0,0 +1,237 @@
191
+#include <stdlib.h>
192
+
193
+#include <string>
194
+#include "tstring.h"
195
+#include "tbytevector.h"
196
+
197
+//#define RCC_DEBUG
198
+
199
+
200
+#ifndef HAVE_LIBRCC
201
+# include <config.h>
202
+#endif
203
+
204
+#ifdef HAVE_LIBRCC
205
+# ifdef RCC_DEBUG
206
+#  include <stdio.h>
207
+# endif /* RCC_DEBUG */
208
+# include <librcc.h>
209
+# include <string.h>
210
+#endif /* HAVE_LIBRCC */
211
+
212
+
213
+#ifdef HAVE_LIBRCC
214
+# define ID3_CLASS 0
215
+# define ID3V2_CLASS 1
216
+# define UTF_CLASS 2
217
+# define OUT_CLASS 3
218
+static rcc_class classes[] = {
219
+    { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 },
220
+    { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 },
221
+    { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0},
222
+    { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 },
223
+    { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 }
224
+};
225
+
226
+static int rcc_initialized = 0;
227
+
228
+static rcc_context ctx = NULL;
229
+#endif /* HAVE_LIBRCC */
230
+
231
+
232
+void rccTaglibPatchFree() {
233
+#ifdef HAVE_LIBRCC
234
+    if (rcc_initialized) {
235
+       rccFree();
236
+       rcc_initialized = 0;
237
+    }
238
+#endif /* HAVE_LIBRCC */
239
+}
240
+
241
+void rccTaglibPatchInit() {
242
+#ifdef HAVE_LIBRCC
243
+    if (rcc_initialized) return;
244
+    rccInit();
245
+    rccInitDefaultContext(NULL, 0, 0, classes, 0);
246
+    rccLoad(NULL, "xmms");
247
+    rccInitDb4(NULL, NULL, 0);
248
+    rcc_initialized = 1;
249
+#endif /* HAVE_LIBRCC */
250
+}
251
+
252
+void rccTaglibPatchSetContext(void *newctx) {
253
+#ifdef HAVE_LIBRCC
254
+    if (newctx) {
255
+	ctx = (rcc_context)newctx;
256
+	rcc_initialized = 1;
257
+    }
258
+#endif /* HAVE_LIBRCC */
259
+}
260
+
261
+static void rccTaglibPatchTryInit() {
262
+#ifdef HAVE_LIBRCC
263
+    if (!rcc_initialized) {
264
+	rccTaglibPatchInit();
265
+	if (rcc_initialized) atexit(rccTaglibPatchFree);	
266
+    }
267
+#endif /* HAVE_LIBRCC */
268
+}
269
+
270
+
271
+TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) {
272
+    TagLib::ByteVector v;
273
+#ifdef HAVE_LIBRCC
274
+    size_t rlen;
275
+    char *res;
276
+
277
+    rccTaglibPatchTryInit();
278
+
279
+    res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen);
280
+#ifdef RCC_DEBUG
281
+    for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
282
+	if (*c > 127) {
283
+	    printf(" Output: %s - %s\n", s.c_str(), res?res:"null");
284
+	    break;
285
+	}
286
+    }
287
+#endif /* RCC_DEBUG */
288
+
289
+    if (res) v.setData(res, rlen);
290
+    else v.setData("", 0);
291
+    //v.setData(s.c_str(), s.length());
292
+
293
+    return v;
294
+#else
295
+    v.setData("", 0);
296
+    
297
+    return v;
298
+#endif /* HAVE_LIBRCC */
299
+}
300
+
301
+TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) {
302
+    TagLib::ByteVector v;
303
+#ifdef HAVE_LIBRCC
304
+    size_t rlen;
305
+    char *res;
306
+
307
+    rccTaglibPatchTryInit();
308
+
309
+    res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen);
310
+#ifdef RCC_DEBUG
311
+    for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
312
+	if (*c > 127) {
313
+	    printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
314
+	    break;
315
+	}
316
+    }
317
+#endif /* RCC_DEBUG */
318
+
319
+    if (res) v.setData(res, rlen);
320
+    else v.setData("", 0);
321
+    //v.setData(s.c_str(), s.length());
322
+
323
+    return v;
324
+#else
325
+    v.setData("", 0);
326
+    
327
+    return v;
328
+#endif /* HAVE_LIBRCC */
329
+}
330
+
331
+TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) {
332
+    TagLib::ByteVector v;
333
+#ifdef HAVE_LIBRCC
334
+    size_t rlen;
335
+    char *res;
336
+
337
+    rccTaglibPatchTryInit();
338
+
339
+    res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
340
+#ifdef RCC_DEBUG
341
+    for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
342
+	if (*c > 127) {
343
+	    printf(" Input: %s - %s\n", s.c_str(), res?res:"null");
344
+	    break;
345
+	}
346
+    }
347
+#endif /* RCC_DEBUG */
348
+
349
+    if (res) v.setData(res, rlen);
350
+    else
351
+#endif /* HAVE_LIBRCC */
352
+    v.setData("", 0);
353
+    
354
+    return v;
355
+}
356
+
357
+TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) {
358
+    TagLib::ByteVector v;
359
+#ifdef HAVE_LIBRCC
360
+    size_t rlen;
361
+    char *res;
362
+
363
+    rccTaglibPatchTryInit();
364
+
365
+    res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen);
366
+#ifdef RCC_DEBUG
367
+    for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) {
368
+	if (*c > 127) {
369
+	    printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null");
370
+	    break;
371
+	}
372
+    }
373
+#endif /* RCC_DEBUG */
374
+    if (res) v.setData(res, rlen + 1);
375
+    else
376
+#endif /* HAVE_LIBRCC */
377
+    v.setData("", 0);
378
+
379
+    return v;
380
+}
381
+
382
+TagLib::String::Type rccTaglibPatchGetLocaleType() {
383
+#ifdef HAVE_LIBRCC
384
+    size_t len;
385
+    char charset[32];
386
+
387
+    rccTaglibPatchTryInit();
388
+    if (!rccLocaleGetCharset(charset, NULL, 31)) {
389
+	if (!strncmp(charset, "UTF", 3)) {
390
+	    len = strlen(charset);
391
+	    
392
+	    if (charset[len-1]=='8') return TagLib::String::UTF8;
393
+	    if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
394
+	    if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
395
+	    if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
396
+	}
397
+	return TagLib::String::Latin1;
398
+    }
399
+#endif /* HAVE_LIBRCC */
400
+    return TagLib::String::UTF8;
401
+}
402
+
403
+TagLib::String::Type rccTaglibPatchGetID3Type() {
404
+#ifdef HAVE_LIBRCC
405
+    size_t len;
406
+    const char *charset;
407
+
408
+    rccTaglibPatchTryInit();
409
+    
410
+    charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS);
411
+    if (charset) {
412
+	if (!strncmp(charset, "UTF", 3)) {
413
+	    len = strlen(charset);
414
+	    
415
+	    if (charset[len-1]=='8') return TagLib::String::UTF8;
416
+	    if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16;
417
+	    if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE;
418
+	    if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE;
419
+	}
420
+	return TagLib::String::Latin1ID3V2;
421
+    } else {
422
+	// Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib
423
+	return TagLib::String::Latin1ID3V2;
424
+    }
425
+#endif /* HAVE_LIBRCC */
426
+    return TagLib::String::Latin1;
427
+}
428
diff -dPNur ./taglib/toolkit/rccpatch.h ./taglib/toolkit/rccpatch.h
429
--- ./taglib/toolkit/rccpatch.h	1970-01-01 01:00:00.000000000 +0100
430
+++ ./taglib/toolkit/rccpatch.h	2013-11-11 13:42:53.045126729 +0100
431
@@ -0,0 +1,20 @@
432
+#ifndef _RCC_PATCH_H
433
+#define _RCC_PATCH_H
434
+
435
+#include <string.h>
436
+#include "tstring.h"
437
+#include "tbytevector.h"
438
+
439
+void rccTaglibPatchFree();
440
+void rccTaglibPatchInit();
441
+void rccTaglibPatchSetContext(void *newctx);
442
+
443
+TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s);
444
+TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s);
445
+TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false);
446
+TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false);
447
+
448
+TagLib::String::Type rccTaglibPatchGetLocaleType();
449
+TagLib::String::Type rccTaglibPatchGetID3Type();
450
+
451
+#endif /* _RCC_PATCH_H */
452
diff -dPNur ./taglib/toolkit/tstring.cpp ./taglib/toolkit/tstring.cpp
453
--- ./taglib/toolkit/tstring.cpp	2013-10-08 17:50:01.000000000 +0200
454
+++ ./taglib/toolkit/tstring.cpp	2013-11-11 13:42:53.046126750 +0100
455
@@ -29,6 +29,7 @@
456
 #include <config.h>
457
 #endif
458
 
459
+#include "rccpatch.h"
460
 #include "tstring.h"
461
 #include "tdebug.h"
462
 #include "tstringlist.h"
463
@@ -197,8 +198,11 @@
464
 String::String(const std::string &s, Type t)
465
   : d(new StringPrivate())
466
 {
467
-  if(t == Latin1)
468
-    copyFromLatin1(&s[0], s.length());
469
+  if(t == Locale)
470
+    t = rccTaglibPatchGetLocaleType();
471
+
472
+  if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
473
+    copyFromLatin1(&s[0], s.length(), true, t);
474
   else if(t == String::UTF8)
475
     copyFromUTF8(&s[0], s.length());
476
   else {
477
@@ -229,8 +233,11 @@
478
 String::String(const char *s, Type t)
479
   : d(new StringPrivate())
480
 {
481
-  if(t == Latin1)
482
-    copyFromLatin1(s, ::strlen(s));
483
+  if(t == Locale)
484
+    t = rccTaglibPatchGetLocaleType();
485
+
486
+  if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
487
+    copyFromLatin1(s, ::strlen(s), true, t);
488
   else if(t == String::UTF8)
489
     copyFromUTF8(s, ::strlen(s));
490
   else {
491
@@ -251,7 +258,10 @@
492
 String::String(char c, Type t)
493
   : d(new StringPrivate(1, static_cast<uchar>(c)))
494
 {
495
-  if(t != Latin1 && t != UTF8) {
496
+  if(t == Locale)
497
+    t = rccTaglibPatchGetLocaleType();
498
+
499
+  if(t != Latin1 && t != Latin1ID3 && t != Latin1ID3V2 && t != UTF8) {
500
     debug("String::String() -- A char should not contain UTF16.");
501
   }
502
 }
503
@@ -262,8 +272,11 @@
504
   if(v.isEmpty())
505
     return;
506
 
507
-  if(t == Latin1) 
508
-    copyFromLatin1(v.data(), v.size());
509
+  if(t == Locale)
510
+    t = rccTaglibPatchGetLocaleType();
511
+
512
+  if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2)
513
+    copyFromLatin1(v.data(), v.size(), true, t);
514
   else if(t == UTF8) 
515
     copyFromUTF8(v.data(), v.size());
516
   else 
517
@@ -428,16 +441,46 @@
518
 
519
 ByteVector String::data(Type t) const
520
 {
521
-  switch(t) 
522
-  {
523
+  ByteVector v;
524
+
525
+  if (t == Locale) {
526
+        // The source is either Unicode or real Latin1 (if rcc is bypassed)
527
+    std::string s = to8Bit(true);
528
+
529
+        // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich
530
+    v = rccTaglibPatchRecodeOutput(s);
531
+    if (v.size()) return v;
532
+
533
+    t = rccTaglibPatchGetLocaleType();
534
+  }
535
+
536
+  switch(t) {
537
+  case Latin1ID3:
538
+  case Latin1ID3V2:
539
+    {
540
+      std::string s = to8Bit(true);
541
+      if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false);
542
+      else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true);
543
+      if (v.size()) 
544
+        return v;
545
+      
546
+          // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required
547
+      if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) {
548
+          v.setData(s.c_str(), s.length());
549
+      } else {
550
+          for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
551
+            v.append(char(*it));
552
+      }
553
+      return v;
554
+    }
555
   case Latin1:
556
     {
557
       ByteVector v(size(), 0);
558
       char *p = v.data();
559
-
560
+ 
561
       for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++)
562
         *p++ = static_cast<char>(*it);
563
-
564
+ 
565
       return v;
566
     }
567
   case UTF8:
568
@@ -763,12 +806,29 @@
569
 // private members
570
 ////////////////////////////////////////////////////////////////////////////////
571
 
572
-void String::copyFromLatin1(const char *s, size_t length)
573
+void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t)
574
 {
575
   d->data.resize(length);
576
-
577
   for(size_t i = 0; i < length; ++i)
578
     d->data[i] = static_cast<uchar>(s[i]);
579
+
580
+  // librcc conversation
581
+  if (prepare) {
582
+    std::string s = to8Bit(false);
583
+    ByteVector v;
584
+
585
+    if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false);
586
+    else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true);
587
+    else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s);
588
+
589
+    if (v.size()) {
590
+      copyFromUTF8(v.data(), v.size());
591
+    } else {
592
+    // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed,
593
+    // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8
594
+    //if (Unicode::isLegalUTF8(s)) t = UTF8;
595
+    }
596
+  }
597
 }
598
 
599
 void String::copyFromUTF8(const char *s, size_t length)
600
@@ -874,7 +934,33 @@
601
 
602
 std::ostream &operator<<(std::ostream &s, const TagLib::String &str)
603
 {
604
-  s << str.to8Bit();
605
+  TagLib::ByteVector bv = str.data(TagLib::String::Locale);
606
+  s << bv;
607
   return s;
608
 }
609
 
610
+TagLib::String::Type TagLib::String::ID3Type(int i)
611
+{
612
+  if(i == Latin1)
613
+    return Latin1ID3V2;
614
+  return Type(i);
615
+};
616
+
617
+TagLib::String::Type TagLib::String::ID3WType(Type type)
618
+{
619
+  Type rcc_type = rccTaglibPatchGetID3Type();
620
+  if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) {
621
+    if(type == Latin1) return
622
+      rcc_type;
623
+    return type;
624
+  }
625
+
626
+  return rcc_type;
627
+};
628
+
629
+TagLib::String::Type TagLib::String::ID3RealType(Type type)
630
+{
631
+  if((type == Latin1ID3) || (type == Latin1ID3V2))
632
+    return Latin1;
633
+  return type;
634
+}
635
diff -dPNur ./taglib/toolkit/tstring.h ./taglib/toolkit/tstring.h
636
--- ./taglib/toolkit/tstring.h	2013-10-08 17:50:01.000000000 +0200
637
+++ ./taglib/toolkit/tstring.h	2013-11-11 13:42:53.047126771 +0100
638
@@ -90,6 +90,18 @@
639
      */
640
     enum Type {
641
       /*!
642
+       * Determine using current locale settings
643
+       */
644
+      Locale = -1,
645
+      /*!
646
+       * Latin1 for ID3 tags.
647
+       */
648
+      Latin1ID3 = 65,
649
+      /*!
650
+       * Latin1 for ID3v2 tags.
651
+       */
652
+      Latin1ID3V2 = 66,
653
+      /*!
654
        * IS08859-1, or <i>Latin1</i> encoding.  8 bit characters.
655
        */
656
       Latin1 = 0,
657
@@ -112,6 +124,10 @@
658
       UTF16LE = 4
659
     };
660
 
661
+    static Type ID3Type(int i);
662
+    static Type ID3WType(Type type);
663
+    static Type ID3RealType(Type type);
664
+
665
     /*!
666
      * Constructs an empty String.
667
      */
668
@@ -479,7 +495,7 @@
669
      * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) 
670
      * and copies it to the internal buffer.
671
      */
672
-    void copyFromLatin1(const char *s, size_t length);
673
+    void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1);
674
 
675
     /*!
676
      * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) 
(-)pkg-plist (+1 lines)
Lines 56-61 Link Here
56
include/taglib/ownershipframe.h
56
include/taglib/ownershipframe.h
57
include/taglib/popularimeterframe.h
57
include/taglib/popularimeterframe.h
58
include/taglib/privateframe.h
58
include/taglib/privateframe.h
59
%%RCC%%include/taglib/rccpatch.h
59
include/taglib/relativevolumeframe.h
60
include/taglib/relativevolumeframe.h
60
include/taglib/rifffile.h
61
include/taglib/rifffile.h
61
include/taglib/s3mfile.h
62
include/taglib/s3mfile.h

Return to bug 184280