-
Notifications
You must be signed in to change notification settings - Fork 0
/
transcode.cpp
108 lines (91 loc) · 3 KB
/
transcode.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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/* Copyright (c) 2011, Markus Peloquin <markus@cs.wisc.edu>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <iostream>
#include <memory>
#include <cuetools/cuefile.h>
#include <unicode/utf8.h>
#include "transcode.hpp"
flacsplit::Music_info::Music_info() :
_parent(nullptr),
_track(0)
{}
std::shared_ptr<flacsplit::Music_info>
flacsplit::Music_info::create_hidden(const Music_info &parent) {
auto info = std::shared_ptr<Music_info>();
info->_parent = &parent;
info->_title = "[hidden]";
return info;
}
flacsplit::Music_info::Music_info(const Cdtext *cdtext0) :
_parent(nullptr),
_track(0)
{
Cdtext *cdtext = const_cast<Cdtext *>(cdtext0);
const char *album = cdtext_get(PTI_TITLE, cdtext);
if (album) _title = iso8859_to_utf8(album);
const char *artist = cdtext_get(PTI_PERFORMER, cdtext);
if (artist) _artist = iso8859_to_utf8(artist);
const char *genre = cdtext_get(PTI_GENRE, cdtext);
if (genre) _genre = iso8859_to_utf8(genre);
}
flacsplit::Music_info::Music_info(const Cdtext *cdtext0,
const Music_info &parent, uint8_t track) :
_parent(&parent),
_track(track)
{
Cdtext *cdtext = const_cast<Cdtext *>(cdtext0);
const char *artist_cstr = cdtext_get(PTI_PERFORMER, cdtext);
if (artist_cstr) {
std::string artist = iso8859_to_utf8(artist_cstr);
if (artist != parent._artist) _artist = artist;
}
const char *genre_cstr = cdtext_get(PTI_GENRE, cdtext);
if (genre_cstr) {
std::string genre = iso8859_to_utf8(genre_cstr);
if (genre != parent._genre) _genre = genre;
}
const char *title = cdtext_get(PTI_TITLE, cdtext);
if (title) _title = iso8859_to_utf8(title);
}
std::string
flacsplit::iso8859_to_utf8(const std::string &str) {
const char *s = str.c_str();
int32_t length = str.size();
int32_t i = 0;
bool iso8859_1 = false;
while (i < length) {
int32_t c;
U8_NEXT(s, i, length, c);
if (c < 0) {
iso8859_1 = true;
break;
}
}
if (!iso8859_1)
return str;
// maximum bytes needed is 2 (+1 for null, so 3); U8_APPEND_UNSAFE
// needs 4 bytes in the worst case, so 4 is used to avoid warnings
std::string res;
char buf[4];
for (i = 0; i < length; i++) {
// encode single character
size_t len = 0;
// c must be unsigned; conversion to unsigned always defined
uint32_t c = static_cast<uint8_t>(str[i]);
U8_APPEND_UNSAFE(buf, len, c);
buf[len] = '\0';
res += buf;
}
return res;
}