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:
Lukáš Lalinský 2007-11-10 16:06:16 +00:00
parent 7b0c053359
commit bb438484da
20 changed files with 134 additions and 49 deletions

View File

@ -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

View File

@ -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);

View File

@ -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)
{

View 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);

View File

@ -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;

View File

@ -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);
/*!

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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)
{

View 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);

View File

@ -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;

View File

@ -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);
/*!

View File

@ -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;
}

View File

@ -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 &);

View 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;

View File

@ -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);
/*!

View File

@ -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;
}

View File

@ -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.

View File

@ -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;

View File

@ -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);
/*!