#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
+
#ifdef _WIN32
# include <wchar.h>
# include <windows.h>
# include <io.h>
# define ftruncate _chsize
#else
- #include <unistd.h>
+# include <unistd.h>
#endif
+
#include <stdlib.h>
#ifndef R_OK
using namespace TagLib;
-class File::FilePrivate
-{
-public:
- FilePrivate(FileName fileName) :
- file(0),
- name(fileName),
- readOnly(true),
- valid(true),
- size(0)
- {}
-
- ~FilePrivate()
- {
#ifdef _WIN32
- free((void *)((const char *)name));
- free((void *)((const wchar_t *)name));
+
+typedef FileName FileNameHandle;
+
#else
- free((void *)name);
-#endif
- }
- void openFile(const char *file, bool printError = true);
-#ifdef _WIN32
- void openFile(const wchar_t *file);
+struct FileNameHandle : public std::string
+{
+ FileNameHandle(FileName name) : std::string(name) {}
+ operator FileName () const { return c_str(); }
+};
+
#endif
+class File::FilePrivate
+{
+public:
+ FilePrivate(FileName fileName);
+
FILE *file;
- FileName name;
+
+ FileNameHandle name;
+
bool readOnly;
bool valid;
ulong size;
static const uint bufferSize = 1024;
};
-void File::FilePrivate::openFile(const char *name, bool printError)
+File::FilePrivate::FilePrivate(FileName fileName) :
+ file(0),
+ name(fileName),
+ readOnly(true),
+ valid(true),
+ size(0)
{
- // 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.
+ // First try with read / write mode, if that fails, fall back to read only.
- file = fopen(name, "rb+");
+#ifdef _WIN32
+
+ file = _wfopen(name, L"rb+");
if(file)
readOnly = false;
else
- file = fopen(name, "rb");
+ file = _wfopen(name, L"rb");
- if(!file && printError)
- debug("Could not open file " + String(name));
-}
-
-#ifdef _WIN32
+ if(file)
+ return;
-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");
- }
+#endif
- // Windows 9x/ME
+ file = fopen(name, "rb+");
- 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)
+ readOnly = false;
+ else
+ file = fopen(name, "rb");
if(!file)
- debug("Could not open file " + String(name));
+ debug("Could not open file " + String((const char *) name));
}
-#endif
-
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
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));
- d->openFile(d->name);
-#endif
+ d = new FilePrivate(file);
}
File::~File()
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;
+ FileName(const wchar_t *name) : m_wname(name) {}
+ FileName(const char *name) : m_name(name) {}
+ operator const wchar_t *() const { return m_wname.c_str(); }
+ operator const char *() const { return m_name.c_str(); }
+ private:
+ std::string m_name;
+ std::wstring m_wname;
};
#else
typedef const char *FileName;