GDIでPNGを読み込む

GDIでは通常PNGファイルを読み込むことはできないらしい。

どうしても読み込む必要があったのでちょっと調べてみた

http://code.logos.com/blog/2008/09/displaying_a_splash_screen_with_c_part_i.html

このやり方でうまく読み込めるのだが、どうやらマシンによっては読み込みにFailする。一応XPSP3から使えるとなっているのだが。。。

仕方がないのでGDI+を用いました。

HBITMAP LoadImage( HINSTANCE hinst, LPCTSTR pszName, LPCTSTR pszType )
{
		HRSRC hRes = FindResource(hinst, pszName, pszType);
		DWORD Size = SizeofResource(hinst, hRes);
		HGLOBAL hData = LoadResource(hinst, hRes);
		const void *pData = LockResource(hData);
		HGLOBAL hBuffer = GlobalAlloc(GMEM_MOVEABLE, Size);
		void *pBuffer = GlobalLock(hBuffer);
		CopyMemory(pBuffer, pData, Size);
		GlobalUnlock(hBuffer);

		IStream *pStream;
		CreateStreamOnHGlobal(hBuffer, TRUE, &pStream) ;
	 IStream *pStream=CreateStreamOnResource(hinst,pszName,pszType);

		Gdiplus::Bitmap* pBitmap = Gdiplus::Bitmap::FromStream(pStream);
		pStream->Release();
		HBITMAP ret;
		pBitmap->GetHBITMAP(Color(0,0,0,0),&ret);
		delete pBitmap;
	return ret;
}

JavaでMongoDBに接続してみた

MongoDBはQueryがちょっと特殊です。

http://gihyo.jp/dev/serial/01/mongodb/0003?page=2

この辺りを参考に。。

データにISODate型で入っているものに対してwhere句はこんなかんじ

> db.search_engine.find({time:{$gte:ISODate("2013-04-12T04:10:30Z"),$lt:ISODate("2013-04-12T04:32:50Z")}},{time:1}).sort({time:1})
{ "_id" : ObjectId("5167893f7cbb48516f000013"), "time" : ISODate("2013-04-12T04:10:30Z") }
{ "_id" : ObjectId("5167893f7cbb48516f000014"), "time" : ISODate("2013-04-12T04:10:31Z") }
{ "_id" : ObjectId("5167893f7cbb48516f000015"), "time" : ISODate("2013-04-12T04:10:33Z") }
{ "_id" : ObjectId("5167893f7cbb48516f000016"), "time" : ISODate("2013-04-12T04:10:34Z") }
{ "_id" : ObjectId("51678caf7cbb48516f00002f"), "time" : ISODate("2013-04-12T04:25:07Z") }
{ "_id" : ObjectId("51678caf7cbb48516f000030"), "time" : ISODate("2013-04-12T04:25:07Z") }
{ "_id" : ObjectId("51678caf7cbb48516f000031"), "time" : ISODate("2013-04-12T04:25:08Z") }
{ "_id" : ObjectId("51678caf7cbb48516f000032"), "time" : ISODate("2013-04-12T04:25:08Z") }
{ "_id" : ObjectId("51678e687cbb48516f000049"), "time" : ISODate("2013-04-12T04:32:34Z") }
{ "_id" : ObjectId("51678e687cbb48516f00004a"), "time" : ISODate("2013-04-12T04:32:34Z") }
> 

これをJavaから接続するにはちょっと悩みました

http://www.mkyong.com/mongodb/java-mongodb-query-document/

http://stackoverflow.com/questions/9091155/mongo-isodate-query-in-java

この辺りを参考に

	SimpleDateFormat df=new SimpleDateFormat("yyyyMMdd");
	Date fromDate=df.format("20130412");
	Date toDate=df.format("20130413");
	String host="hostname";
	int port=11111;
	MongoClient mon=new MongoClient(new ServerAddress(host,port));
	DB db=mon.getDB("dbName");
	DBCollection coll=db.getCollection("collection");
	BasicDBObject query=new BasicDBObject();
	query.put("time",new BasicDBObject("$gte",fromDate).append("$lte",toDate));
	DBCursor cur=coll.find(query);
	while(cur.hasNext()){
		DBObject o=cur.next();
	
	}

ポイントはJavaのDateクラスがそのまま用いることができるとのこと。

結構悩みました。。

Kakasiをrubyでつかう(その後)

ruby-kakasiを導入してみたのですが、どうも動きがおかしいことに気づきました

どういう時におかしいかというと連続で違う引数で呼び出す際にどうやら2回めの呼び出し時の引数が聞いていないような感じです。しかもローマ字に変換する際にヘボン式か訓令式か変更した場合のみです

こんなコード

#!ruby
#coding:utf-8

require "kakasi"
require "nkf"
keyword="し ち つ ふ じ ぢ しゃ しゅ しょ ちゃ ちゅ ちょ じゃ じゅ じょ ぢゃ ぢゅ ぢょ"
p Kakasi.kakasi("-Ea -Ja -Ka -Ha ",NKF.nkf("-e",keyword))
p Kakasi.kakasi("-Ea -Ja -Ka -Ha -rk",NKF.nkf("-e",keyword))

結果がこれ

$ ruby test.rb
"shi chi tsu fu ji di sha shu sho cha chu cho ja ju jo dya dyu dyo"
"shi chi tsu fu ji di sha shu sho cha chu cho ja ju jo dya dyu dyo"

最初kakasi-rubyがおかしいのかと思いソースコードをいじってみていたのですがどうやらそうではなく、本体側がおかしいことがわかりました。

このぶぶん

--- kakasi-2.3.4/src/hh2.c			2001-05-30 14:46:55.000000000 +0900
+++ kakasi-2.3.4_mod/src/hh2.c	2013-04-23 18:23:04.000000000 +0900
@@ -192,7 +192,7 @@
		 int max_match, match_more;
		 char *max_romaji;

-		if (index_made == 0) {
+//		if (index_made == 0) {
				int last;

				for (i = 0; i < 0x81; ++ i) {
@@ -211,7 +211,7 @@
								last = index_table[i];
				}
				index_made = 1;
-		}
+//		}

		 buffer[H2rom_buflen-1] = '\0'; clen = H2rom_buflen-1;
		 for (i = 0; i < (H2rom_buflen-1)/2; i ++) {

どうも訓令式とヘボン式のテーブルを切り替えて使っているようなのですが、高速化のためか一文字目の際にテーブルを作成し、それ以降はキャッシュを見るような感じになっています。しかしstatic変数で管理しているため、Library使用時にはこれがクリアされず、2回めのライブラリ呼び出し時には前回のキャッシュをそのまま使っていたようです

とりあえずキャッシュ部分を削除してみました。

本来ならばきちんと治すべきなのですが、、、、、

本体修正後rubyを実行

ruby test.rb
"shi chi tsu fu ji di sha shu sho cha chu cho ja ju jo dya dyu dyo"
"si ti tu hu zi di sya syu syo tya tyu tyo zya zyu zyo dya dyu dyo"

期待通りとなりました

kakasi-rubyをruby1.9で動かす

https://github.com/hogelog/kakasi-ruby

ruby用のkakasiモジュールはそのままではruby1.9ではコンパイルが通りません

そこで↓を参考に修正

http://www.metareal.org/2007/06/14/ruby-extension-struct-rstring-macros/

パッチ

diff -u kakasi-ruby-master/kakasi.c kakasi-ruby-master-1.9/kakasi.c
--- kakasi-ruby-master/kakasi.c 2013-04-19 10:14:17.000000000 +0900
+++ kakasi-ruby-master-1.9/kakasi.c		 2013-04-19 10:08:46.000000000 +0900
@@ -3,24 +3,28 @@
	*	Copyright (c) 1999-2002 GOTO Kentaro
	*/

-
 #include 
 #include "ruby.h"
 #include "libkakasi.h"

-
 #define OPTMAX 1024
 #define min(x,y) ((x)<(y) ? (x) : (y))


+// 130419 for 1.9
+#ifndef RSTRING_PTR
+#define RSTRING_PTR(s) (RSTRING(s)->ptr)
+#endif
+#ifndef RSTRING_LEN
+#define RSTRING_LEN(s) (RSTRING(s)->len)
+#endif
+
 static char const rcsid[] =
	 "$kNotwork: kakasi.c,v 1.3 2002/09/28 05:21:37 gotoken Exp $";

-
 static int dic_closed = 1, len = 0;
 static char prev_opt_ptr[OPTMAX];

-
 static VALUE
 rb_kakasi_kakasi(obj, opt, src)
		 VALUE obj, opt, src;
@@ -30,45 +34,36 @@
		 char *buf, *opt_ptr, *t;
		 VALUE dst;

-
		 Check_Type(src, T_STRING);

-
		 /* return "" immediately if source str is empty */
-		if (RSTRING(src)->len == 0)
+		if(RSTRING_LEN(src)==0)
				return rb_str_new2("");

-
		 Check_Type(opt, T_STRING);

-
			/* initialize kakasi iff opt != previous opt */
-		if (0 == len || 0 != strncmp(RSTRING(opt)->ptr, prev_opt_ptr,
-																min(RSTRING(opt)->len, len))) {
-			 strncpy(prev_opt_ptr, RSTRING(opt)->ptr, RSTRING(opt)->len);
-			 len = RSTRING(opt)->len;
-
+		if (0 == len || 0 != strncmp(RSTRING_PTR(opt), prev_opt_ptr,
+																min(RSTRING_LEN(opt), len))) {
+			 strncpy(prev_opt_ptr, RSTRING_PTR(opt), RSTRING_LEN(opt));
+			 len = RSTRING_LEN(opt);

				if (len + 1 > OPTMAX) {
						rb_raise(rb_eArgError, "too long 1st arg (should be < 1023)");
				}

-
				if (!dic_closed) {
						kakasi_close_kanwadict();
						dic_closed = 1;
				}

-
-			 argv = opts = ALLOCA_N(char*, RSTRING(opt)->len);
+			 argv = opts = ALLOCA_N(char*, RSTRING_LEN(opt));
				*opts++ = "kakasi";
				argc++;

-
-			 opt_ptr = ALLOCA_N(char, 1 + RSTRING(opt)->len);
-			 strncpy(opt_ptr, RSTRING(opt)->ptr, RSTRING(opt)->len);
-			 opt_ptr[RSTRING(opt)->len] = '\0';
-
+			 opt_ptr = ALLOCA_N(char, 1 + RSTRING_LEN(opt));
+			 strncpy(opt_ptr, RSTRING_PTR(opt), RSTRING_LEN(opt));
+			 opt_ptr[RSTRING_LEN(opt)] = '\0';

				if (*opts++ = strtok(opt_ptr, " \t")) {
						argc++;
@@ -77,42 +72,37 @@
								argc++;
						}
				}
-
-
+
				if (0 != kakasi_getopt_argv(argc, argv))
						rb_raise(rb_eRuntimeError, "failed to initialize kakasi");
				dic_closed = 0;
		 }

-
		 dst = rb_str_new2("");
-		while (i < RSTRING(src)->len) {
-			if (*(RSTRING(src)->ptr + i) != '\0') {
-			 buf = kakasi_do((RSTRING(src)->ptr + i));
+		while (i < RSTRING_LEN(src)) {
+			if (*(RSTRING_PTR(src) + i) != '\0') {
+			 buf = kakasi_do((RSTRING_PTR(src) + i));
				rb_str_concat(dst, rb_str_new2(buf));
				if (*buf) free(buf);
-			 while (*(RSTRING(src)->ptr + i) != '\0') {
+			 while (*(RSTRING_PTR(src) + i) != '\0') {
					i++;
				}
			 }
-			if (i == RSTRING(src)->len) {
+			if (i == RSTRING_LEN(src)) {
				break;
			 }
			 rb_str_concat(dst, rb_str_new("\0", 1));
			 i++;
		 }

-
		 return dst;
 }

-
 void
 Init_kakasi()
 {
		 VALUE mKakasi = rb_define_module("Kakasi");

-
		 rb_define_module_function(mKakasi, "kakasi", rb_kakasi_kakasi, 2);
		 rb_define_const(mKakasi, "KAKASI_VERSION", rb_str_new2("2002-09-28"));
 }

と思って作成していたらすでに修正している人がいました。_| ̄|○

https://github.com/hogelog/kakasi-ruby/tree/1.9

Tomcat+DBCP+SQLite

  • server.xml
			
								
			
  • WEB-INF/web.xml


	test	
	
		jdbc/sqlite
		javax.sql.DataSource
		Container
	

  • jsp
<%@ page language="java" contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS"%><%@ page import="java.sql.*,javax.naming.*,javax.sql.*,java.util.*,java.text.*,java.net.*" %>
<%
	InitialContext ic = new InitialContext();
	DataSource ds=(DataSource)ic.lookup("java:comp/env/jdbc/sqlite");
	Connection conn=ds.getConnection();
	PreparedStatement ps=conn.prepareStatement("select datetime('now','localtime')");
	ps.execute();
	ResultSet rs=ps.getResultSet();
	while(rs.next()){
		 out.println(rs.getString(1));
	}
 %>
  • 結果
2013-04-18 17:01:20

autocompleteで送信パラメタをカスタマイズしてみた

jQueryAutoCompleteではデフォルトの送信パラメタはtermのみでちょっと使い勝手が悪かったりします。

そこでカスタマイズしてみます

source:function(request,response)をオーバーライド



	Insert title here
	    


 

test.js

$(function() {
		var url="./searchEngine.jsp";
		var val1=$("#val1").val();
		var val2=$("#val2").val();
		$( "#searchTags" ).autocomplete({
		source : function( request, response ) {
					 request["val1"]=val1;
					 request["val2"]=val2;

			 $.ajax({
				url: url,
				data: request,
				dataType: "jsonp",
				jsonpCallback:'callback',
				success: function( data ) {
					response( data );
				},
				error: function() {
					response( [] );
				}
			});
		},

		});
});

searchEngine.jsp

<%@ page language="java" contentType="text/html; charset=Shift_JIS"
		pageEncoding="Shift_JIS"%>
Map map = request.getParameterMap();
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
	String name = (String)it.next();
	String[] val = (String[])map.get(name);
	for (int i = 0;i

MacOS10.8のVirtualBox上でUSB接続のDVDを認識させる

  • iMac MacOS10.8
  • DVD Drive Buffalo BRXL-PC6VU2
  • ゲストWindowsVista Ultimate 32bit

この組み合わせでVirtualBox上のVistaにつなげるにはちょっと苦労しました。

VirtualBoxの設定からポート、USB を選択し+ボタンでBUFFALO Optical ODDを追加します。この際にUSB2.0コントローラを有効にしますが、こちらはVirtualBoxの追加パッケージを入れておく必要がありました。

このまま起動すると、Vista上では不明なデバイスとして認識されてしまい、DVDは使えません。

ネットを調べたところ皆さん苦労しているようで、起動前にUSBをMacから物理的にはなしておき、VirtualBox起動後につけるとかあったのですが、うまくいきません。

半ばあきらめていたのですが、OKWebにあったこれ

「CPUを一個にするとうまくいく!」

半信半疑でVirtualBoxのCPU数を2個から1個へ。

これがうまくいきました。Explorer上でちゃんとDVDドライブとして認識されています

YAML.dumpで日本語が文字化けする

YAML.dumpでUTF8文字列をダンプする際にはバイナリと認識されてしまい、ファイルに保存した際にちょっと困ったことになります。

Psychなどを使う方法があるとのことですが、1.8だと気軽には使えません。

一つすばらしいやり方が紹介されていたのでちょっと改造してみます

http://projectzero-swb.blogspot.jp/2010/06/rubyyaml2.html

  • CentOS5.4
  • ruby1.8.7
#!/usr/bin/env ruby																																											 
# -*- encoding: utf-8 -*-

require "yaml"
require "yaml/encoding"

# String.is_binary_data?で必ずfalseを返すように書き換える
class String
	def is_binary_data?
		return false
	end
end

class Name
	attr_reader:no,:name
	def initialize(no,name)
		 @no=no
		 @name=name
	end
	def to_s
		return @no.to_s+":"+@name.to_s
	end
end

data = {"はつね"=>Name.new(1,"みく"), "はちゅね"=>Name.new(2,"みく"), "かがみね"=>Name.new(3,"りん・
れん"), "めぐりね"=>Name.new(4,"るか")}

# 通常どおり表示
#puts "Escape:"
yaml = YAML.dump(data)

# アンエスケープして表示
#puts "Unescape:"
yaml = YAML.unescape(yaml)

f=open("test3.yaml","w")
f.write(yaml)
f.close

f=YAML.load_file("test3.yaml")
f.each{|k,v|
	puts k+","+v.to_s
}

実行結果

はちゅね,2:みく
めぐりね,4:るか
かがみね,3:りん・れん
はつね,1:みく

test3.yaml

--- 
"はちゅね": !ruby/object:Name
	name: "みく"
	"no": 2
"めぐりね": !ruby/object:Name
	name: "るか"
	"no": 4
"かがみね": !ruby/object:Name
	name: "りん・れん"
	"no": 3
"はつね": !ruby/object:Name
	name: "みく"
	"no": 1

rubyのマルチスレッド

rubyはマルチスレッドのプログラムを書いても、CPUは一個しか使ってくれないらしい。

GIL というもののせいらしい。。

http://ja.wikipedia.org/wiki/グローバルインタプリタロック

そこでマルチプロセスのプログラムを作ってみる

#!/bin/env ruby
class Test
	def exec
		t1=fork{calc}
		t2=fork{calc}
		Process.waitpid t1
		Process.waitpid t2
	end
	def calc
		tim=rand(10)
p Process.pid.to_s+",start,"+tim.to_s
		sleep tim
p Process.pid.to_s+",end,"+tim.to_s
		exit
	end
end

if __FILE__ == $0 then
	Test.new.exec
end