-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathid3.cpp
142 lines (118 loc) · 2.86 KB
/
id3.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
* Author: Floris Creyf
* Date: May 2015
* ID3 contains meta data irrelevant to the decoder. The header contains an
* offset used to determine the location of the first MP3 header.
* | Header | Additional header (optional) | Meta Data | Footer (optional) |
*/
#include <regex>
#include "util.h"
#include "id3.h"
id3::id3(unsigned char *buffer)
{
this->buffer = buffer;
if (buffer[0] == 'I' && buffer[1] == 'D' && buffer[2] == '3') {
set_version(buffer[3], buffer[4]);
if(set_flags(buffer[5])) {
valid = true;
set_offset(char_to_int(&buffer[6]));
set_extended_header_size(char_to_int(&buffer[10]));
set_fields(&buffer[10 + extended_header_size]);
} else
valid = false;
} else
valid = false;
}
id3::id3(const id3 &orig)
{
this->start = orig.start;
this->version = orig.version;
this->offset = orig.offset;
for (int i = 0; i < 4; i++)
this->id3_flags[i] = orig.id3_flags[i];
this->extended_header_size = orig.extended_header_size;
for (int i = 0; i < 2; i++)
this->id3_frames[i] = orig.id3_frames[i];
}
bool id3::is_valid()
{
return valid;
}
void id3::set_version(unsigned char version, unsigned char revision)
{
char v[6];
sprintf(v, "2.%u.%u", version, revision);
this->version = (string)v;
}
string id3::get_id3_version()
{
return this->version;
}
void id3::set_offset(int offset)
{
this->offset = offset;
}
int id3::get_id3_offset()
{
return this->offset;
}
bool id3::set_flags(unsigned char flags)
{
/* These flags must be unset for the ID3 header to be valid. */
for (int bit_num = 0; bit_num < 4; bit_num++)
if (flags >> bit_num & 1)
return false;
for (int bit_num = 4; bit_num < 8; bit_num++)
if (flags >> bit_num & 1)
this->id3_flags[bit_num-4] = true;
else
this->id3_flags[bit_num-4] = false;
return true;
}
const bool *id3::get_id3_flags()
{
return this->id3_flags;
}
void id3::set_extended_header_size(int size)
{
if (this->id3_flags[ExtendedHeader] == 1)
this->extended_header_size = size;
else
this->extended_header_size = 0;
}
int id3::get_id3_extended_header_size()
{
return this->extended_header_size;
}
void id3::set_fields(unsigned char *buffer)
{
int footer_size = id3_flags[FooterPresent] * 10;
int size = offset - extended_header_size - footer_size;
int i = 0;
std::regex re("[A-Z0-9]");
string str(1, (char)buffer[i]);
while (!std::regex_match(str, re) && i < size) {
string id = "";
string content = "";
int field_size = 0;
for (int j = i; j < i + 4; j++)
id += buffer[j];
this->id3_frames[0].push_back(id);
i += 4;
field_size = char_to_int(&buffer[i]);
i += 6;
for (int j = i; j < field_size + i; j++)
content += buffer[j];
this->id3_frames[1].push_back(content);
i += field_size;
str = (char)buffer[i];
}
}
const vector<string> *id3::get_id3_fields()
{
return this->id3_frames;
}
unsigned int id3::get_id3_fields_length()
{
return this->id3_frames[1].size();
}