diff --git a/src/taglib2.cc b/src/taglib2.cc index ea0e0d0..dd3f551 100644 --- a/src/taglib2.cc +++ b/src/taglib2.cc @@ -37,6 +37,15 @@ using namespace std; using namespace v8; using namespace node; +static std::wstring GetWString(v8::Handle str) +{ + uint16_t* buf = new uint16_t[str->Length()+1]; + str->Write(buf); + std::wstring value = reinterpret_cast(buf); + delete [] buf; + return value; +} + Local TagLibStringToString(TagLib::String s) { if (s.isEmpty()) return Nan::Null(); @@ -53,13 +62,9 @@ TagLib::String StringToTagLibString(std::string s) { return TagLib::String(s, TagLib::String::UTF8); } -bool isFile(const char *s) { - struct stat st; -#ifdef _WIN32 - return ::stat(s, &st) == 0 && (st.st_mode & (S_IFREG)); -#else - return ::stat(s, &st) == 0 && (st.st_mode & (S_IFREG | S_IFLNK)); -#endif +bool isFile(const wchar_t *fileName) { + std::ifstream infile(fileName); + return infile.good(); } NAN_METHOD(writeTagsSync) { @@ -79,7 +84,7 @@ NAN_METHOD(writeTagsSync) { if (!info[1]->IsObject()) return; options = v8::Local::Cast(info[1]); - std::string audio_file = *v8::String::Utf8Value(info[0]->ToString()); + std::wstring audio_file = GetWString(info[0]->ToString()); if (!isFile(audio_file.c_str())) { Nan::ThrowTypeError("Audio file not found"); @@ -120,47 +125,29 @@ NAN_METHOD(writeTagsSync) { return o->Get(Nan::New(name).ToLocalChecked())->Int32Value(); }; - if (hasOption(options, "albumartist")) { - hasProps = true; - TagLib::String value = getOptionString(options, "albumartist"); - map.erase(TagLib::String("ALBUMARTIST")); - map.insert(TagLib::String("ALBUMARTIST"), value); - } + string common_props[8] = {"artist", "title", "album", "comment", "genre", "year", "track", "pictures"}; - if (hasOption(options, "discnumber")) { - hasProps = true; - TagLib::String value = getOptionString(options, "discnumber"); - map.erase(TagLib::String("DISCNUMBER")); - map.insert(TagLib::String("DISCNUMBER"), value); - } + Local property_names = options->GetOwnPropertyNames(); + for (int i = 0; i < property_names->Length(); ++i) { + auto key = property_names->Get(Nan::New(i)); + std::string key_utf = *v8::String::Utf8Value(key); - if (hasOption(options, "tracknumber")) { - hasProps = true; - TagLib::String value = getOptionString(options, "tracknumber"); - map.erase(TagLib::String("TRACKNUMBER")); - map.insert(TagLib::String("TRACKNUMBER"), value); - } + bool isCommon = false; - if (hasOption(options, "composer")) { - hasProps = true; - TagLib::String value = getOptionString(options, "composer"); - map.erase(TagLib::String("COMPOSER")); - map.insert(TagLib::String("COMPOSER"), value); - } + for (int i = 0; i < 8; i++) { + if (key_utf.compare(common_props[i]) == 0) + isCommon = true; + } - if (hasOption(options, "id")) { - hasProps = true; - TagLib::String value = getOptionString(options, "id"); - map.erase(TagLib::String("ID")); - map.insert(TagLib::String("ID"), value); - } + if (!isCommon) { + hasProps = true; - if (hasOption(options, "bpm")) { - hasProps = true; - TagLib::String value = getOptionString(options, "bpm"); - map.erase(TagLib::String("BPM")); - map.insert(TagLib::String("BPM"), value); - } + TagLib::String value = getOptionString(options, key_utf); + + map.erase(TagLib::String(TagLib::String(key_utf).upper())); + map.insert(TagLib::String(TagLib::String(key_utf).upper()), value); + } + } if (hasProps) { f.setProperties(map); @@ -247,15 +234,15 @@ NAN_METHOD(writeTagsSync) { NAN_METHOD(readTagsSync) { Nan::HandleScope scope; - std::string audio_file = *v8::String::Utf8Value(info[0]->ToString()); + std::wstring audio_file = GetWString(info[0]->ToString()); if (!isFile(audio_file.c_str())) { Nan::ThrowTypeError("Audio file not found"); return; } - string ext; - const size_t pos = audio_file.find_last_of("."); + std::wstring ext; + const size_t pos = audio_file.find_last_of(L"."); if (pos != -1) { ext = audio_file.substr(pos + 1); @@ -373,7 +360,7 @@ NAN_METHOD(readTagsSync) { // file is not the greatest way to get the pictures for flac files. It seems // like this should be managed by the tag->pictures() method on FileRef, but // isn't, open to changes here. - if (audio_file.find(".flac") != std::string::npos) { + if (audio_file.find(L".flac") != std::wstring::npos) { TagLib::FLAC::File flacfile(audio_file.c_str()); TagLib::List list = flacfile.pictureList(); @@ -468,7 +455,7 @@ NAN_METHOD(readTagsSync) { // this is the same hackery, a second read, is required to get the codec // since codec isn't always a member of audioProperties. There should be // a better way of getting properties that are unique to each format. - if (ext == "M4A" || ext == "MP4") { + if (ext == L"M4A" || ext == L"MP4") { TagLib::MP4::File mp4file(audio_file.c_str()); if (mp4file.audioProperties()) { auto codec = mp4file.audioProperties()->codec();