From a35ea9616410d7c7dc8320aadca215442d51554a Mon Sep 17 00:00:00 2001 From: tobigun Date: Thu, 23 Dec 2010 11:04:13 +0000 Subject: Path class implemented for full unicode support git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2770 b956fd51-792f-4845-bead-9b4dfca2ff2c --- mediaplugin/src/media/UMediaPlugin.pas | 77 ++++++++++++++++++++-- .../mediaplugins/ffmpeg/ffmpeg_audio_decode.cpp | 4 +- .../src/mediaplugins/ffmpeg/ffmpeg_audio_decode.h | 6 +- .../mediaplugins/ffmpeg/ffmpeg_video_decode.cpp | 4 +- .../src/mediaplugins/ffmpeg/ffmpeg_video_decode.h | 4 +- .../src/mediaplugins/include/core/plugin_core.h | 11 ++++ mediaplugin/src/mediaplugins/include/core/util.h | 46 ++++++++----- 7 files changed, 121 insertions(+), 31 deletions(-) (limited to 'mediaplugin') diff --git a/mediaplugin/src/media/UMediaPlugin.pas b/mediaplugin/src/media/UMediaPlugin.pas index 8d4a8a7e..dd5b0d6a 100644 --- a/mediaplugin/src/media/UMediaPlugin.pas +++ b/mediaplugin/src/media/UMediaPlugin.pas @@ -45,20 +45,30 @@ type PMutex = Pointer; PCond = Pointer; + PFilePath = PAnsiChar; + PMediaPluginCore = ^TMediaPluginCore; TMediaPluginCore = record version: cint; + memAlloc: function(size: cint): Pointer; cdecl; + memFree: procedure(ptr: Pointer); cdecl; + log: procedure(level: cint; msg: PAnsiChar; context: PAnsiChar); cdecl; ticksMillis: function(): cuint32; cdecl; - fileOpen: function(utf8Filename: PAnsiChar; mode: cint): PFileStream; cdecl; + fileOpen: function(utf8Filename: PFilePath; mode: cint): PFileStream; cdecl; fileClose: procedure(stream: PFileStream); cdecl; fileRead: function(stream: PFileStream; buf: PCuint8; size: cint): cint64; cdecl; fileWrite: function(stream: PFileStream; buf: PCuint8; size: cint): cint64; cdecl; fileSeek: function(stream: PFileStream; pos: cint64; whence: cint): cint64; cdecl; fileSize: function(stream: PFileStream): cint64; cdecl; + pathToNative: function(filePath: PFilePath): PChar; cdecl; + pathToUTF8: function(filePath: PFilePath; useNativeDelim: cbool): PChar; cdecl; + pathToWide: function(filePath: PFilePath; useNativeDelim: cbool): PWideChar; cdecl; + pathIsFile: function(filePath: PFilePath): cbool; cdecl; + threadCreate: function(func: Pointer; data: Pointer): PThread; cdecl; threadCurrentID: function(): cuint32; cdecl; threadGetID: function(thread: PThread): cuint32; cdecl; @@ -94,7 +104,7 @@ type priority: cint; init: function(): cbool; cdecl; finalize: function(): cbool; cdecl; - open: function(filename: PAnsiChar): PAudioDecodeStream; cdecl; + open: function(filename: PFilePath): PAudioDecodeStream; cdecl; close: procedure(stream: PAudioDecodeStream); cdecl; getLength: function(stream: PAudioDecodeStream): double; cdecl; getAudioFormatInfo: procedure(stream: PAudioDecodeStream; var info: TCAudioFormatInfo); cdecl; @@ -142,7 +152,7 @@ type priority: cint; init: function(): cbool; cdecl; finalize: function(): cbool; cdecl; - open: function(filename: PAnsiChar; format: TCVideoFrameFormat): PVideoDecodeStream; cdecl; + open: function(filename: PFilePath; format: TCVideoFrameFormat): PVideoDecodeStream; cdecl; close: procedure(stream: PVideoDecodeStream); cdecl; setLoop: procedure(stream: PVideoDecodeStream; enable: cbool); cdecl; getLoop: function(stream: PVideoDecodeStream): cbool; cdecl; @@ -183,6 +193,7 @@ uses UFilesystem, UPath, UPathUtils, + UUnicodeUtils, ULog, UPlatform, UAudioDecoderPlugin, @@ -217,6 +228,16 @@ end; {* Misc *} +function Core_memAlloc(size: cint): Pointer; cdecl; +begin + GetMem(Result, size); +end; + +procedure Core_memFree(ptr: Pointer); cdecl; +begin + FreeMem(ptr); +end; + procedure Core_log(level: cint; msg: PAnsiChar; context: PAnsiChar); cdecl; begin Log.LogMsg(msg, context, DebugLogLevels[level]); @@ -234,7 +255,7 @@ const FILE_OPEN_MODE_WRITE = $02; FILE_OPEN_MODE_READ_WRITE = FILE_OPEN_MODE_READ or FILE_OPEN_MODE_WRITE; -function Core_fileOpen(utf8Filename: PAnsiChar; mode: cint): PFileStream; cdecl; +function Core_fileOpen(utf8Filename: PFilePath; mode: cint): PFileStream; cdecl; var OpenMode: word; begin @@ -308,6 +329,48 @@ begin Result := FileStream.Size; end; +{* Path *} + +function Core_pathToNative(filePath: PFilePath): PChar; cdecl; +var + ResStr: RawByteString; +begin + ResStr := Path(filePath).ToNative(); + // RawByteString is reference-counted -> copy characters to a new buffer + GetMem(Result, Length(ResStr) + 1); + StrCopy(Result, PChar(ResStr)); +end; + +function Core_pathToUTF8(filePath: PFilePath; useNativeDelim: cbool): PChar; cdecl; +var + ResStr: UTF8String; + StrSize: integer; +begin + ResStr := Path(filePath).ToUTF8(useNativeDelim); + // UTF8String is reference-counted -> copy characters to a new buffer + GetMem(Result, Length(ResStr) + 1); + StrCopy(Result, PChar(ResStr)); +end; + +function Core_pathToWide(filePath: PFilePath; useNativeDelim: cbool): PWideChar; cdecl; +var + ResStr: WideString; + StrSize: integer; +begin + ResStr := Path(filePath).ToWide(useNativeDelim); + // WideString is reference-counted -> copy characters to a new buffer + StrSize := Length(ResStr) * SizeOf(WideChar); + GetMem(Result, StrSize + SizeOf(WideChar)); + Move(PWideChar(ResStr)^, Result, StrSize); + // terminate string + Result[Length(ResStr)] := #0; +end; + +function Core_pathIsFile(filePath: PFilePath): cbool; cdecl; +begin + Result := Path(filePath).IsFile; +end; + {* Thread *} function Core_threadCreate(func: Pointer; data: Pointer): PThread; cdecl; @@ -394,6 +457,8 @@ begin with MediaPluginCore_Instance do begin version := 0; + memAlloc := Core_memAlloc; + memFree := Core_memFree; log := Core_log; ticksMillis := Core_ticksMillis; fileOpen := Core_fileOpen; @@ -402,6 +467,10 @@ begin fileWrite := Core_fileWrite; fileSeek := Core_fileSeek; fileSize := Core_fileSize; + pathToNative := Core_pathToNative; + pathToUTF8 := Core_pathToUTF8; + pathToWide := Core_pathToWide; + pathIsFile := Core_pathIsFile; threadCreate := Core_threadCreate; threadCurrentID := Core_threadCurrentID; threadGetID := Core_threadGetID; diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.cpp b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.cpp index ce15f7a7..01dfdf1c 100644 --- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.cpp +++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.cpp @@ -80,7 +80,7 @@ FFmpegAudioDecodeStream::FFmpegAudioDecodeStream() : memset(&_audioPaketTemp, 0, sizeof(_audioPaketTemp)); } -FFmpegAudioDecodeStream* FFmpegAudioDecodeStream::open(const IPath &filename) { +FFmpegAudioDecodeStream* FFmpegAudioDecodeStream::open(const Path &filename) { FFmpegAudioDecodeStream *stream = new FFmpegAudioDecodeStream(); if (!stream->_open(filename)) { delete stream; @@ -89,7 +89,7 @@ FFmpegAudioDecodeStream* FFmpegAudioDecodeStream::open(const IPath &filename) { return stream; } -bool FFmpegAudioDecodeStream::_open(const IPath &filename) { +bool FFmpegAudioDecodeStream::_open(const Path &filename) { _filename = filename; if (!filename.isFile()) { logger.error("Audio-file does not exist: '" + filename.toNative() + "'", "UAudio_FFmpeg"); diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.h b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.h index c0d1b288..93711dc5 100644 --- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.h +++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_audio_decode.h @@ -87,7 +87,7 @@ private: int _audioBufferSize; DECLARE_ALIGNED(16, uint8_t, _audioBuffer[AUDIO_BUFFER_SIZE]); - IPath _filename; + Path _filename; private: FFmpegAudioDecodeStream(); @@ -119,7 +119,7 @@ private: int decodeFrame(uint8_t *buffer, int bufferSize); void flushCodecBuffers(); - bool _open(const IPath &filename); + bool _open(const Path &filename); void close(); public: @@ -127,7 +127,7 @@ public: close(); } - static FFmpegAudioDecodeStream* open(const IPath &filename); + static FFmpegAudioDecodeStream* open(const Path &filename); virtual double getLength(); diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp index ad34c7f3..4dbe6558 100644 --- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp +++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.cpp @@ -79,7 +79,7 @@ FFmpegVideoDecodeStream::FFmpegVideoDecodeStream() : _frameTime(0), _loopTime(0) {} -FFmpegVideoDecodeStream* FFmpegVideoDecodeStream::open(const IPath &filename, +FFmpegVideoDecodeStream* FFmpegVideoDecodeStream::open(const Path &filename, videoFrameFormat_t format) { FFmpegVideoDecodeStream *stream = new FFmpegVideoDecodeStream(); @@ -90,7 +90,7 @@ FFmpegVideoDecodeStream* FFmpegVideoDecodeStream::open(const IPath &filename, return stream; } -bool FFmpegVideoDecodeStream::_open(const IPath &filename, videoFrameFormat_t format) { +bool FFmpegVideoDecodeStream::_open(const Path &filename, videoFrameFormat_t format) { std::stringstream ss; // use custom 'ufile' protocol for UTF-8 support diff --git a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h index addf2a82..59a46267 100644 --- a/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h +++ b/mediaplugin/src/mediaplugins/ffmpeg/ffmpeg_video_decode.h @@ -71,7 +71,7 @@ private: bool decodeFrame(); void synchronizeTime(AVFrame *frame, double &pts); - bool _open(const IPath &filename, videoFrameFormat_t format); + bool _open(const Path &filename, videoFrameFormat_t format); void close(); public: @@ -79,7 +79,7 @@ public: close(); } - static FFmpegVideoDecodeStream* open(const IPath &filename, videoFrameFormat_t format); + static FFmpegVideoDecodeStream* open(const Path &filename, videoFrameFormat_t format); virtual void setLoop(bool enable); virtual bool getLoop(); diff --git a/mediaplugin/src/mediaplugins/include/core/plugin_core.h b/mediaplugin/src/mediaplugins/include/core/plugin_core.h index 69cc7f19..0979b992 100644 --- a/mediaplugin/src/mediaplugins/include/core/plugin_core.h +++ b/mediaplugin/src/mediaplugins/include/core/plugin_core.h @@ -111,6 +111,9 @@ typedef struct{} thread_t; typedef struct pluginCore_t { int version; + void* PLUGIN_CALL (*memAlloc)(int size); + void PLUGIN_CALL (*memFree)(void* ptr); + void PLUGIN_CALL (*log)(int level, const char *msg, const char *context); uint32_t PLUGIN_CALL (*ticksMillis)(); @@ -121,6 +124,14 @@ typedef struct pluginCore_t { int64_t PLUGIN_CALL (*fileSeek)(fileStream_t *stream, int64_t pos, int whence); int64_t PLUGIN_CALL (*fileSize)(fileStream_t *stream); + // Note: result string must be freed with memFree() + const char* PLUGIN_CALL (*pathToNative)(const char *path); + // Note: result string must be freed with memFree() + const char* PLUGIN_CALL (*pathToUTF8)(const char *path, BOOL useNativeDelim); + // Note: result string must be freed with memFree() + wchar_t* PLUGIN_CALL (*pathToWide)(const char *path, BOOL useNativeDelim); + BOOL PLUGIN_CALL (*pathIsFile)(const char *path); + thread_t* PLUGIN_CALL (*threadCreate)(int (PLUGIN_CALL *fn)(void *), void *data); uint32_t PLUGIN_CALL (*threadCurrentID)(); uint32_t PLUGIN_CALL (*threadGetID)(thread_t *thread); diff --git a/mediaplugin/src/mediaplugins/include/core/util.h b/mediaplugin/src/mediaplugins/include/core/util.h index ba7ae2a4..6b402774 100644 --- a/mediaplugin/src/mediaplugins/include/core/util.h +++ b/mediaplugin/src/mediaplugins/include/core/util.h @@ -99,35 +99,45 @@ public: //AudioFormatInfo copy(); }; -class IPath { +class Path { private: std::string _filename; public: - IPath(const char *filename) : - _filename(filename) - { - // TODO - } + Path(const char *filename) : + _filename(filename) {} - IPath(std::string filename) : - _filename(filename) - { - // TODO - } + Path(std::string filename) : + _filename(filename) {} std::string toNative() const { - // TODO - return _filename; + const char* cstr = pluginCore->pathToNative(_filename.c_str()); + std::string result(cstr); + pluginCore->memFree((void*)cstr); + return result; + } + + std::string toUTF8(bool useNativeDelim = true) const { + const char* cstr = pluginCore->pathToUTF8(_filename.c_str(), + useNativeDelim ? TRUE : FALSE); + std::string result(cstr); + pluginCore->memFree((void*)cstr); + return result; } - std::string toUTF8() const { - // TODO - return _filename; +// TODO: wchar_t sizes differ on Windows (2 byte)/Linux (4 byte). +// USDX uses the Pascal WideChar type which is 2 bytes in size. +#ifdef _WIN32 + std::wstring toWide(bool useNativeDelim = true) const { + const wchar_t* cstr = pluginCore->pathToWide(_filename.c_str(), + useNativeDelim ? TRUE : FALSE); + std::wstring result(cstr); + pluginCore->memFree((void*)cstr); + return result; } +#endif bool isFile() const { - // TODO - return true; + return pluginCore->pathIsFile(_filename.c_str()); } }; -- cgit v1.2.3