Created
February 8, 2011 22:35
-
-
Save miau/817427 to your computer and use it in GitHub Desktop.
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
// D で作る Win32 DLL - プログラミング言語 D 2.0 | |
// http://www.kmonos.net/alang/d/2.0/dll.html | |
// から拝借。 | |
// | |
// -w オプションつきでコンパイルすると以下のエラーになったので default: を追加しています | |
// warning - dll.d(8): Error: switch statement has no default | |
// warning - dll.d(8): Error: statement is not reachable | |
import core.runtime; | |
import std.c.windows.windows; | |
HINSTANCE g_hInst; | |
extern (Windows) | |
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved) | |
{ | |
switch (ulReason) | |
{ | |
case DLL_PROCESS_ATTACH: | |
Runtime.initialize(); | |
break; | |
case DLL_PROCESS_DETACH: | |
Runtime.terminate(); | |
break; | |
case DLL_THREAD_ATTACH: | |
case DLL_THREAD_DETACH: | |
// Multiple threads not supported yet | |
return false; | |
default: | |
} | |
g_hInst=hInstance; | |
return true; | |
} |
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
// コンパイル方法: | |
// dmd -ofhttp.dll http.d wstring.d dll.d http.def OLEAUT32.LIB | |
// | |
// テスト方法: | |
// rdmd -unittest http.d wstring.d dll.d http.def OLEAUT32.LIB | |
// | |
// wtypes、oleauto 利用のため、 | |
// svn export http://svn.dsource.org/projects/bindings/trunk/win32 | |
// で取得した Bindings for the Windows API を | |
// %programfiles%\dmd2\src\phobos\win32 | |
// として配置しています。 | |
module http; | |
import std.stdio; | |
import std.conv; // for to!wstring | |
import std.c.wcharh; | |
import win32.oleauto; // for SysAllocString | |
import win32.wtypes; // for BSTR | |
import wstring; | |
import std.algorithm; // for splitter | |
import std.string; // for string | |
version (none) | |
{ | |
import std.regex; | |
} | |
extern (Windows) { | |
int GetPluginType() { | |
return 1; | |
} | |
BSTR GetName() { | |
return SysAllocString("http"); | |
} | |
BSTR GetVersion() { | |
return SysAllocString("0.0.2"); | |
} | |
BSTR GetAuthor() { | |
return SysAllocString("@miau_jp"); | |
} | |
BSTR GetSyntax() { | |
return SysAllocString("[http://~:title=タイトル]"); | |
} | |
BSTR GetDescription() { | |
return SysAllocString("http記法"); | |
} | |
BSTR GetExample() { | |
return SysAllocString("[http://www.google.co.jp/:title=Google]"); | |
} | |
BSTR PluginInline( | |
in char* escapedString, | |
in char* plainString, | |
in char* documentName, | |
in char* fileName, | |
in char* documentFolder, | |
in char* templateFolder, | |
in char* settingsName) { | |
string s = ntsToString(plainString); | |
wstring ws = SjisToUtf16(s); | |
return SysAllocString(_PluginInline(ws).ptr); | |
} | |
} | |
wstring _PluginInline(wstring s) { | |
version (none) | |
{ | |
// 以下のエラーになるので正規表現を利用しない形に変更 | |
// core.exception.AssertError@D:\dmd2\windows\bin\..\..\src\phobos\std\regex.d(1689): 5 | |
wstring re_url = to!wstring(std.regex.url); | |
auto captures = match("http:" ~ s, "(" ~ re_url ~ "):title=(.*)").captures; | |
if (!captures.empty) { | |
return `<a href="` ~ captures[1] ~ `">` ~ captures[captures.length] ~ `</a>` ~ "\0"; | |
} | |
} | |
auto split = split(s, ":title="); | |
if (split.length == 2) { | |
return `<a href="http:` ~ split[0] ~ `">` ~ split[1] ~ `</a>` ~ "\0"; | |
} | |
return "can't analyse!"; // assert 失敗時に文字化けしないよう、エラーメッセージは ASCII で書く | |
} | |
unittest { | |
wstring expected = `<a href="http://www.google.co.jp/">Google 日本</a>` ~ "\0"; | |
wstring result = _PluginInline("//www.google.co.jp/:title=Google 日本"); | |
assert(result == expected, to!string(result ~ expected)); | |
} | |
// -unittest で起動した際、main() が無いとエラーになるのでダミーの main() を作成する | |
version(unittest) { | |
void main() { | |
writeln("*** unittest passed ***"); | |
} | |
} |
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
LIBRARY "http.dll" | |
EXETYPE NT | |
CODE PRELOAD DISCARDABLE | |
DATA PRELOAD SINGLE | |
EXPORTS | |
GetPluginType | |
GetName | |
GetVersion | |
GetAuthor | |
GetSyntax | |
GetDescription | |
GetExample | |
PluginInline |
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
module wstring; | |
import std.c.locale; // for setlocale, LC_CTYPE | |
import std.c.stdlib; // for wcstombs | |
import std.c.string; // for strlen | |
import std.string; | |
// null-terminated string の char* を string に変換する | |
string ntsToString(const char* s) | |
{ | |
if (s is null) { | |
return cast(string) null; | |
} | |
return s[0 .. strlen(s)].idup; | |
} | |
// Shift_JIS の string を UTF-16 の wstring で返す | |
// 参考: | |
// http://pokohimesama.blog98.fc2.com/?mode=m&no=337 | |
wstring SjisToUtf16(string s) | |
{ | |
if (s is null) { | |
return cast(wstring) null; | |
} | |
wchar[] ws; | |
ws.length = s.length + 1; | |
auto locale_org = setlocale(LC_CTYPE, ""); | |
scope(exit) { setlocale(LC_CTYPE, locale_org); } | |
auto n = mbstowcs(ws.ptr, s.toStringz(), ws.length); | |
return ws[0 .. n].idup; | |
} | |
unittest | |
{ | |
wstring expected, result; | |
expected = "あいう"; | |
result = SjisToUtf16(x"82a0 82a2 82a4"); // 「あいう」の Shift_JIS 表現 | |
assert(expected == result); | |
expected = "\uff5e"; // 「~」(FULLWIDTH TILDE)。念のためコードポイントで比較する。 | |
result = SjisToUtf16(x"8160"); // 「~」の Shift_JIS 表現 | |
assert(expected == result); | |
} | |
// wchar* 同士の wstrcmp()。実装を変更したため未使用。 | |
int wstrcmp(in wchar* a, in wchar* b) { | |
const(wchar)* p = a; | |
const(wchar)* q = b; | |
while (1) { | |
if (*p == '\0' && *q == '\0') { | |
return 0; | |
} else if (*p > *q) { | |
return 1; | |
} else if (*p < *q) { | |
return -1; | |
} else { | |
p++; | |
q++; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment