Last active
June 26, 2023 12:55
-
-
Save tapetums/0a924712fb2fa0a7bb93 to your computer and use it in GitHub Desktop.
Susie プラグイン API 定義ファイル (C++11)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
//---------------------------------------------------------------------------// | |
// | |
// Susie.hpp | |
// Susie プラグイン API 定義ファイル (C++11) | |
// Copyright (C) 2013-2016 tapetums | |
// | |
//---------------------------------------------------------------------------// | |
// | |
// 下記を参考 : | |
// | |
// Susie Plug-in Programming Guide | |
// http://home.netyou.jp/cc/susumu/progSusie.html | |
// | |
// Susie Plug-in Specification Rev4+α on Win32 | |
// http://www2f.biglobe.ne.jp/~kana/spi_api/index.html | |
// | |
// TORO's Software library | |
// http://homepage1.nifty.com/toro/slplugin.html | |
// | |
// Susie Plug-inプログラミング | |
// http://www.asahi-net.or.jp/~kh4s-smz/spi/index.html | |
// | |
// DでSusieプラグインを使うためのクラス(リンク切れ): | |
// http://moephp.org/?D%B8%C0%B8%EC#content_1_13 | |
// | |
//---------------------------------------------------------------------------// | |
#include <cstdint> | |
#include <utility> | |
//---------------------------------------------------------------------------// | |
// | |
// 型宣言 | |
// | |
//---------------------------------------------------------------------------// | |
#if defined (_WIN32) || defined(WIN32) | |
#include <windows.h> | |
#else | |
#include <dlfcn.h> | |
struct HWND__; using HWND = HWND__*; | |
struct HINSTANCE__; using HINSTANCE = HINSTANCE__*; | |
using HMODULE = void*; | |
using LPSTR = char*; | |
using LPCSTR = const char*; | |
using LPWSTR = wchar_t*; | |
using LPCWSTR = const wchar_t*; | |
#if defined(_UNICODE) || defined(UNICODE) | |
using TCHAR = wchar_t; | |
using LPCTSTR = LPCWSTR; | |
#else | |
using TCHAR = char; | |
using LPCTSTR = LPCSTR; | |
#endif | |
#define WINAPI | |
#endif | |
//---------------------------------------------------------------------------// | |
// | |
// 定数 | |
// | |
//---------------------------------------------------------------------------// | |
// SusieFileInfo::path における最大要素数 | |
static constexpr size_t SPI_MAX_PATH { 200 }; | |
// IsSupported()関数へ渡すデータのサイズ | |
// 余白部分は <必ず> 0 で埋めること!! | |
static constexpr size_t SPI_TEST_BUF_SIZE { 2048 }; | |
// Susie plugin の 拡張子 | |
#if INTPTR_MAX == INT64_MAX | |
static constexpr auto SPI_EXT = TEXT(".sph"); | |
#elif INTPTR_MAX == INT32_MAX | |
static constexpr auto SPI_EXT = TEXT(".spi"); | |
#else | |
#error Susie.hpp : Unsupported Environment | |
#endif | |
//---------------------------------------------------------------------------// | |
// | |
// 列挙体 | |
// | |
//---------------------------------------------------------------------------// | |
// Susie エラーコード | |
enum SPI_RESULT : int32_t | |
{ | |
SPI_UNSUPPORTED = 0, // 非対応のファイル形式 | |
SPI_SUPPORTED = 1, // 対応可能なファイル形式 | |
SPI_NO_FUNCTION = -1, // その機能はインプリメントされていない | |
SPI_ALL_RIGHT = 0, // 正常終了 | |
SPI_E_ABORT = 1, // コールバック関数が非0を返したので展開を中止した | |
SPI_NOT_SUPPORT = 2, // 未知のフォーマット | |
SPI_OUT_OF_ORDER = 3, // データが壊れている | |
SPI_NO_MEMORY = 4, // メモリーが確保出来ない | |
SPI_MEMORY_ERROR = 5, // メモリーエラー | |
SPI_FILE_READ_ERROR = 6, // ファイルリードエラー | |
SPI_WINDOW_ERROR = 7, // 窓が開けない (非公開のエラーコード) | |
SPI_OTHER_ERROR = 8, // 内部エラー | |
SPI_FILE_WRITE_ERROR = 9, // 書き込みエラー (非公開のエラーコード) | |
SPI_END_OF_FILE = 10, // ファイル終端 (非公開のエラーコード) | |
}; | |
//---------------------------------------------------------------------------// | |
// Susie 追加情報フラグ | |
enum SPI_FLAG : uint32_t | |
{ | |
SPI_INPUT_FILE = 0, // 入力はディスクファイル | |
SPI_INPUT_MEMORY = 1, // 入力はメモリ上のイメージ | |
SPI_IGNORE_CASE = 1 << 7, // ファイル名の大文字小文字を同一視する | |
SPI_OUTPUT_FILE = 0, // 出力はディスクファイル | |
SPI_OUTPUT_MEMORY = 1 << 8, // 出力はメモリ上のイメージ | |
}; | |
//---------------------------------------------------------------------------// | |
// Susie 設定ダイアログ 機能コード | |
enum SPI_FNC_CODE : int32_t | |
{ | |
SPI_CONFIGDLG_ABOUT = 0, // About ダイアログを表示する | |
SPI_CONFIGDLG_SETTING = 1, // 設定ダイアログを表示する | |
SPI_CONFIGDLG_RESERVED = 2, // 予約済み | |
}; | |
//---------------------------------------------------------------------------// | |
// | |
// 時間型 | |
// | |
//---------------------------------------------------------------------------// | |
// Susie 独自の time_t 型 | |
#if INTPTR_MAX == INT64_MAX | |
using susie_time_t = int64_t; | |
#elif INTPTR_MAX == INT32_MAX | |
using susie_time_t = int32_t; | |
#else | |
#error Susie.hpp : Unsupported Environment | |
#endif | |
//---------------------------------------------------------------------------// | |
// | |
// 構造体 | |
// | |
//---------------------------------------------------------------------------// | |
#pragma pack(push, 1) | |
//---------------------------------------------------------------------------// | |
// Susie 画像情報 | |
struct SusiePictureInfo | |
{ | |
int32_t left; // 画像を展開する位置 | |
int32_t top; // 画像を展開する位置 | |
int32_t width; // 画像の幅(pixel) | |
int32_t height; // 画像の高さ(pixel) | |
uint16_t x_density; // 画素の水平方向密度 | |
uint16_t y_density; // 画素の垂直方向密度 | |
int16_t colorDepth; // 画素当たりのbit数 | |
#if INTPTR_MAX == INT64_MAX | |
uint8_t dummy[2]; // アラインメント | |
#endif | |
void* hInfo; // 画像内のテキスト情報 | |
}; | |
//---------------------------------------------------------------------------// | |
// Susie ファイル情報 (ANSI) | |
struct SusieFileInfoA | |
{ | |
uint8_t method[8]; // 圧縮法の種類 | |
size_t position; // ファイル上での位置 | |
size_t compsize; // 圧縮されたサイズ | |
size_t filesize; // 元のファイルサイズ | |
susie_time_t timestamp; // ファイルの更新日時 | |
char path[SPI_MAX_PATH]; // 相対パス | |
char filename[SPI_MAX_PATH]; // ファイルネーム | |
uint32_t crc; // CRC32 | |
#if INTPTR_MAX == INT64_MAX | |
uint8_t dummy[4]; // アラインメント | |
#endif | |
}; | |
//---------------------------------------------------------------------------// | |
// Susie ファイル情報 (Windows UNICODE) | |
struct SusieFileInfoW | |
{ | |
uint8_t method[8]; // 圧縮法の種類 | |
size_t position; // ファイル上での位置 | |
size_t compsize; // 圧縮されたサイズ | |
size_t filesize; // 元のファイルサイズ | |
susie_time_t timestamp; // ファイルの更新日時 | |
wchar_t path[SPI_MAX_PATH]; // 相対パス | |
wchar_t filename[SPI_MAX_PATH]; // ファイルネーム | |
uint32_t crc; // CRC32 | |
#if INTPTR_MAX == INT64_MAX | |
uint8_t dummy[4]; // アラインメント | |
#endif | |
}; | |
//---------------------------------------------------------------------------// | |
#pragma pack(pop) | |
//---------------------------------------------------------------------------// | |
// | |
// 関数ポインタ宣言 | |
// | |
//---------------------------------------------------------------------------// | |
#define SPI_FUNC SPI_RESULT (WINAPI *) | |
extern "C" | |
{ | |
// コールバック関数 | |
using SUSIE_PROGRESS = SPI_FUNC(int32_t nNum, int32_t nDenom, intptr_t lData); | |
// 共通関数 | |
using SPI_GetPluginInfoA = SPI_FUNC(int32_t, LPSTR, int32_t); | |
using SPI_GetPluginInfoW = SPI_FUNC(int32_t, LPWSTR, int32_t); | |
using SPI_IsSupportedA = SPI_FUNC(LPCSTR, uint8_t*); | |
using SPI_IsSupportedW = SPI_FUNC(LPCWSTR, uint8_t*); | |
// '00IN'の関数 | |
using SPI_GetPictureInfoA = SPI_FUNC(LPCSTR, size_t, SPI_FLAG, SusiePictureInfo*); | |
using SPI_GetPictureInfoW = SPI_FUNC(LPCWSTR, size_t, SPI_FLAG, SusiePictureInfo*); | |
using SPI_GetPictureA = SPI_FUNC(LPCSTR, size_t, SPI_FLAG, void**, void**, SUSIE_PROGRESS, intptr_t); | |
using SPI_GetPictureW = SPI_FUNC(LPCWSTR, size_t, SPI_FLAG, void**, void**, SUSIE_PROGRESS, intptr_t); | |
using SPI_GetPreviewA = SPI_FUNC(LPCSTR, size_t, SPI_FLAG, void**, void**, SUSIE_PROGRESS, intptr_t); | |
using SPI_GetPreviewW = SPI_FUNC(LPCWSTR, size_t, SPI_FLAG, void**, void**, SUSIE_PROGRESS, intptr_t); | |
// '00AM'の関数 | |
using SPI_GetArchiveInfoA = SPI_FUNC(LPCSTR, size_t, SPI_FLAG, HLOCAL*); | |
using SPI_GetArchiveInfoW = SPI_FUNC(LPCWSTR, size_t, SPI_FLAG, HLOCAL*); | |
using SPI_GetFileInfoA = SPI_FUNC(LPCSTR, size_t, LPCSTR, SPI_FLAG, SusieFileInfoA*); | |
using SPI_GetFileInfoW = SPI_FUNC(LPCWSTR, size_t, LPCWSTR, SPI_FLAG, SusieFileInfoW*); | |
using SPI_GetFileA = SPI_FUNC(LPCSTR, size_t, LPSTR, SPI_FLAG, SUSIE_PROGRESS, intptr_t); | |
using SPI_GetFileW = SPI_FUNC(LPCWSTR, size_t, LPWSTR, SPI_FLAG, SUSIE_PROGRESS, intptr_t); | |
// オプション関数(Susie v0.40 以降) | |
using SPI_ConfigurationDlg = SPI_FUNC(HWND, SPI_FNC_CODE); | |
// 拡張子で保存形式を決定 | |
using SPI_CreatePictureA = SPI_FUNC(LPCSTR, SPI_FLAG, void**, void**, SusiePictureInfo*, SUSIE_PROGRESS, intptr_t); | |
using SPI_CreatePictureW = SPI_FUNC(LPCWSTR, SPI_FLAG, void**, void**, SusiePictureInfo*, SUSIE_PROGRESS, intptr_t); | |
} | |
//---------------------------------------------------------------------------// | |
// | |
// Susie 外部公開関数 | |
// | |
//---------------------------------------------------------------------------// | |
#if defined (_WIN32) || defined(WIN32) | |
#define SUSIE_EXPORT extern "C" __declspec(dllexport) SPI_RESULT WINAPI | |
#else | |
#define SUSIE_EXPORT extern "C" SPI_RESULT | |
#endif | |
SUSIE_EXPORT GetPluginInfo (int32_t infono, LPSTR buf, int32_t buflen); | |
SUSIE_EXPORT GetPluginInfoW(int32_t infono, LPWSTR buf, int32_t buflen); | |
SUSIE_EXPORT IsSupported (LPCSTR filename, void* dw); | |
SUSIE_EXPORT IsSupportedW(LPCWSTR filename, void* dw); | |
SUSIE_EXPORT GetPictureInfo (LPCSTR buf, size_t len, SPI_FLAG flag, SusiePictureInfo* lpInfo); | |
SUSIE_EXPORT GetPictureInfoW(LPCWSTR buf, size_t len, SPI_FLAG flag, SusiePictureInfo* lpInfo); | |
SUSIE_EXPORT GetPicture (LPCSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT GetPictureW(LPCWSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT GetPreview (LPCSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT GetPreviewW(LPCWSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT GetArchiveInfo (LPCSTR buf, size_t len, SPI_FLAG flag, HLOCAL* lphInf); | |
SUSIE_EXPORT GetArchiveInfoW(LPCWSTR buf, size_t len, SPI_FLAG flag, HLOCAL* lphInf); | |
SUSIE_EXPORT GetFileInfo (LPCSTR buf, size_t len, LPCSTR filename, SPI_FLAG flag, SusieFileInfoA* lpInfo); | |
SUSIE_EXPORT GetFileInfoW(LPCWSTR buf, size_t len, LPCWSTR filename, SPI_FLAG flag, SusieFileInfoW* lpInfo); | |
SUSIE_EXPORT GetFile (LPCSTR src, size_t len, LPSTR dest, SPI_FLAG flag, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT GetFileW(LPCWSTR src, size_t len, LPWSTR dest, SPI_FLAG flag, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT ConfigurationDlg(HWND parent, SPI_FNC_CODE fnc); | |
SUSIE_EXPORT CreatePicture (LPCSTR filepath, SPI_FLAG flag, void** pHBInfo, void** pHBm, SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SUSIE_EXPORT CreatePictureW(LPCWSTR filepath, SPI_FLAG flag, void** pHBInfo, void** pHBm, SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
//---------------------------------------------------------------------------// | |
// | |
// Susie コールバック用ダミー関数 | |
// (プラグインの中には progressCallback に nullptr を渡すと落ちるものがあるため) | |
// | |
//---------------------------------------------------------------------------// | |
namespace | |
{ | |
extern "C" constexpr SPI_RESULT WINAPI SusieCallbackDummy | |
( | |
int32_t, int32_t, intptr_t | |
) | |
{ | |
return SPI_ALL_RIGHT; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
// | |
// C++ クラス | |
// | |
//---------------------------------------------------------------------------// | |
namespace tapetums | |
{ | |
class Susie; | |
} | |
//---------------------------------------------------------------------------// | |
// Susie プラグインのラッパークラス | |
class tapetums::Susie | |
{ | |
public: | |
constexpr Susie() = default; | |
~Susie() { Free(); } | |
Susie(const Susie&) = delete; | |
Susie& operator =(const Susie&) = delete; | |
Susie(Susie&&) noexcept; | |
Susie& operator =(Susie&&) noexcept; | |
explicit Susie(LPCTSTR path) { Load(path); } | |
public: | |
constexpr LPCTSTR path() const noexcept { return path_; } | |
public: | |
bool Load(LPCTSTR path); | |
void Free(); | |
SPI_RESULT GetPluginInfoA(int32_t infono, LPSTR buf, int32_t buflen); | |
SPI_RESULT GetPluginInfoW(int32_t infono, LPWSTR buf, int32_t buflen); | |
SPI_RESULT IsSupportedA (LPCSTR filename, uint8_t* dw); | |
SPI_RESULT IsSupportedW (LPCWSTR filename, uint8_t* dw); | |
SPI_RESULT GetPictureInfoA(LPCSTR buf, size_t len, SPI_FLAG flag, SusiePictureInfo* lpInfo); | |
SPI_RESULT GetPictureInfoW(LPCWSTR buf, size_t len, SPI_FLAG flag, SusiePictureInfo* lpInfo); | |
SPI_RESULT GetPictureA (LPCSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT GetPictureW (LPCWSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT GetPreviewA (LPCSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT GetPreviewW (LPCWSTR buf, size_t len, SPI_FLAG flag, void** pHBInfo, void** pHBm, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT GetArchiveInfoA(LPCSTR buf, size_t len, SPI_FLAG flag, HLOCAL* lphInf); | |
SPI_RESULT GetArchiveInfoW(LPCWSTR buf, size_t len, SPI_FLAG flag, HLOCAL* lphInf); | |
SPI_RESULT GetFileInfoA (LPCSTR buf, size_t len, LPCSTR filename, SPI_FLAG flag, SusieFileInfoA* lpInfo); | |
SPI_RESULT GetFileInfoW (LPCWSTR buf, size_t len, LPCWSTR filename, SPI_FLAG flag, SusieFileInfoW* lpInfo); | |
SPI_RESULT GetFileA (LPCSTR src, size_t len, LPSTR dest, SPI_FLAG flag, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT GetFileW (LPCWSTR src, size_t len, LPWSTR dest, SPI_FLAG flag, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT ConfigurationDlg(HWND parent, SPI_FNC_CODE fnc); | |
SPI_RESULT CreatePictureA(LPCSTR filepath, SPI_FLAG flag, void** pHBInfo, void** pHBm, SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
SPI_RESULT CreatePictureW(LPCWSTR filepath, SPI_FLAG flag, void** pHBInfo, void** pHBm, SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData); | |
private: | |
struct API | |
{ | |
SPI_GetPluginInfoA GetPluginInfoA { nullptr }; | |
SPI_GetPluginInfoW GetPluginInfoW { nullptr }; | |
SPI_IsSupportedA IsSupportedA { nullptr }; | |
SPI_IsSupportedW IsSupportedW { nullptr }; | |
SPI_GetPictureInfoA GetPictureInfoA { nullptr }; | |
SPI_GetPictureInfoW GetPictureInfoW { nullptr }; | |
SPI_GetPictureA GetPictureA { nullptr }; | |
SPI_GetPictureW GetPictureW { nullptr }; | |
SPI_GetPreviewA GetPreviewA { nullptr }; | |
SPI_GetPreviewW GetPreviewW { nullptr }; | |
SPI_GetArchiveInfoA GetArchiveInfoA { nullptr }; | |
SPI_GetArchiveInfoW GetArchiveInfoW { nullptr }; | |
SPI_GetFileInfoA GetFileInfoA { nullptr }; | |
SPI_GetFileInfoW GetFileInfoW { nullptr }; | |
SPI_GetFileA GetFileA { nullptr }; | |
SPI_GetFileW GetFileW { nullptr }; | |
SPI_ConfigurationDlg ConfigurationDlg { nullptr }; | |
SPI_CreatePictureA CreatePictureA { nullptr }; | |
SPI_CreatePictureW CreatePictureW { nullptr }; | |
}; | |
HMODULE handle { nullptr }; | |
TCHAR path_[SPI_MAX_PATH] {}; | |
API api {}; | |
}; | |
//---------------------------------------------------------------------------// | |
// | |
// 実装 | |
// | |
//---------------------------------------------------------------------------// | |
inline tapetums::Susie::Susie(Susie&& rhs) noexcept | |
{ | |
std::swap(handle, rhs.handle); | |
std::swap(path_, rhs.path_); | |
std::swap(api, rhs.api); | |
} | |
//---------------------------------------------------------------------------// | |
inline tapetums::Susie& tapetums::Susie::operator =(Susie&& rhs) noexcept | |
{ | |
std::swap(handle, rhs.handle); | |
std::swap(path_, rhs.path_); | |
std::swap(api, rhs.api); | |
return *this; | |
} | |
//---------------------------------------------------------------------------// | |
inline bool tapetums::Susie::Load(LPCTSTR path) | |
{ | |
if ( handle ) { return true; } | |
#if defined (_WIN32) || defined(WIN32) | |
#define dlopen(path, y) ::LoadLibraryEx(path, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH); | |
#define dlsym(handle, proc_name) ::GetProcAddress(handle, proc_name) | |
#endif | |
// DLLの読み込み | |
handle = dlopen(path, RTLD_LAZY); | |
if ( nullptr == handle ) | |
{ | |
return false; | |
} | |
// DLLのフルパスを取得 | |
#if defined (_WIN32) || defined(WIN32) | |
::GetModuleFileName(handle, path_, SPI_MAX_PATH); | |
#else | |
strncpy(path_, path, SPI_MAX_PATH); | |
path_[SPI_MAX_PATH - 1] = '\0'; | |
#endif | |
api.GetPluginInfoA = (SPI_GetPluginInfoA) dlsym(handle, "GetPluginInfo"); | |
api.GetPluginInfoW = (SPI_GetPluginInfoW) dlsym(handle, "GetPluginInfoW"); | |
if ( nullptr == api.GetPluginInfoA && nullptr == api.GetPluginInfoW ) | |
{ | |
Free(); return false; | |
} | |
api.IsSupportedA = (SPI_IsSupportedA) dlsym(handle, "IsSupported"); | |
api.IsSupportedW = (SPI_IsSupportedW) dlsym(handle, "IsSupportedW"); | |
if ( nullptr == api.IsSupportedA && nullptr == api.IsSupportedW ) | |
{ | |
Free(); return false; | |
} | |
api.GetPictureInfoA = (SPI_GetPictureInfoA) dlsym(handle, "GetPictureInfo"); | |
api.GetPictureInfoW = (SPI_GetPictureInfoW) dlsym(handle, "GetPictureInfoW"); | |
api.GetPictureA = (SPI_GetPictureA) dlsym(handle, "GetPicture"); | |
api.GetPictureW = (SPI_GetPictureW) dlsym(handle, "GetPictureW"); | |
api.GetPreviewA = (SPI_GetPreviewA) dlsym(handle, "GetPreview"); | |
api.GetPreviewW = (SPI_GetPreviewW) dlsym(handle, "GetPreviewW"); | |
api.GetArchiveInfoA = (SPI_GetArchiveInfoA) dlsym(handle, "GetArchiveInfo"); | |
api.GetArchiveInfoW = (SPI_GetArchiveInfoW) dlsym(handle, "GetArchiveInfoW"); | |
api.GetFileInfoA = (SPI_GetFileInfoA) dlsym(handle, "GetFileInfo"); | |
api.GetFileInfoW = (SPI_GetFileInfoW) dlsym(handle, "GetFileInfoW"); | |
api.GetFileA = (SPI_GetFileA) dlsym(handle, "GetFile"); | |
api.GetFileW = (SPI_GetFileW) dlsym(handle, "GetFileW"); | |
api.ConfigurationDlg = (SPI_ConfigurationDlg)dlsym(handle, "ConfigurationDlg"); | |
api.CreatePictureA = (SPI_CreatePictureA) dlsym(handle, "CreatePicture"); | |
api.CreatePictureW = (SPI_CreatePictureW) dlsym(handle, "CreatePictureW"); | |
return true; | |
} | |
//---------------------------------------------------------------------------// | |
inline void tapetums::Susie::Free() | |
{ | |
#if defined (_WIN32) || defined(WIN32) | |
#define dlclose(handle) ::FreeLibrary(handle) | |
#endif | |
if ( handle ) | |
{ | |
dlclose(handle); | |
handle = nullptr; | |
} | |
path_[0] = '\0'; | |
api.GetPluginInfoA = nullptr; | |
api.GetPluginInfoW = nullptr; | |
api.IsSupportedA = nullptr; | |
api.IsSupportedW = nullptr; | |
api.GetPictureInfoA = nullptr; | |
api.GetPictureInfoW = nullptr; | |
api.GetPictureA = nullptr; | |
api.GetPictureW = nullptr; | |
api.GetPreviewA = nullptr; | |
api.GetPreviewW = nullptr; | |
api.GetArchiveInfoA = nullptr; | |
api.GetArchiveInfoW = nullptr; | |
api.GetFileInfoA = nullptr; | |
api.GetFileInfoW = nullptr; | |
api.GetFileA = nullptr; | |
api.GetFileW = nullptr; | |
api.ConfigurationDlg = nullptr; | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPluginInfoA | |
( | |
int32_t infono, LPSTR buf, int32_t buflen | |
) | |
{ | |
if ( api.GetPluginInfoA ) | |
{ | |
return api.GetPluginInfoA(infono, buf, buflen); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPluginInfoW | |
( | |
int32_t infono, LPWSTR buf, int32_t buflen | |
) | |
{ | |
if ( api.GetPluginInfoW ) | |
{ | |
return api.GetPluginInfoW(infono, buf, buflen); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::IsSupportedA | |
( | |
LPCSTR filename, uint8_t* dw | |
) | |
{ | |
if ( api.IsSupportedA ) | |
{ | |
return api.IsSupportedA(filename, dw); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::IsSupportedW | |
( | |
LPCWSTR filename, uint8_t* dw | |
) | |
{ | |
if ( api.IsSupportedW ) | |
{ | |
return api.IsSupportedW(filename, dw); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPictureInfoA | |
( | |
LPCSTR buf, size_t len, SPI_FLAG flag, | |
SusiePictureInfo* lpInfo | |
) | |
{ | |
if ( api.GetPictureInfoA ) | |
{ | |
return api.GetPictureInfoA(buf, len, flag, lpInfo); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPictureInfoW | |
( | |
LPCWSTR buf, size_t len, SPI_FLAG flag, | |
SusiePictureInfo* lpInfo | |
) | |
{ | |
if ( api.GetPictureInfoW ) | |
{ | |
return api.GetPictureInfoW(buf, len, flag, lpInfo); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPictureA | |
( | |
LPCSTR buf, size_t len, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetPictureA ) | |
{ | |
return api.GetPictureA | |
( | |
buf, len, flag, pHBInfo, pHBm, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPictureW | |
( | |
LPCWSTR buf, size_t len, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetPictureW ) | |
{ | |
return api.GetPictureW | |
( | |
buf, len, flag, pHBInfo, pHBm, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPreviewA | |
( | |
LPCSTR buf, size_t len, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetPreviewA ) | |
{ | |
return api.GetPreviewA | |
( | |
buf, len, flag, pHBInfo, pHBm, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetPreviewW | |
( | |
LPCWSTR buf, size_t len, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetPreviewW ) | |
{ | |
return api.GetPreviewW | |
( | |
buf, len, flag, pHBInfo, pHBm, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetArchiveInfoA | |
( | |
LPCSTR buf, size_t len, SPI_FLAG flag, | |
HLOCAL* lphInf | |
) | |
{ | |
if ( api.GetArchiveInfoA ) | |
{ | |
return api.GetArchiveInfoA(buf, len, flag, lphInf); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetArchiveInfoW | |
( | |
LPCWSTR buf, size_t len, SPI_FLAG flag, | |
HLOCAL* lphInf | |
) | |
{ | |
if ( api.GetArchiveInfoW ) | |
{ | |
return api.GetArchiveInfoW(buf, len, flag, lphInf); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetFileInfoA | |
( | |
LPCSTR buf, size_t len, LPCSTR filename, SPI_FLAG flag, | |
SusieFileInfoA* lpInfo | |
) | |
{ | |
if ( api.GetFileInfoA ) | |
{ | |
return api.GetFileInfoA(buf, len, filename, flag, lpInfo); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetFileInfoW | |
( | |
LPCWSTR buf, size_t len, LPCWSTR filename, SPI_FLAG flag, | |
SusieFileInfoW* lpInfo | |
) | |
{ | |
if ( api.GetFileInfoW ) | |
{ | |
return api.GetFileInfoW(buf, len, filename, flag, lpInfo); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetFileA | |
( | |
LPCSTR src, size_t len, LPSTR dest, SPI_FLAG flag, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetFileA ) | |
{ | |
return api.GetFileA(src, len, dest, flag, progressCallback, lData); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::GetFileW | |
( | |
LPCWSTR src, size_t len, LPWSTR dest, SPI_FLAG flag, | |
SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.GetFileW ) | |
{ | |
return api.GetFileW(src, len, dest, flag, progressCallback, lData); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::ConfigurationDlg | |
( | |
HWND parent, SPI_FNC_CODE fnc | |
) | |
{ | |
if ( api.ConfigurationDlg ) | |
{ | |
return api.ConfigurationDlg(parent, fnc); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::CreatePictureA | |
( | |
LPCSTR filepath, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.CreatePictureA ) | |
{ | |
return api.CreatePictureA | |
( | |
filepath, flag, pHBInfo, pHBm, lpInfo, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline SPI_RESULT tapetums::Susie::CreatePictureW | |
( | |
LPCWSTR filepath, SPI_FLAG flag, | |
void** pHBInfo, void** pHBm, | |
SusiePictureInfo* lpInfo, SUSIE_PROGRESS progressCallback, intptr_t lData | |
) | |
{ | |
if ( api.CreatePictureW ) | |
{ | |
return api.CreatePictureW | |
( | |
filepath, flag, pHBInfo, pHBm, lpInfo, progressCallback, lData | |
); | |
} | |
else | |
{ | |
return SPI_NO_FUNCTION; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
// Susie.hpp |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
//---------------------------------------------------------------------------// | |
// | |
// SusieMgr.hpp | |
// Susie プラグイン管理クラス (C++17) | |
// Copyright (C) 2013-2016 tapetums | |
// | |
//---------------------------------------------------------------------------// | |
#if __cplusplus > 201700L | |
#include <optional> | |
#elif __cplusplus >= 201402L | |
#include <experimental/optional> | |
namespace std { template<typename T> using optional = experimental::optional<T>; } | |
#else | |
#error No library <optional> | |
#endif | |
#include <vector> | |
#include <stdexcept> | |
#include <string> | |
namespace std { using tstring = basic_string<TCHAR>; } | |
#include "Susie.hpp" | |
//---------------------------------------------------------------------------// | |
namespace tapetums | |
{ | |
class SusieMgr; | |
} | |
//---------------------------------------------------------------------------// | |
// Susie プラグイン管理クラス | |
class tapetums::SusieMgr | |
{ | |
public: | |
using value_type = Susie; | |
using ref_type = std::optional<value_type&>; | |
using const_ref_type = std::optional<const value_type&>; | |
using container_type = std::vector<value_type>; | |
using iterator = container_type::iterator; | |
using const_iterator = container_type::const_iterator; | |
using reverse_iterator = container_type::reverse_iterator; | |
using const_reverse_iterator = container_type::const_reverse_iterator; | |
private: | |
container_type plugins; | |
public: | |
SusieMgr() = default; | |
~SusieMgr() = default; | |
SusieMgr(const SusieMgr&) = delete; | |
SusieMgr& operator =(const SusieMgr&) = delete; | |
SusieMgr(SusieMgr&&) noexcept = default; | |
SusieMgr& operator =(SusieMgr&&) noexcept = default; | |
template <typename... Args> | |
SusieMgr(Susie&& susie, Args&&... args) { init(susie, args...); } | |
template <typename... Args> | |
SusieMgr(LPCTSTR path, Args... args) { init(path, args...); } | |
public: | |
size_t size() const noexcept; | |
const_ref_type at(size_t index) const noexcept; | |
ref_type at(size_t index) noexcept; | |
public: | |
const_ref_type operator[](size_t index) const noexcept { return at(index); } | |
ref_type operator[](size_t index) noexcept { return at(index); } | |
public: | |
void append(Susie&& susie); | |
bool append(LPCTSTR path); | |
void collect_susie(LPCTSTR dir_path, bool serach_in_subdir); | |
ref_type acquire(LPCSTR filename, uint8_t* dw); | |
ref_type acquire(LPCWSTR filename, uint8_t* dw); | |
public: | |
iterator begin() noexcept { return plugins.begin(); } | |
iterator end() noexcept { return plugins.end(); } | |
const_iterator begin() const noexcept { return plugins.begin(); } | |
const_iterator end() const noexcept { return plugins.end(); } | |
const_iterator cbegin() const noexcept { return plugins.cbegin(); } | |
const_iterator cend() const noexcept { return plugins.cend(); } | |
reverse_iterator rbegin() noexcept { return plugins.rbegin(); } | |
reverse_iterator rend() noexcept { return plugins.rend(); } | |
const_reverse_iterator rbegin() const noexcept { return plugins.rbegin(); } | |
const_reverse_iterator rend() const noexcept { return plugins.rend(); } | |
const_reverse_iterator crbegin() const noexcept { return plugins.crbegin(); } | |
const_reverse_iterator crend() const noexcept { return plugins.crend(); } | |
private: | |
void init(Susie&& susie); | |
void init(LPCTSTR path); | |
template <typename... Args> | |
void init(Susie&& susie, Args&&... args); | |
template <typename... Args> | |
void init(LPCTSTR path, Args... args); | |
}; | |
//---------------------------------------------------------------------------// | |
// ctor | |
//---------------------------------------------------------------------------// | |
inline void tapetums::SusieMgr::init(Susie&& susie) | |
{ | |
append(std::move(susie)); | |
} | |
//---------------------------------------------------------------------------// | |
inline void tapetums::SusieMgr::init(LPCTSTR path) | |
{ | |
append(path); | |
} | |
//---------------------------------------------------------------------------// | |
template<typename... Args> | |
inline void tapetums::SusieMgr::init(Susie&& susie, Args&&... args) | |
{ | |
append(std::move(susie)); | |
init(args...); | |
} | |
//---------------------------------------------------------------------------// | |
template<typename... Args> | |
inline void tapetums::SusieMgr::init(LPCTSTR path, Args... args) | |
{ | |
append(path); | |
init(args...); | |
} | |
//---------------------------------------------------------------------------// | |
// Accessors | |
//---------------------------------------------------------------------------// | |
inline size_t tapetums::SusieMgr::size() const noexcept | |
{ | |
return plugins.size(); | |
} | |
//---------------------------------------------------------------------------// | |
inline tapetums::SusieMgr::const_ref_type tapetums::SusieMgr::at(size_t index) const noexcept | |
{ | |
try | |
{ | |
return const_ref_type(plugins.at(index)); | |
} | |
catch ( std::out_of_range& ) | |
{ | |
return const_ref_type(); | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline tapetums::SusieMgr::ref_type tapetums::SusieMgr::at(size_t index) noexcept | |
{ | |
try | |
{ | |
return ref_type(plugins.at(index)); | |
} | |
catch ( std::out_of_range& ) | |
{ | |
return ref_type(); | |
} | |
} | |
//---------------------------------------------------------------------------// | |
// Methids | |
//---------------------------------------------------------------------------// | |
inline void tapetums::SusieMgr::append | |
( | |
Susie&& susie | |
) | |
{ | |
plugins.push_back(std::move(susie)); | |
} | |
//---------------------------------------------------------------------------// | |
inline bool tapetums::SusieMgr::append | |
( | |
LPCTSTR path | |
) | |
{ | |
Susie susie; | |
if ( susie.Load(path) ) | |
{ | |
plugins.push_back(std::move(susie)); | |
return true; | |
} | |
else | |
{ | |
return false; | |
} | |
} | |
//---------------------------------------------------------------------------// | |
inline void tapetums::SusieMgr::collect_susie | |
( | |
LPCTSTR dir_path, bool serach_in_subdir | |
) | |
{ | |
std::tstring path { dir_path }; | |
path += TEXT(R"(\*)"); | |
WIN32_FIND_DATA fd { }; | |
const auto hFindFile = ::FindFirstFile(path.c_str(), &fd); | |
if ( INVALID_HANDLE_VALUE == hFindFile ) | |
{ | |
// 指定されたフォルダが見つからなかった | |
return; | |
} | |
// フォルダ内にあるものを列挙する | |
do | |
{ | |
// 隠しファイルは飛ばす | |
if ( fd.cFileName[0] == '.' ) | |
{ | |
continue; | |
} | |
if ( fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN ) | |
{ | |
continue; | |
} | |
// フルパスを合成 | |
path = dir_path + std::tstring{ TEXT(R"(\)") } + fd.cFileName; | |
if ( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) | |
{ | |
// フォルダだったら | |
if ( serach_in_subdir ) | |
{ | |
// サブフォルダを検索 | |
collect_susie(path.c_str(), serach_in_subdir); | |
} | |
} | |
else | |
{ | |
// DLLファイルだったら | |
const auto pos = path.rfind(TEXT(".")); | |
if ( path.substr(pos) == SPI_EXT ) | |
{ | |
// コンポーネントデータベースに記憶 | |
append(path.c_str()); | |
} | |
} | |
} | |
while ( ::FindNextFile(hFindFile, &fd) ); | |
::FindClose( hFindFile ); | |
return; | |
} | |
//---------------------------------------------------------------------------// | |
inline tapetums::SusieMgr::ref_type tapetums::SusieMgr::acquire | |
( | |
LPCSTR filename, uint8_t* dw | |
) | |
{ | |
for ( auto&& susie : plugins ) | |
{ | |
if ( susie.IsSupportedA(filename, dw) == SPI_SUPPORTED ) | |
{ | |
return ref_type(std::ref(susie)); | |
} | |
} | |
return ref_type(); | |
} | |
//---------------------------------------------------------------------------// | |
inline tapetums::SusieMgr::ref_type tapetums::SusieMgr::acquire | |
( | |
LPCWSTR filename, uint8_t* dw | |
) | |
{ | |
for ( auto&& susie : plugins ) | |
{ | |
if ( susie.IsSupportedW(filename, dw) == SPI_SUPPORTED ) | |
{ | |
return ref_type(std::ref(susie)); | |
} | |
} | |
return ref_type(); | |
} | |
//---------------------------------------------------------------------------// | |
// SusieMgr.hpp |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment