views:

97

answers:

2

i'm trying to read ID3 frames and their values with TagLib (1) and index them with CLucene (2). the former returns frame ID's as std::vector<char> (3) and the latter writes field names as tchar* [wchar_t* in Linux] (4). i need to make a link between the two. how can i convert from std::vector<char> to wchar_t* by means of the STL? thank you

(1)http://developer.kde.org/~wheeler/taglib.html
(2)http://clucene.sourceforge.net/
(3)http://developer.kde.org/~wheeler/taglib/api/classTagLib_1_1ID3v2_1_1Frame.html#6aac53ec5893fd15164cd22c6bdb5dfd
(4)http://ohnopublishing.net/doc/clucene-0.9.21b/html/classlucene_1_1document_1_1Field.html#59b0082e2ade8c78a51a64fe99e684b2

+1  A: 

In a simple case where your chars don't contain any accented characters or anything like that, you can just copy each one to the destination and use it:

std::vector<char> frameID;

std::vector<wchar_t> field_name;

std::copy(frameID.begin(), frameID.end(), std::back_inserter(field_name));

lucene_write_field(&field_name[0], field_name.length());

My guess is that for ID3 frame ID's you don't have accented characters and such, so that'll probably be all you need. If you do have a possibility of accented characters and such, things get more complex in a hurry -- you'll need to convert from something like ISO 8859-x to (probably) UTF-16 Unicode. To do that, you need a code-page that tells you how to interpret the input (i.e., there are several varieties of ISO 8859, and one for French input will be different from one for Russian, for example).

Jerry Coffin
You can use a constructor of `std::vector` to avoid `std::copy`, like: `std::vector<wchar_t> field_name(frameID.begin(), frameID.end());` Just a bit more concise.
GMan
This can result in undesired behavior on systems with signed char. The problem being that the static cast that will be applied during the copy operation will turn char values > max before going negative into negative wchar_t values, not bitwise copies as is probably desired.
Noah Roberts
>"your chars don't contain any accented characters or anything like that"actually, they do. i'm from Russia, so i do have Russian songs ;-)
theorist
to make things worse, i have French and German songs as well ...
theorist
The frame ID is a 4-character sequence to say what's in the frame (e.g. "TIT2" or something for the song title). It can only contain the characters "A-Z" and "0-9", so there's no need to deal with non-ASCII characters. The frame data may be encoded as Latin-1 or Unicode; TagLib has a `String` class to deal with that.
Mike Seymour
"there's no need to deal with non-ASCII characters" yes, you're right
theorist
A: 

In order to prevent large char values from becoming negative wchar_t values you need to make sure that you cast to unsigned. This works though I believe it's technically undefined:

unsigned char* uchar = reinterpret_cast<unsigned char*>(&vect[0]);

std::vector<wchar_t> vwchar(uchar, uchar + vect.size());

This is important if your text contains anything above 127 in the character set.

Also keep in mind that none of these answer correctly deal with UTF-anything.

Noah Roberts
In this case, you don't need to deal with non-ASCII characters. Frame IDs only contain the characters "A-Z" and "0-9".
Mike Seymour