mirror of
https://github.com/taglib/taglib.git
synced 2025-06-04 01:28:21 -04:00
Use Unicode filenames on Windows (this time the correct patch).
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@734975 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
parent
7b0c053359
commit
bb438484da
@ -59,7 +59,7 @@ FileRef::FileRef()
|
||||
d = new FileRefPrivate(0);
|
||||
}
|
||||
|
||||
FileRef::FileRef(const char *fileName, bool readAudioProperties,
|
||||
FileRef::FileRef(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
d = new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle));
|
||||
@ -150,7 +150,7 @@ bool FileRef::operator!=(const FileRef &ref) const
|
||||
return ref.d->file != d->file;
|
||||
}
|
||||
|
||||
File *FileRef::create(const char *fileName, bool readAudioProperties,
|
||||
File *FileRef::create(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle) // static
|
||||
{
|
||||
|
||||
@ -164,7 +164,15 @@ File *FileRef::create(const char *fileName, bool readAudioProperties,
|
||||
|
||||
// Ok, this is really dumb for now, but it works for testing.
|
||||
|
||||
String s = fileName;
|
||||
String s;
|
||||
#ifdef _WIN32
|
||||
if((const wchar_t *)fileName)
|
||||
s = (const wchar_t *)fileName;
|
||||
else
|
||||
s = (const char *)fileName;
|
||||
#else
|
||||
s = fileName;
|
||||
#endif
|
||||
|
||||
// If this list is updated, the method defaultFileExtensions() should also be
|
||||
// updated. However at some point that list should be created at the same time
|
||||
|
@ -26,6 +26,7 @@
|
||||
#ifndef TAGLIB_FILEREF_H
|
||||
#define TAGLIB_FILEREF_H
|
||||
|
||||
#include <tfile.h>
|
||||
#include <tstringlist.h>
|
||||
|
||||
#include "taglib_export.h"
|
||||
@ -33,8 +34,6 @@
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class File;
|
||||
class Tag;
|
||||
|
||||
//! This class provides a simple abstraction for creating and handling files
|
||||
@ -105,7 +104,7 @@ namespace TagLib {
|
||||
* deleted. Deletion will happen automatically when the FileRef passes
|
||||
* out of scope.
|
||||
*/
|
||||
virtual File *createFile(const char *fileName,
|
||||
virtual File *createFile(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle
|
||||
audioPropertiesStyle = AudioProperties::Average) const = 0;
|
||||
@ -125,7 +124,7 @@ namespace TagLib {
|
||||
* Also see the note in the class documentation about why you may not want to
|
||||
* use this method in your application.
|
||||
*/
|
||||
explicit FileRef(const char *fileName,
|
||||
explicit FileRef(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle
|
||||
audioPropertiesStyle = AudioProperties::Average);
|
||||
@ -248,7 +247,7 @@ namespace TagLib {
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
static File *create(const char *fileName,
|
||||
static File *create(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle = AudioProperties::Average);
|
||||
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FLAC::File::File(const char *file, bool readProperties,
|
||||
FLAC::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file)
|
||||
{
|
||||
@ -110,7 +110,7 @@ FLAC::File::File(const char *file, bool readProperties,
|
||||
read(readProperties, propertiesStyle);
|
||||
}
|
||||
|
||||
FLAC::File::File(const char *file, ID3v2::FrameFactory *frameFactory,
|
||||
FLAC::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
bool readProperties, Properties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file)
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ namespace TagLib {
|
||||
* \deprecated This constructor will be dropped in favor of the one below
|
||||
* in a future version.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
@ -84,7 +84,7 @@ namespace TagLib {
|
||||
* \a frameFactory.
|
||||
*/
|
||||
// BIC: merge with the above constructor
|
||||
File(const char *file, ID3v2::FrameFactory *frameFactory,
|
||||
File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPC::File::File(const char *file, bool readProperties,
|
||||
MPC::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
|
@ -85,7 +85,7 @@ namespace TagLib {
|
||||
* file's audio properties will also be read using \a propertiesStyle. If
|
||||
* false, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
|
@ -71,7 +71,7 @@ TagLib::uint Frame::headerSize(uint version)
|
||||
ByteVector Frame::textDelimiter(String::Type t)
|
||||
{
|
||||
ByteVector d = char(0);
|
||||
if(t == String::UTF16 || t == String::UTF16BE)
|
||||
if(t == String::UTF16 || t == String::UTF16BE || t == String::UTF16LE)
|
||||
d.append(char(0));
|
||||
return d;
|
||||
}
|
||||
|
@ -51,17 +51,17 @@ namespace TagLib {
|
||||
* <a href="id3v2-structure.html#6.2">6.2</a>). The default \a length of
|
||||
* 4 is used if another value is not specified.
|
||||
*/
|
||||
uint toUInt(const ByteVector &data);
|
||||
TAGLIB_EXPORT uint toUInt(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Returns a 4 byte (32 bit) synchsafe integer based on \a value.
|
||||
*/
|
||||
ByteVector fromUInt(uint value);
|
||||
TAGLIB_EXPORT ByteVector fromUInt(uint value);
|
||||
|
||||
/*!
|
||||
* Deunsynchronize the data (in-place).
|
||||
*/
|
||||
void decode(ByteVector &data);
|
||||
TAGLIB_EXPORT void decode(ByteVector &data);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPEG::File::File(const char *file, bool readProperties,
|
||||
MPEG::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
@ -235,7 +235,7 @@ MPEG::File::File(const char *file, bool readProperties,
|
||||
}
|
||||
}
|
||||
|
||||
MPEG::File::File(const char *file, ID3v2::FrameFactory *frameFactory,
|
||||
MPEG::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
bool readProperties, Properties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file)
|
||||
{
|
||||
|
@ -77,7 +77,7 @@ namespace TagLib {
|
||||
* \deprecated This constructor will be dropped in favor of the one below
|
||||
* in a future version.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
@ -87,7 +87,7 @@ namespace TagLib {
|
||||
* \a frameFactory.
|
||||
*/
|
||||
// BIC: merge with the above constructor
|
||||
File(const char *file, ID3v2::FrameFactory *frameFactory,
|
||||
File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
|
@ -68,7 +68,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Ogg::FLAC::File::File(const char *file, bool readProperties,
|
||||
Ogg::FLAC::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : Ogg::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
|
@ -68,7 +68,7 @@ namespace TagLib {
|
||||
* the file's audio properties will also be read using \a propertiesStyle.
|
||||
* If false, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
|
@ -208,7 +208,7 @@ bool Ogg::File::save()
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Ogg::File::File(const char *file) : TagLib::File(file)
|
||||
Ogg::File::File(FileName file) : TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ namespace TagLib {
|
||||
* instantiated directly but rather should be used through the codec
|
||||
* specific subclasses.
|
||||
*/
|
||||
File(const char *file);
|
||||
File(FileName file);
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
|
@ -61,7 +61,7 @@ namespace TagLib {
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Vorbis::File::File(const char *file, bool readProperties,
|
||||
Vorbis::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : Ogg::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
|
@ -67,7 +67,7 @@ namespace TagLib {
|
||||
* file's audio properties will also be read using \a propertiesStyle. If
|
||||
* false, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
# include <wchar.h>
|
||||
# include <windows.h>
|
||||
# include <io.h>
|
||||
# define ftruncate _chsize
|
||||
#else
|
||||
@ -50,7 +52,7 @@ using namespace TagLib;
|
||||
class File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate(const char *fileName) :
|
||||
FilePrivate(FileName fileName) :
|
||||
file(0),
|
||||
name(fileName),
|
||||
readOnly(true),
|
||||
@ -60,37 +62,96 @@ public:
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
free((void *)((const char *)name));
|
||||
free((void *)((const wchar_t *)name));
|
||||
#else
|
||||
free((void *)name);
|
||||
#endif
|
||||
}
|
||||
|
||||
void openFile(const char *file, bool printError = true);
|
||||
#ifdef _WIN32
|
||||
void openFile(const wchar_t *file);
|
||||
#endif
|
||||
|
||||
FILE *file;
|
||||
const char *name;
|
||||
FileName name;
|
||||
bool readOnly;
|
||||
bool valid;
|
||||
ulong size;
|
||||
static const uint bufferSize = 1024;
|
||||
};
|
||||
|
||||
void File::FilePrivate::openFile(const char *name, bool printError)
|
||||
{
|
||||
// First try with read/write mode, if that fails, fall back to read only.
|
||||
// We can't use ::access() since that works in odd ways on some file systems.
|
||||
|
||||
file = fopen(name, "rb+");
|
||||
|
||||
if(file)
|
||||
readOnly = false;
|
||||
else
|
||||
file = fopen(name, "rb");
|
||||
|
||||
if(!file && printError)
|
||||
debug("Could not open file " + String(name));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
void File::FilePrivate::openFile(const wchar_t *name)
|
||||
{
|
||||
// Windows NT/2000/XP/Vista
|
||||
|
||||
if(GetVersion() < 0x80000000) {
|
||||
file = _wfopen(name, L"rb+");
|
||||
if(file)
|
||||
readOnly = false;
|
||||
else
|
||||
file = _wfopen(name, L"rb");
|
||||
}
|
||||
|
||||
// Windows 9x/ME
|
||||
|
||||
else {
|
||||
size_t length = wcslen(name) + 1;
|
||||
char *tmpname = (char *)malloc(length);
|
||||
if(tmpname) {
|
||||
if(WideCharToMultiByte(CP_ACP, 0, name, -1, tmpname, length, NULL, NULL))
|
||||
openFile(tmpname, false);
|
||||
free(tmpname);
|
||||
}
|
||||
}
|
||||
|
||||
if(!file)
|
||||
debug("Could not open file " + String(name));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
File::File(const char *file)
|
||||
File::File(FileName file)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
const char *name = (const char *)file;
|
||||
const wchar_t *wname = (const wchar_t *)file;
|
||||
if(wname) {
|
||||
d = new FilePrivate(::_wcsdup(wname));
|
||||
d->openFile(wname);
|
||||
}
|
||||
else {
|
||||
d = new FilePrivate(::strdup(name));
|
||||
d->openFile(name);
|
||||
}
|
||||
#else
|
||||
d = new FilePrivate(::strdup(file));
|
||||
|
||||
// First try with read/write mode, if that fails, fall back to read only.
|
||||
// We can't use ::access() since that works in odd ways on some file systems.
|
||||
|
||||
d->file = fopen(file, "rb+");
|
||||
|
||||
if(d->file)
|
||||
d->readOnly = false;
|
||||
else
|
||||
d->file = fopen(file,"rb");
|
||||
|
||||
if(!d->file)
|
||||
debug("Could not open file " + String(file));
|
||||
d->openFile(d->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
File::~File()
|
||||
@ -100,7 +161,7 @@ File::~File()
|
||||
delete d;
|
||||
}
|
||||
|
||||
const char *File::name() const
|
||||
FileName File::name() const
|
||||
{
|
||||
return d->name;
|
||||
}
|
||||
|
@ -36,6 +36,23 @@ namespace TagLib {
|
||||
class Tag;
|
||||
class AudioProperties;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
class TAGLIB_EXPORT FileName
|
||||
{
|
||||
public:
|
||||
FileName(const wchar_t *name) : name(0), wname(name) {}
|
||||
FileName(const char *name) : name(name), wname(0) {}
|
||||
operator const wchar_t *() { return wname; }
|
||||
operator const char *() { return name; }
|
||||
protected:
|
||||
const char *name;
|
||||
const wchar_t *wname;
|
||||
};
|
||||
#else
|
||||
typedef const char *FileName;
|
||||
#endif
|
||||
|
||||
//! A file class with some useful methods for tag manipulation
|
||||
|
||||
/*!
|
||||
@ -67,7 +84,7 @@ namespace TagLib {
|
||||
/*!
|
||||
* Returns the file name in the local file system encoding.
|
||||
*/
|
||||
const char *name() const;
|
||||
FileName name() const;
|
||||
|
||||
/*!
|
||||
* Returns a pointer to this file's tag. This should be reimplemented in
|
||||
@ -223,7 +240,7 @@ namespace TagLib {
|
||||
* \note Constructor is protected since this class should only be
|
||||
* instantiated through subclasses.
|
||||
*/
|
||||
File(const char *file);
|
||||
File(FileName file);
|
||||
|
||||
/*!
|
||||
* Marks the file as valid or invalid.
|
||||
|
@ -86,7 +86,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WavPack::File::File(const char *file, bool readProperties,
|
||||
WavPack::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
|
@ -84,7 +84,7 @@ namespace TagLib {
|
||||
* file's audio properties will also be read using \a propertiesStyle. If
|
||||
* false, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(const char *file, bool readProperties = true,
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
|
Loading…
x
Reference in New Issue
Block a user