Skip to content

Commit

Permalink
add support for POPM frames (see issue #9)
Browse files Browse the repository at this point in the history
  • Loading branch information
squell committed Jun 5, 2017
1 parent 517b38a commit 8d611a3
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 8 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Changelog for 'id3'.
2017-156 (W23):
id3-imges.c: prefix filenames of extract images with the path of the mp3
file they orginated from ("file.mp3:cover.jp3")
[gs]etid3v2.h: add support for POPM frames; referenced as POPM:email,
using the syntax <rating>[:playcounter]

2017-121 (W18):
fileexp.cpp: [bugfix] files with [] in them were not being found
Expand Down
17 changes: 13 additions & 4 deletions getid3v2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,20 @@ extern ID3v2::value_string tag::unbinarize(ID3FRAME f, charset::conv<>& descript
return ID3v2::value_string(cs("<compressed or encrypted>"),0);

if(ID3v2::is_counter(field)) {
const char* data = f->data;
if(ID3v2::has_desc(field)) {
if(!(data = membrk0(data, f->size, 0))) return conv<>();
descriptor = conv<charset::latin1>(":") += conv<charset::latin1>(f->data, data - f->data);
data += 2; // data[-1] points to rating
}
char buf[12]; // enough for 32bits
unsigned long t = 0;
for(size_t n = 0; n < f->size; ++n)
t = t << 8 | (f->data[n] & 0xFF);
sprintf(buf, "%lu", t & 0xFFFFFFFFul);
for(size_t n = 0; n < f->size - (data - f->data); ++n)
t = t << 8 | (data[n] & 0xFF);
if(ID3v2::has_desc(field)) {
sprintf(buf, "%u:%lu", data[-1]&0xFFu, t & 0xFFFFFFFFul);
} else
sprintf(buf, "%lu", t & 0xFFFFFFFFul);
return conv<latin1>(buf);
}

Expand All @@ -160,7 +169,7 @@ extern ID3v2::value_string tag::unbinarize(ID3FRAME f, charset::conv<>& descript
p += 3; // skip-ignore language field
}
if(ID3v2::has_desc(field)) {
const char *q = membrk0(p, f->size - (p - f->data), wide);
const char* q = membrk0(p, f->size - (p - f->data), wide);
if(!q) return conv<>(); // malformed frame
descriptor = conv<charset::latin1>(":");
switch(*f->data) {
Expand Down
6 changes: 4 additions & 2 deletions getid3v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ namespace tag {
{ return field == "TXXX" || field == "TXX" ||
field == "WXXX" || field == "WXX" ||
field == "COMM" || field == "COM" ||
field == "USLT" || field == "ULT"; }
field == "USLT" || field == "ULT" ||
field == "POPM" || field == "POP"; }

static bool is_counter(const std::string field)
{ return field == "PCNT" || field == "CNT"; }
{ return field == "PCNT" || field == "CNT" ||
field == "POPM" || field == "POP"; }

static bool is_url(const std::string field)
{ return field[0] == 'W'; }
Expand Down
3 changes: 2 additions & 1 deletion id3.man
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ W??/W??? (links),
COM/COMM (comment),
IPL/IPLS (involved people),
ULT/USLT (lyrics),
CNT/PCNT (numeric play counter) and
CNT/PCNT (numeric play counter),
POP/POPM (popularimeter) and
USER (tos, v2.3 only).
Attempts to write ID3v2.2 frames to ID3v2.3 or vice versa will be ignored.

Expand Down
9 changes: 8 additions & 1 deletion setid3v2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,14 @@ static const string binarize(string field, charset::conv<charset::latin1> conten
if(!ID3v2::is_valid(field))
return data;
if(ID3v2::is_counter(field)) {
unsigned long t = strtoul(string(content).c_str(), 0, 0);
string s = content;
unsigned long t = strtoul(s.c_str(), 0, 0);
if(ID3v2::has_desc(field)) {
data.append(encode(0,descr));
data.push_back(t&0xFFu);
string::size_type i = s.find(':');
t = i==string::npos? 0 : strtoul(s.substr(i+1).c_str(), 0, 0);
}
data.push_back(t >> 24 & 0xFF);
data.push_back(t >> 16 & 0xFF);
data.push_back(t >> 8 & 0xFF);
Expand Down

0 comments on commit 8d611a3

Please sign in to comment.