Skip to content

Commit

Permalink
Update class comments to be mutable.
Browse files Browse the repository at this point in the history
  • Loading branch information
sp1ff committed Jan 28, 2024
1 parent 9667a18 commit 6bf2f9d
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 41 deletions.
2 changes: 1 addition & 1 deletion doc/version.texi
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
@set UPDATED 25 January 2024
@set UPDATED 27 January 2024
@set UPDATED-MONTH January 2024
@set EDITION 0.6.23
@set VERSION 0.6.23
20 changes: 18 additions & 2 deletions scribbu/charsets.cc
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ namespace scribbu {
srcenc, dstenc, rsp);
}

/// Convert encodings from C strings to buffers of unsigned char
/// Convert encodings from C strings to buffers of unsigned char
template <>
std::vector<unsigned char>
convert_encoding(char const* const& text,
Expand Down Expand Up @@ -800,6 +800,22 @@ namespace scribbu {
const unsigned char *pbom = nullptr;
if (add_bom) {
switch (dstenc) {
case encoding::UCS_2:
cbbom = 2;
if constexpr (std::endian::native == std::endian::big) {
pbom = UTF16BE;
} else {
pbom = UTF16LE;
}
break;
case encoding::UCS_4:
cbbom = 4;
if constexpr (std::endian::native == std::endian::big) {
pbom = UTF32BE;
} else {
pbom = UTF32LE;
}
break;
case encoding::UCS_2BE:
case encoding::UTF_16BE:
cbbom = 2;
Expand Down Expand Up @@ -840,7 +856,7 @@ namespace scribbu {
// http://stackoverflow.com/questions/13297458/simple-utf8-utf16-string-conversion-with-iconv
std::size_t cbout = cbbom + (ntext << 2);
vector<unsigned char> out(cbout);
std::size_t outbytesleft = cbout;
std::size_t outbytesleft = cbout - cbbom;
char *outbuf = reinterpret_cast<char*>(&(out[cbbom]));
size_t status = iconv(dsc, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
while (~0 == status && E2BIG == errno) {
Expand Down
6 changes: 3 additions & 3 deletions scribbu/csv-pprinter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ scribbu::csv_pprinter::pprint_COM(const COM &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1],lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
escape(f.description<string>(dst, rsp, v2enc_)) << sep_ <<
Expand Down Expand Up @@ -500,7 +500,7 @@ scribbu::csv_pprinter::pprint_COMM(const COMM &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1],lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
escape(f.description<string>(dst, rsp, v2enc_)) << sep_ <<
Expand Down Expand Up @@ -664,7 +664,7 @@ scribbu::csv_pprinter::pprint_COMM_2_4(const COMM_2_4 &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
escape(f.description<string>(dst, rsp, v2enc_)) << sep_ <<
Expand Down
44 changes: 39 additions & 5 deletions scribbu/framesv2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,22 @@ scribbu::unknown_text_frame::what() const noexcept(true)
return pwhat_->c_str();
}

///////////////////////////////////////////////////////////////////////////////
// class bad_unicode_value //
///////////////////////////////////////////////////////////////////////////////

/*virtual*/ const char *
scribbu::bad_unicode_value::what() const noexcept(true)
{
// lazily format
if ( ! pwhat_ ) {
std::stringstream stm;
stm << "Unknown value for the Unicode byte: " << b_;
pwhat_.reset(new std::string(stm.str()));
}
return pwhat_->c_str();
}

///////////////////////////////////////////////////////////////////////////////
// class frame_id3 //
///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -920,13 +936,13 @@ scribbu::comments::comments(id3v2_version ver,
cbnil_ = 1;
break;
case use_unicode::yes:
unicode_ = 4;
unicode_ = 3;
dst = encoding::UTF_8;
add_bom = false;
cbnil_ = 1;
break;
case use_unicode::with_bom:
unicode_ = 4;
unicode_ = 3;
dst = encoding::UTF_8;
add_bom = true;
cbnil_ = 1;
Expand All @@ -941,6 +957,18 @@ scribbu::comments::comments(id3v2_version ver,

}

void
scribbu::comments::description(const std::string &text, encoding src)
{
description_ = convert_encoding(text, src, dst_enc_, add_bom());
}

void
scribbu::comments::text(const std::string &text, encoding src)
{
text_ = convert_encoding(text, src, dst_enc_, add_bom());
}

std::size_t
scribbu::comments::size() const
{
Expand Down Expand Up @@ -1029,6 +1057,15 @@ scribbu::comments::count_syncs(bool false_only) const
return cb;
}

bool
scribbu::comments::add_bom() const
{
return (id3v2_version::v2 == ver_ && encoding::UCS_2 == dst_enc_) ||
(id3v2_version::v3 == ver_ && encoding::UCS_2 == dst_enc_) ||
(id3v2_version::v4 == ver_ && encoding::UTF_16 == dst_enc_);

}


///////////////////////////////////////////////////////////////////////////////
// class play_count //
Expand Down Expand Up @@ -1521,6 +1558,3 @@ scribbu::tag_cloud::parse_to_map(const std::string &text,
}

}



70 changes: 64 additions & 6 deletions scribbu/framesv2.hh
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,19 @@ namespace scribbu {
mutable std::shared_ptr<std::string> pwhat_;
};

/// Thrown on a bad "unicode" byte
class bad_unicode_value : public error
{
public:
bad_unicode_value(unsigned char b) : b_(b)
{ }
virtual const char * what() const noexcept(true);
unsigned char bad_value() const
{ return b_; }
private:
unsigned char b_;
mutable std::shared_ptr<std::string> pwhat_;
};
/// ID3v2.2 identifier-- a simple UDT representing a three-character,
/// ASCII-encoded frame ID for use in hashed collections
class frame_id3
Expand Down Expand Up @@ -655,6 +668,13 @@ namespace scribbu {
* structure, and is meant to be combined into version-specific id3v2_frame
* sub-classes through multiple inheritence.
*
* It is regrettable that this class is implemented in terms of its on-disk
* format (the comment text & descriptions, for instance, are represented as
* vectors of unsigned char in the frame's target encoding). It would be
* preferrable to pick a general representation (UTF-8 strings, to continue
* to the example) and only worry about the on-disk frame representation at
* I/O time.
*
*
*/

Expand All @@ -668,11 +688,41 @@ namespace scribbu {
comments(id3v2_version ver,
forward_input_iterator p0,
forward_input_iterator p1):
ver_(ver),
cbnil_(1)
{
if (p0 != p1) {

unicode_ = *p0++;
if (id3v2_version::v2 == ver_ || id3v2_version::v3 == ver) {
switch (unicode_) {
case 0:
dst_enc_ = encoding::ISO_8859_1;
break;
case 1:
dst_enc_ = encoding::UCS_2;
break;
default:
throw bad_unicode_value(unicode_);
}
} else {
switch (unicode_) {
case 0:
dst_enc_ = encoding::ISO_8859_1;
break;
case 1:
dst_enc_ = encoding::UTF_16;
break;
case 2:
dst_enc_ = encoding::UTF_16BE;
break;
case 3:
dst_enc_ = encoding::UTF_8;
break;
default:
throw bad_unicode_value(unicode_);
}
}

if (id3v2_version::v2 == ver || id3v2_version::v3 == ver) {
cbnil_ = unicode_ ? 2 : 1;
Expand Down Expand Up @@ -715,12 +765,10 @@ namespace scribbu {
return unicode_;
}

template <typename forward_output_iterator>
forward_output_iterator lang(forward_output_iterator p) const {
*p++ = lang_[0];
*p++ = lang_[1];
*p++ = lang_[2];
return p;
typedef std::tuple<unsigned char, unsigned char, unsigned char> lang_type;

lang_type lang() const {
return std::make_tuple(lang_[0], lang_[1], lang_[2]);
}

template <typename forward_output_iterator>
Expand All @@ -733,6 +781,11 @@ namespace scribbu {
return std::copy(text_.begin(), text_.end(), p);
}

/// Set the description
void description(const std::string &text, encoding src);
/// Set the commente text
void text(const std::string &text, encoding src);

/// Return the size, in bytes, of this structure, prior to
/// desynchronisation, compression, and/or encryption exclusive of the
/// header
Expand All @@ -742,9 +795,14 @@ namespace scribbu {
std::size_t write(std::ostream &os) const;

private:
/// Derive from our version & destination encoding whether we need to
/// ad a byte-order mark
bool add_bom() const;
std::size_t count_syncs(bool false_only) const;

private:
id3v2_version ver_;
encoding dst_enc_;
unsigned char cbnil_;
unsigned char unicode_;
unsigned char lang_[3];
Expand Down
4 changes: 2 additions & 2 deletions scribbu/pprinter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ std::string comment_lang(const scribbu::comments &frame) {

using namespace std;

char blang[4]{ 0, 0, 0, 0 };
frame.lang(blang);
char blang[4]{0, 0, 0, 0};
std::tie(blang[0], blang[1], blang[2]) = frame.lang();

stringstream stm(blang);
optional<scribbu::language> strict_lang;
Expand Down
6 changes: 3 additions & 3 deletions scribbu/scheme-serde.cc
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ namespace {
SCM x = init_frame("<comment-frame>", sym_comment_frame);

char lang[4] = { 0, 0, 0, 0 };
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();
if (0 != (lang[0] & 0x80)) lang[0] = 0;
if (0 != (lang[1] & 0x80)) lang[1] = 0;
if (0 != (lang[2] & 0x80)) lang[2] = 0;
Expand All @@ -454,7 +454,7 @@ namespace {
f.readonly());

char lang[4] = { 0, 0, 0, 0 };
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();
if (0 != (lang[0] & 0x80)) lang[0] = 0;
if (0 != (lang[1] & 0x80)) lang[1] = 0;
if (0 != (lang[2] & 0x80)) lang[2] = 0;
Expand All @@ -480,7 +480,7 @@ namespace {
f.readonly(), f.unsynchronised());

char lang[4] = { 0, 0, 0, 0 };
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();
if (0 != (lang[0] & 0x80)) lang[0] = 0;
if (0 != (lang[1] & 0x80)) lang[1] = 0;
if (0 != (lang[2] & 0x80)) lang[2] = 0;
Expand Down
6 changes: 3 additions & 3 deletions scribbu/tdf-pprinter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ scribbu::tdf_pprinter::pprint_COM(const COM &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
f.description<string>(dst, rsp, v2enc_) << sep_ <<
Expand Down Expand Up @@ -454,7 +454,7 @@ scribbu::tdf_pprinter::pprint_COMM(const COMM &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
f.description<string>(dst, rsp, v2enc_) << sep_ <<
Expand Down Expand Up @@ -620,7 +620,7 @@ scribbu::tdf_pprinter::pprint_COMM_2_4(const COMM_2_4 &f, std::ostream &os)
std::tie(dst, rsp) = encoding_from_stream(os);

char lang[3];
f.lang(lang);
std::tie(lang[0], lang[1], lang[2]) = f.lang();

return os << lang[0] << lang[1] << lang[2] << sep_ <<
f.description<string>(dst, rsp, v2enc_) << sep_ <<
Expand Down
Loading

0 comments on commit 6bf2f9d

Please sign in to comment.