C++でURLエンコード&デコード

bool is_safe_char(UCHAR c) { return isalnum(c) || c == '.' || c == '-' || c == '_' || c == '*'; }

char* encode_char_to_hex(char c, char* dist) {
	dist[0] = '%';
	dist[1] = "0123456789ABCDEF"[(c & 0xF0) >> 4];
	dist[2] = "0123456789ABCDEF"[c & 0x0F];
	return dist + 2;
}

unsigned url_encode(const char* c, char* dist) {
	const char* head = dist;
	for (; *c != '\0'; c++, dist++) {
		if (is_safe_char(*c))* dist = *c;
		else if (*c == ' ')* dist = '+';
		else                 dist = encode_char_to_hex(*c, dist);
	}
	*dist = '\0';
	return dist - head;
}


static const char table[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
char decode_hex_to_char(const char* c) {
	// XXX: [0-9a-zA-Z]以外の全ての文字は、0として扱われる (e.g. "%@X" => 0)
	return (table[static_cast<unsigned char>(c[1])] << 4) +
		table[static_cast<unsigned char>(c[2])];
}

unsigned url_decode(const char* c, char* dist) {
	const char* head = dist;
	for (; *c != '\0'; c++, dist++) {
		switch (*c) {
		case '%': *dist = decode_hex_to_char(c); c += 2; break;  // XXX: 末尾に'%'が来る不正な文字列が渡された場合の挙動は未定義(ex. "abc%")
		case '+': *dist = ' ';                         break;
		default:  *dist = *c;                          break;
		}
	}
	*dist = '\0';
	return dist - head;
}

SQLite VC++に組み込み手順

ソースとDLLをダウンロード

https://www.sqlite.org/download.htmlから
Source Code と Precompiled Binaries for Windows をダウンロード

sqlite3.libの作成

Visual Studio コマンドプロンプトを起動。
f:id:shikaku:20190607151320p:plain

libコマンドで sqlite3.libを生成する。
パスはそれぞれの環境に合わせて変えてね。

c:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools>lib /def:C:\prj\sdk\lib\sqlite
-source-3_5_1\sqlite3.def /out:C:\prj\sdk\lib\sqlite-source-3_5_1\sqlite3.lib

作ったsqlite3.libはパスの通った場所に置く。
リンカ/ライブラリアンの設定にある「追加のライブラリディレクトリ」でディレクトリ指定するも良し。

c/hソースをプロジェクトに追加

shell.c/sqlite3.cは
右クリックのプロパティから「プリコンパイル済ヘッダー」は使用しないように変更
f:id:shikaku:20190607151546p:plain

ブラウザの待機処理がうまくいかない場合の対処方法には「ズバリ」の解決策が無い

VBAのIE操作とかでブラウザ待機処理はこんなに書きますが、
その先の処理でまぁエラーが出る。

Do While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
    DoEvents
Loop

どうやら一瞬READYSTATE_COMPLETEでるけど読み終わってないとか
いろいろ原因があるみたいだけど、環境依存みたい。

数回チェックいれたり

For i = 0 To retryCount
    Do While objIE.Busy Or objIE.readyState <> READYSTATE_COMPLETE
        DoEvents
    Loop
    
    Sleep 100
Next

次の画面にあるオブジェクトにサワれるようになるまで無限ループさせたり、泥臭い対策するっきゃないみたい。

Do
    Set obj = Nothing
    On Error Resume Next
    Set obj = objIE.getElementById("nameInput")
    On Error GoTo 0
Loop While obj Is Nothing

しかたなくSleepいれてごまかすしかないシチュエーションもありそう。

Firebase MLKit AutoML Vision Edgeで超簡単に機械学習

試しに犬猫判断でやってみたけど、素材用意してzipにして放り込んで学習させるだけという超簡単仕様。

アプリ組み込み用のファイル出力したり、外部からアクセスできるよう公開することでアプリから学習結果を利用できるようになるらしい。

これくらい簡単だと使い勝手いいですねー。