tag:blogger.com,1999:blog-10870057142172530642024-02-08T20:01:28.783+09:00444 Failedsikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.comBlogger29125tag:blogger.com,1999:blog-1087005714217253064.post-14471002676293202352013-03-24T18:26:00.002+09:002013-03-24T18:26:16.758+09:00jquery mobile を使いながら swipe js を使う。jquery mobile を使いながら swipe js を使う。
<ul>
<li>
Swipe の初期化は以下のようなタイミングで行う。pageinit ではなく、pageshow にしないと width がおかしくて表示されない。
<pre class="brush:cpp">
$( '#home' ).live( 'pageshow',function(event){
var elem = document.getElementById('mySwipe');
window.mySwipe = new Swipe(elem, {
// startSlide: 4,
// auto: 3000,
// continuous: true,
// disableScroll: true,
// stopPropagation: true,
// callback: function(index, element) {},
// transitionEnd: function(index, element) {}
});
});
</pre>
<li>
余白が気になる場合は、以下のようなのを追加しておく
<pre class="brush:cpp">
.ui-content{
padding:0;
}
</pre>
</ul>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-61390477650414336432013-01-03T22:17:00.002+09:002013-01-03T22:17:50.033+09:00python で ioctl の値取得 python で ioctl の値取得
<pre class="brush:cpp">
>>> import struct,termios,fcntl
>>> struct.unpack("HH", fcntl.ioctl(0, termios.TIOCGWINSZ, " "))
(33, 108)
</pre>
sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-28637590975354104562012-01-14T14:55:00.007+09:002012-01-14T15:32:57.065+09:00mysql_escape_string と mysql_real_escape_string の違いまとめmysql_escape_string と mysql_real_escape_string の違いを調査したのでまとめる。<br/>
大まかに以下の違いがある
<ul>
<li> mysql_escape_string : 文字コードを気にせず バックスラッシュ escape する
<li> mysql_real_escape_string : DB へ connect した際に取得した文字コードを元に複数バイト文字はエスケープしない。不正な文字はバックスラッシュ escape する
</ul>
バイナリデータを MySQL に入れる際に使用するため、文字コード判定が入ってるというのは意外。
<br>
日本語で最も影響があるのは、SJIS を使ってるときで、「ソフト」を escape してみると、
<pre class="brush:php">
<?php
mysql_connect('DB host', 'user', 'pass');
$ret = mysql_set_charset('sjis');
$str = "\x83\x5c\x83\x74\x83\x67"; // ソフト
echo mysql_escape_string($str), "\n";
echo mysql_real_escape_string($str), "\n";
</pre>
出力は以下のとおり
<pre class="brush:php">
ソ\フト
ソフト
</pre>
<p>
ソ の2バイト目は \ なので mysql_escape_string の方ではエスケープする。
しかし、mysql_real_escape_string の方は文字コード判定するのでエスケープしない。
</p>
ソース見ると latin1 かコネクト時に取得した文字コードを使うかの違い以外は、同じ関数を使って処理してる。
<pre class="brush:php">
// ./libmysql/libmysql.c
1620 ulong STDCALL
1621 mysql_escape_string(char *to,const char *from,ulong length)
1622 {
// default_charset_info は latin1 (1バイトの文字コード(asciiと下位互換))
1623 return (uint) escape_string_for_mysql(default_charset_info, to, 0, from, length);
1624 }
1625
1626 ulong STDCALL
1627 mysql_real_escape_string(MYSQL *mysql, char *to,const char *from,
1628 ulong length)
1629 {
// コネクト時の文字コードを使用
1630 if (mysql->server_status & SERVER_STATUS_NO_BACKSLASH_ESCAPES)
1631 return (uint) escape_quotes_for_mysql(mysql->charset, to, 0, from, length);
1632 return (uint) escape_string_for_mysql(mysql->charset, to, 0, from, length);
1633 }
</pre>
<pre class="brush:php">
//./mysys/charset.c
675 size_t escape_string_for_mysql(CHARSET_INFO *charset_info,
676 char *to, size_t to_length,
677 const char *from, size_t length)
678 {
679 const char *to_start= to;
680 const char *end, *to_end=to_start + (to_length ? to_length-1 : 2*length);
681 my_bool overflow= FALSE;
682 #ifdef USE_MB
// latin1 の場合は use_mb の値が false
683 my_bool use_mb_flag= use_mb(charset_info);
684 #endif
685 for (end= from + length; from < end; from++)
686 {
687 char escape= 0;
688 #ifdef USE_MB
689 int tmp_length;
// 文字コードが複数バイトの場合の処理(複数バイト場合はここで、continue)
690 if (use_mb_flag && (tmp_length= my_ismbchar(charset_info, from, end)))
691 {
692 if (to + tmp_length > to_end)
693 {
694 overflow= TRUE;
695 break;
696 }
697 while (tmp_length--)
698 *to++= *from++;
699 from--;
700 continue;
701 }
// 不正文字の場合の処理
713 if (use_mb_flag && (tmp_length= my_mbcharlen(charset_info, *from)) > 1)
714 escape= *from;
715 else
// 1バイト文字の場合の処理。switch case 使って いくつかの文字だけエスケープ
717 switch (*from) {
718 case 0: /* Must be escaped for 'mysql' */
719 escape= '0';
720 break;
721 case '\n': /* Must be escaped for logs */
722 escape= 'n';
723 break;
724 case '\r':
725 escape= 'r';
726 break;
727 case '\\':
728 escape= '\\';
729 break;
730 case '\'':
731 escape= '\'';
732 break;
733 case '"': /* Better safe than sorry */
734 escape= '"';
735 break;
736 case '\032': /* This gives problems on Win32 */
737 escape= 'Z';
738 break;
739 }
</pre>
<p>
mysql_real_escape_string だと、以下の場合に不具合が起きるかもしれない。
<ul>
<li>データベースの文字コードが SJIS で、バイナリデータに対して、mysql_real_escape_string を使った場合。
</ul>
DB 側での SQLの解析でも同じ文字コード判定をしているなら問題はないが。
</p>
<p>
SJIS は2バイト目に ASCII と文字がかぶってるものがあるから問題となるが、
もうUTF8しか使わないので、文字コード判定なんてしなくてもいいはず。<br>
PHP の関数は deprecated だが、C API の方は「should instead!」と書いてるだけで、使うなとは書いてない。<br>
<a href="http://dev.mysql.com/doc/refman/5.5/en/mysql-escape-string.html">http://dev.mysql.com/doc/refman/5.5/en/mysql-escape-string.html</a><br>
mysql_eacape_string の方は処理がシンプルだし、負荷が大きいような箇所では mysql_escape_string を使うことにしよう
</p>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-5623333828089753142012-01-07T19:32:00.006+09:002012-01-07T21:16:11.382+09:00CentOS 5系に dotcloud のコマンドラインツールを install するpython2.4 しかないので、2.6 系を入れてところから始める。
かなりはまったのでメモ
<br><br>
python 2.6 系を yum で入れる
<pre class="brush:cpp">
$ sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
$ sudo perl -pi -e 's/enabled=1/enabled=0/' /etc/yum.repos.d/epel.repo
$ sudo yum -y install python26 --enablerepo=epel
</pre>
easy_install-2.6 を入れる
<pre class="brush:cpp">
$ wget http://peak.telecommunity.com/dist/ez_setup.py
$ sudo python ez_setup.py
$ sudo python ez_setup.py -U setuptools
</pre>
以下のとおり、/usr/local/bin/easy_install-2.6 が /usr/bin/python を実行してるので、
<pre class="brush:cpp">
$ head -2 /usr/local/bin/easy_install-2.6
#!/usr/bin/python
# EASY-INSTALL-ENTRY-SCRIPT: 'setuptools==0.6c12dev-r88846','console_scripts','easy_install-2.6'
</pre>
python26 を実行するように注意して、pip 入れなおす
<pre class="brush:cpp">
$ sudo pip uninstall pip
$ sudo python26 /usr/bin/easy_install-2.6 pip
</pre>
dotcloud を入れる
<pre class="brush:cpp">
$ sudo pip install dotcloud
</pre>
終わりsikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-7282008927533005462011-11-06T17:44:00.002+09:002011-11-06T18:46:22.195+09:00ImageMagick を使って画像縮小<div>
mixi のログイン用画像が大きいので、ImageMagick を使って縮小する
</div>
<pre class="brush:cpp">
$ wget "http://developer.mixi.co.jp/about-platform/policies/image_guidelines/m_balloon_icon.png"
$ sudo yum install ImageMagick --exclude=*.i386
$ convert -geometry 32x32 m_balloon_icon.png mixi.png
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-33034033440576556472011-11-06T17:37:00.003+09:002011-11-06T18:39:54.400+09:00yum 使用時、64bit環境で i386パッケージをインストールしない<div>
exclude をつける
</div>
<pre class="brush:cpp">
sudo yum install ImageMagick --exclude=*.i386
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-1736194637159659852011-08-07T23:38:00.003+09:002011-08-07T23:43:34.105+09:00PHP の parse_ini_file 調査parse_ini_file が遅い気がするので、調べてみた。
以下、サンプルコード。
<pre class="brush:cpp">
[192.168.162.128] cat parse_ini.php
<?php
$ret1 = parse_ini_file("sample.ini");
$ret2 = parse_ini_file("sample.ini");
[192.168.162.128] cat sample.ini
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
</pre>
parsekit にかけてみると、
<pre class="brush:cpp">
[192.168.162.128] php -r 'var_dump( parsekit_compile_file("parse_ini.php", $error, PARSEKIT_SIMPLE));'
array(10) {
[0]=>
string(37) "ZEND_SEND_VAL UNUSED 'sample.ini' 0x1"
[1]=>
string(42) "ZEND_DO_FCALL T(0) 'parse_ini_file' UNUSED"
[2]=>
string(26) "ZEND_ASSIGN T(1) T(0) T(0)"
[3]=>
string(37) "ZEND_SEND_VAL UNUSED 'sample.ini' 0x1"
[4]=>
string(42) "ZEND_DO_FCALL T(2) 'parse_ini_file' UNUSED"
[5]=>
string(26) "ZEND_ASSIGN T(3) T(0) T(2)"
[6]=>
string(27) "ZEND_RETURN UNUSED 1 UNUSED"
[7]=>
string(42) "ZEND_HANDLE_EXCEPTION UNUSED UNUSED UNUSED"
["function_table"]=>
NULL
["class_table"]=>
NULL
}
</pre>
当たり前かもしれないが、INI ファイルは、opコードに展開されない。つまり、APCではキャッシュしない。
<br>
strace してみると、
<pre class="brush:cpp">
[192.168.162.128] strace php parse_ini.php 2>&1
open("/home/sikaku/dev/fuwarin/trunk/php/exp/ini/sample.ini", O_RDONLY) = 8
fstat(8, {st_mode=S_IFREG|0664, st_size=130, ...}) = 0
lseek(8, 0, SEEK_CUR) = 0
read(8, "[first_section]\none = 1\nfive = 5"..., 8192) = 130
read(8, "", 8192) = 0
read(8, "", 8192) = 0
close(8) = 0
getcwd("/home/sikaku/dev/fuwarin/trunk/php/exp/ini", 4096) = 43
open("/home/sikaku/dev/fuwarin/trunk/php/exp/ini/sample.ini", O_RDONLY) = 8
fstat(8, {st_mode=S_IFREG|0664, st_size=130, ...}) = 0
lseek(8, 0, SEEK_CUR) = 0
read(8, "[first_section]\none = 1\nfive = 5"..., 8192) = 130
read(8, "", 8192) = 0
read(8, "", 8192) = 0
close(8) = 0
</pre>
どうやら、同じファイルにも関わらず毎回パースしてるようだ。sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-69122679394129962772011-03-09T02:16:00.008+09:002011-03-09T04:10:42.888+09:00mysql で永続接続するか、毎回 connect するかmysql で永続接続するか、毎回 connect するかの stack overflow リンク集
<ul>
<li><a href="http://stackoverflow.com/questions/4672713/mysql-connections-should-i-keep-it-alive-or-start-a-new-connection-before-each-t">connection を keep alive するか、new connection を張るか</a>
<li><a href="http://stackoverflow.com/questions/2546868/cheapest-way-to-to-determine-if-a-mysql-connection-is-still-alive">mysql_ping が一番いい</a>
<li><a href="http://stackoverflow.com/questions/1459198/mysql-ping-c-api-fails">8時間後に mysql_ping() が効かない話</a>
<li><a href="http://stackoverflow.com/questions/1455190/how-to-access-mysql-from-multiple-threads-concurrently">マルチスレッドでアクセスする方法</a>
<li><a href="http://dev.mysql.com/doc/refman/5.0/en/threaded-clients.html">20.8.16.2. How to Write a Threaded Client</a>
</ul>
mysql_ping だけなら結構速いので、ping に失敗した時に close して connect し直せば良い。
以下のようなコードで良さそう。
<pre class="brush:cpp">
bool MysqlUtil::init(const char *host, const char *user, const char *pass, const char *dbname){
if( _isInit ){
if(0 == mysql_ping(_mysql) ){
return true;
}
mysql_close(_mysql);
}
_mysql = mysql_init(NULL);
if( !mysql_real_connect(_mysql, host, user, pass, dbname, 0, NULL, 0) ){
fprintf(stderr, "ERROR:mysql_real_connect()\n");
return false;
}
if( 0 != mysql_set_character_set(_mysql, "utf8") ){
fprintf(stderr, "ERROR:mysql_set_character_set()\n");
return false;
}
_isInit = true;
return true;
}
</pre>
mysql 側の設定
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/too-many-connections.html">C.5.2.7. Too many connections</a>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/server-options.html#option_mysqld_open-files-limit">open-files-limit を大きくすべき</a>
<li>
<a href="http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_table_open_cache">table_open_cacheも大きくすべき</a>
<li><a href="http://www.mysqlperformanceblog.com/2006/05/30/innodb-memory-usage/">InnoDB memory usage</a>
</ul>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-87121696229894387412011-02-26T23:26:00.005+09:002011-02-26T23:45:22.986+09:00apache libapreq のソース読み<br />
apacheモジュールでGETやPOSTのパラメータを処理するときは、<a href="http://httpd.apache.org/apreq/docs/libapreq2/">libapreq2</a> を使って、
以下のように書けばよいが、
<pre class="brush:cpp">
apreq_handle_t *hl = apreq_handle_cgi(r->pool);
apr_table_t *params = apreq_params(hl, pool);
</pre>
どこでquery string をパースしてるのかを調べてみた。
<ol>
<li> apreq_handle_t の初期化
<pre class="brush:cpp">
library/module_cgi.c
655 APREQ_DECLARE(apreq_handle_t *)apreq_handle_cgi(apr_pool_t *pool)
671 req->handle.module = &cgi_module;
677 req->args_status =
678 req->jar_status =
679 req->body_status = APR_EINIT;
</pre>
cgi_module がどこにも定義されていないと思ったら以下のMACROが
<pre class="brush:cpp">
653 static APREQ_MODULE(cgi, 20050425);
</pre>
以下に展開される
<pre class="brush:cpp">
static const apreq_module_t cgi_module = { "cgi", 20050425, cgi_jar, cgi_args, cgi_body, cgi_jar_get, cgi_args_get, cgi_body_get, cgi_parser_get, cgi_parser_set, cgi_hook_add, cgi_brigade_limit_get, cgi_brigade_limit_set, cgi_read_limit_get, cgi_read_limit_set, cgi_temp_dir_get, cgi_temp_dir_set, };
</pre>
<li> apreq_params の中身
<pre class="brush:cpp">
library/module.c
32 APREQ_DECLARE(apr_table_t *)apreq_params(apreq_handle_t *req, apr_pool_t *p)
33 {
34 const apr_table_t *args, *body;
35 apreq_args(req, &args);
36 apreq_body(req, &body);
37
38 if (args != NULL)
39 if (body != NULL)
40 return apr_table_overlay(p, args, body);
41 else
42 return apr_table_copy(p, args);
43 else
44 if (body != NULL)
45 return apr_table_copy(p, body);
46 else
47 return NULL;
48
49 }
</pre>
apreq_args が cgi_argsを呼んでGETパラメータ,
apreq_body が cgi_body, cgi_read を呼んでPOSTパラメータに対応する
<li> cgi_args でGETパラメータ初期化
<pre class="brush:cpp">
./library/param.c
140 APREQ_DECLARE(apr_status_t) apreq_parse_query_string(apr_pool_t *pool,
141 apr_table_t *t,
142 const char *qs)
</pre>
<li> cgi_body cgi_read でPOSTパラメータ初期化
mod_apreq を使う場合や、apreq_initialize() を呼んだときに、
以下のパース用関数が、content-type にあわせて用意されている。
<pre class="brush:cpp">
library/parser.c
114 default_parsers = apr_hash_make(default_parser_pool);
115
116 apreq_register_parser("application/x-www-form-urlencoded",
117 apreq_parse_urlencoded);
118 apreq_register_parser("multipart/form-data", apreq_parse_multipart);
119 apreq_register_parser("multipart/related", apreq_parse_multipart);
</pre>
URL エンコードされた POST に対しては以下の関数で処理される。
<pre class="brush:cpp">
./library/parser_urlencoded.c
158 APREQ_DECLARE_PARSER(apreq_parse_urlencoded)
</pre>
</ol>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-22645537471061840052010-12-24T00:37:00.008+09:002010-12-24T01:19:15.572+09:00HipHop for PHP をインストールして apache で proxy してみた<br />
依存関係が相当面倒なので、rpm が用意されている CentOS 5 にインストールすることにした。<br />
CentoOS 5系であれば、以下のようなページも用意されている。<br />
https://github.com/facebook/hiphop-php/wiki/Installing-or-Building-HipHop-PHP-via-RPM-on-CentOS-5
<br />
それでも相当いろんなパッケージを入れないといけない。<br />
<br />
説明のとおり、yum の設定用パッケージなどを以下のとおり実行
<pre class="brush:cpp">
[sikaku@localhost hiphop_rpm]$ sudo rpm -ivh http://epel.osuosl.org/5/x86_64/epel-release-5-4.noarch.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -ivh http://dl.iuscommunity.org/pub/ius/stable/Redhat/5/x86_64/ius-release-1.0-6.ius.el5.noarch.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -ivh http://pkg.tag1consulting.com/hphp/x86_64/hphp-release-1.0-2.el5.noarch.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/x86_64/epel-release-5-3.noarch.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -Uvh http://centos.alt.ru/repository/centos/5/x86_64/centalt-release-5-3.noarch.rpm
[sikaku@localhost hiphop_rpm]$ sudo rpm -Uvh http://dag.wieers.com/rpm/packages/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
[sikaku@localhost hiphop_rpm]$ sudo yum update
</pre>
以下のとおり、大量に yum でパッケージを入れる。
何度もエラーと戦い続けて、以下が必要なことがわかった。
<pre class="brush:cpp">
[sikaku@localhost hiphop_rpm]$ sudo yum install libidn-devel openssl-devel cvs cvsps gcc gcc-c++ libmcrypt zlib-devel automake libmcrypt mhash libtidy mysql
[sikaku@localhost hiphop_rpm]$ sudo yum install cmake mysql-devel pcre-devel gd-devel expat-devel libmcrypt-devel libcap-devel binutils-devel flex tbb-devel
</pre>
以下に用意されているパッケージを全部ダウンロードする。<br />
http://sourceforge.net/projects/hphp/files/CentOS%205%2064bit/
<br />
このダウンロードは、Irvine などでリンクインポートして一括ダウンロードすると良い。<br />
mysqlのライブラリが古いと、エラーが出るので以下だけ、直接 mysql からダウンロードしてくる。
<pre class="brush:cpp">
[sikaku@localhost hiphop_rpm]$ wget "http://dev.mysql.com/get/Downloads/MySQL-5.1/MySQL-shared-community-5.1.54-1.rhel5.x86_64.rpm/from/http://ftp.jaist.ac.jp/pub/mysql/"
</pre>
で、以下のとおりインストール。一部ダウンロードしたファイルで、依存関係が問題で入らないのがあったので、除外している。
<pre class="brush:cpp">
[sikaku@localhost hiphop_rpm]$ sudo rpm -Uvh hiphop-php-1.0-2.x86_64.rpm boost-1.37.0-1.x86_64.rpm libicu-4.2.1-6.x86_64.rpm oniguruma-5.9.2-1.x86_64.rpm php52-5.2.12-1.ius.x86_64.rpm php52-cli-5.2.12-1.ius.x86_64.rpm php52-common-5.2.12-1.ius.x86_64.rpm tbb-2.2-1.20090809.x86_64.rpm php52-mysql-5.2.12-1.ius.x86_64.rpm MySQL-shared-community-5.1.54-1.rhel5.x86_64.rpm php52-pdo-5.2.12-1.ius.x86_64.rpm libxml2-*.rpm boost-devel-1.37.0-1.x86_64.rpm libevent-*.rpm php52-gd-5.2.12-1.ius.x86_64.rpm curl-devel-7.20.0-1hiphop.x86_64.rpm curl-7.20.0-1hiphop.x86_64.rpm icu-4.2.1-6.x86_64.rpm libicu-devel-4.2.1-6.x86_64.rpm oniguruma-devel-5.9.2-1.x86_64.rpm flex-2.5.35-7.x86_64.rpm
</pre>
実際に実行してみた。vm環境で 256M しか割り当ててなかったからか、スワップしまくって7分もかかった。
<pre class="brush:cpp">
[sikaku@localhost dev]$ cat test.php
<?php
echo "hello world!";
?>
[sikaku@localhost dev]$ time hphp test.php
hello world!
real 7m8.916s
user 1m2.269s
sys 0m33.538s
[sikaku@localhost dev]$
</pre>
ポート8999 で起動してみる。
<pre class="brush:cpp">
[sikaku@localhost dev]$ mkdir bin
[sikaku@localhost dev]$ time hphp test.php --keep-tempdir=1 -o bin
hello world!
real 9m0.035s
user 1m5.599s
sys 0m34.827s
[sikaku@localhost dev]$ bin/program -m server -p 8999
Could not mlockall
loading static content...
loading static content took 0'00" (0 ms) wall time
page server started
admin server started
all servers started
</pre>
以下のようにアクセスできる。
<pre class="brush:cpp">
[sikaku@localhost ~]$ curl "http://localhost:8999/test.php"
hello world!
</pre>
続いて、apache の設定を以下のように追加する。mod_rewrite か、mod_proxy で proxy 設定を書く。
<pre class="brush:cpp">
[sikaku@localhost dev]$ cat /etc/httpd/conf.d/custom.conf
#RewriteEngine on
#RewriteRule /(.*) http://localhost:8999/$1 [P,L]
ProxyPassMatch ^/(.*)$ http://localhost:8999/$1
[sikaku@localhost dev]$ sudo /etc/init.d/httpd restart
</pre>
80 ポートからアクセスできた。
<pre class="brush:cpp">
[sikaku@localhost ~]$ curl "http://localhost/test.php"
hello world!
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-10264692251779192732010-12-05T00:01:00.005+09:002010-12-05T00:12:16.552+09:00libev を使った web server Lighttz を make してみた<p>
まずは、libev のインストール
</p>
<pre class="brush:cpp">
[192.168.162.128] cvs -z3 -d :pserver:anonymous@cvs.schmorp.de/schmorpforge co libev
[192.168.162.128] cd libev
[192.168.162.128] autoheader
[192.168.162.128] aclocal
[192.168.162.128] autoconf
[192.168.162.128] touch ltmain.sh
[192.168.162.128] automake -a
[192.168.162.128] ./configure --prefix=$HOME/local
[192.168.162.128] rm libtool
[192.168.162.128] ln -s /usr/bin/libtool libtool
[192.168.162.128] make
[192.168.162.128] make install
</pre>
libtool がうまく動かなかったので置き換え
lighttz の方では、以下のように Makefile を書き換えて gmake
<pre class="brush:cpp">
[192.168.162.128] cat Makefile
lighttz: lighttz.o
gcc -o lighttz ./lighttz.o -L$$HOME/local/lib -lev -u is_default_loop
lighttz.o: lighttz.c
gcc -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"lighttz.d" -MT"lighttz.d" -I../libev -o $@ ./lighttz.c
clean:
rm -f lighttz.o lighttz
start:
LD_LIBRARY_PATH=/home/sikaku/local/lib/ ./lighttz &
</pre>
起動してみる。
<pre class="brush:cpp">
[192.168.162.128] LD_LIBRARY_PATH=/home/sikaku/local/lib/ ./lighttz &
[192.168.162.128] curl http://localhost:8002/
curl: (18) transfer closed with 1 bytes remaining to read
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml" version="-//W3C//DTD XHTML 1.1//EN" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><title>Hello World</title></head><body><p>Hello World</p></body></html>[192.168.162.128]
</pre>
どうやら、1byte 書き出しが少ないようだ。<br />
以下のように修正するとうまくいく
<pre class="brush:cpp">
Index: lighttz.c
===================================================================
--- lighttz.c (revision 103)
+++ lighttz.c (working copy)
@@ -76,7 +76,7 @@
char superjared[]="HTTP/1.1 200 OK\r\nContent-Length: 336\r\nConnection: close\r\nContent-Type: text/html\r\nDate: Sat, 26 Apr 2008 01:13:35 GMT\r\nServer: lighttz/0.1\r\n\r\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\" version=\"-//W3C//DTD XHTML 1.1//EN\" xml:lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><title>Hello World</title></head><body><p>Hello World</p></body></html>";
if (revents & EV_WRITE){
- write(cli->fd,superjared,strlen(superjared));
+ write(cli->fd,superjared,strlen(superjared)+1);
ev_io_stop(EV_A_ w);
}
close(cli->fd);
</pre>
<ul>
<li>lighttz<br />
<a href="http://arekzb.wordpress.com/2008/04/27/lighttz-a-simple-and-fast-web-server/">http://arekzb.wordpress.com/2008/04/27/lighttz-a-simple-and-fast-web-server/</a>
<li>libev<br />
<a href="http://software.schmorp.de/pkg/libev.html">http://software.schmorp.de/pkg/libev.html</a>
<li>
libev のreference など<br />
<a href="http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod">http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod</a>
</ul>
sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-5522430021571894952010-11-07T17:35:00.007+09:002010-11-07T18:05:01.869+09:00apache と nginx から node.js に proxy させる方法<p>
node.js と nginx のインストールメモと、apache と nginx から proxy させる方法メモ
</p>
<h3>node.js のインストール</h3>
<p> git からとってきて ./configure してみる
<pre class="brush:cpp">
cd /home/sikaku/src
git clone git://github.com/ry/node.git
cd node
./configure
</pre>
しかし、環境が古くて ./configure が通らない
<pre class="brush:cpp">
../src/platform_linux.cc: In static member function `static void node::OS::SetProcessTitle(char*)':
../src/platform_linux.cc:29: error: `PR_SET_NAME' was not declared in this scope
Waf: Leaving directory `/home/sikaku/src/node/build'
Build failed: -> task failed (err #1):
{task: cxx platform_linux.cc -> platform_linux_4.o}
gmake: *** [all] Error 1
</pre>
以下を見ると、ほぼ debug 用のようなので、<br />
http://stackoverflow.com/questions/778085/how-to-name-a-thread-in-linux <br />
以下のようなパッチをあててしのぐことにする
<pre class="brush:cpp">
[192.168.162.128] diff -ru src/platform_linux.cc src/platform_linux.cc.NEW
--- src/platform_linux.cc 2010-10-22 11:09:49.000000000 +0900
+++ src/platform_linux.cc.NEW 2010-10-22 11:09:46.000000000 +0900
@@ -26,7 +26,7 @@
void OS::SetProcessTitle(char *title) {
if (process_title) free(process_title);
process_title = strdup(title);
- prctl(PR_SET_NAME, process_title);
+// prctl(PR_SET_NAME, process_title);
}
</pre>
openssl が入っていなかったので、yum install しておく
<pre class="brush:cpp">
sudo yum install openssl-devel
</pre>
ようやく make install まで成功
<pre class="brush:cpp">
./configure
make
sudo make install
</pre>
以下のようなコードを書いて、実行してみる
<pre class="brush:cpp">
[192.168.162.128] cat http.js
var sys = require('sys'),
http = require('http'),
port = 8000;
http.createServer(function(request, response) {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.end( request.url + ' - Hello World\n');
}).listen(port);
sys.puts('Server listening on port ' + port);
</pre>
起動してみる
<pre class="brush:cpp">
node http.js &
</pre>
アクセスしてみる
<pre class="brush:cpp">
[192.168.162.128] curl "http://192.168.162.128:8000/test"
/test - Hello World
</pre>
<h3>apache から node.js に proxy させる</h3>
rewrite で P をフラグをつければいいだけ
<pre class="brush:cpp">
[192.168.162.128] cat /etc/httpd/conf.d/custom.conf
RewriteEngine on
RewriteRule /(.*) http://192.168.162.128:8000/$1 [P,L]
</pre>
再起動
<pre class="brush:cpp">
sudo //etc/init.d/httpd restart
</pre>
apache にアクセスすると動いた。
<pre class="brush:cpp">
[192.168.162.128] curl "http://192.168.162.128/test"
/test - Hello World
</pre>
<h3>nginx のインストール</h3>
まったく問題なく make install まで成功した
<pre class="brush:cpp">
cd /home/sikaku/src
wget "http://www.nginx.org/download/nginx-0.8.53.tar.gz"
tar zxvf nginx-0.8.53.tar.gz
cd nginx-0.8.53
./configure
make
sudo make install
</pre>
ポートを変えて起動してみる
<pre class="brush:cpp">
[192.168.162.128] diff -ru /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.NEW
--- /usr/local/nginx/conf/nginx.conf 2010-10-22 13:38:25.000000000 +0900
+++ /usr/local/nginx/conf/nginx.conf.NEW 2010-10-22 13:38:33.000000000 +0900
@@ -33,7 +33,7 @@
#gzip on;
server {
- listen 80;
+ listen 8001;
server_name localhost;
#charset koi8-r;
</pre>
アクセスしてみる。
<pre class="brush:cpp">
[192.168.162.128] curl "http://192.168.162.128:8001/"
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>
</body>
</html>
</pre>
<h3>nginx から node.js に proxy させる</h3>
以下のように、nginx.conf を書き換えて、nginx を再起動する
<pre class="brush:cpp">
[192.168.162.128] cat /usr/local/nginx/conf/nginx.conf | perl -nle 'print unless(/\s*#/ || /^\s*$/)'
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8001;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location ~ .*$ {
proxy_pass http://192.168.162.128:8000;
}
}
}
</pre>
問題なく動いた
<pre class="brush:cpp">
[192.168.162.128] curl "http://192.168.162.128:8001/test"
/test - Hello World
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-70669372614264495412010-10-10T14:10:00.003+09:002010-10-10T14:12:54.613+09:00NICの設定を表示する: linux<p>
NICの設定を確認する方法。
<pre class="brush:cpp">
[sikaku@localhost ~]$ sudo /sbin/ethtool eth0
Settings for eth0:
Supported ports: [ MII ]
Supported link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Supports auto-negotiation: Yes
Advertised link modes: 10baseT/Half 10baseT/Full
100baseT/Half 100baseT/Full
1000baseT/Full
Advertised auto-negotiation: Yes
Speed: 100Mb/s
Duplex: Full
Port: MII
PHYAD: 19
Transceiver: external
Auto-negotiation: on
Supports Wake-on: g
Wake-on: d
Link detected: yes
</pre>
ethtool は、表示と設定変更を行える
<pre class="brush:cpp">
[sikaku@localhost ~]$ whatis ethtool
ethtool (8) - Display or change ethernet card settings
ethtool (rpm) - Ethernet settings tool for PCI ethernet cards
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-60481814823043593322010-08-08T00:30:00.008+09:002010-08-08T01:22:29.571+09:00convert integer to std::string<p>
int型変数を std::string に変換する方法を考えてみた。
</p>
<p>
C言語で、char * にするなら、反射的に、sprintf などを使うと思うが、
std::string に入れたいときに一番いい方法はあまり思いつかない。
今回は、いくつか案を考えて実際に家のPCで計測してみた。
以下のような関数をそれぞれ定義して、計測する。<br />
<pre class="brush:cpp">
void func(int num, std::string &str);
</pre>
</p>
<p>
計測に使った関数は以下のとおり。
getMicroTime はマイクロタイムを取得する関数。
</p>
<pre class="brush:cpp">
void testCount(const char *msg, int count, void (*func)(int, std::string &)){
std::string str;
int num;
long start, ustart, end, uend;
getMicroTime(start, ustart);
for(int i=-count; i< count; i++){
num = i;
(*func)(num, str);
}
getMicroTime(end, uend);
double i = (end - start) * 1000000;
double f = uend - ustart;
printf("%s time:%lf\n", msg, (i+f)/2/count );
}
</pre>
<h3>[1]std::streamstring を使う</h3>
一番 C++ らしい方法はこれかもしれない。
<pre class="brush:cpp">
void intToString1(int num, std::string &str){
std::stringstream ss;
ss << num;
str = ss.str();
}
</pre>
しかし、今回調べた中で最も遅かった。
<h3>[2]sprintf を使う</h3>
C言語のスタンダードな方法だと思う。
<pre class="brush:cpp">
void intToString2(int num, std::string &str){
char buf[32];
sprintf(buf, "%d", num);
str = buf;
}
</pre>
[1]に比べたら、5~6倍ぐらい早かった
<h3>[3]10 のmodulo演算を使用</h3>
modulo 演算で、1の位から順に決定していく。
<pre class="brush:cpp">
void intToString3(int num, std::string &str){
int snum = num;
if(num<0)
snum = ~num + 1;
char buf[12];
char *ptr = buf+11;
*ptr = '\0';
while(snum > 0){
*(--ptr) = '0' + snum % 10;
snum /= 10;
}
if(num<0)
*(--ptr) = '-';
str = ptr;
}
</pre>
[2]よりも、2~3倍速い
<h3>[4]長さを求めて、引数のstd::string に直接書き込む</h3>
作業用バッファを用意するのではなく、引数の std::string に直接書き込む方法とした。
<pre class="brush:cpp">
void intToString4(int num, std::string &str){
int snum = num & 0x80000000 ? ~num + 1 : num;
int len = snum < 10000 ? (snum < 100 ? ( snum < 10 ? 1 : 2 ) : snum < 1000 ? 3 : 4)
: snum < 100000000 ? (snum < 1000000 ? ( snum < 100000 ? 5 : 6 ) : snum < 10000000 ? 7 : 8)
: snum < 1000000000 ? 9 : 10;
if(num & 0x80000000)
++len;
str.resize(len);
while(snum > 0){
str[--len] = '0' + snum % 10;
snum /= 10;
}
if(num & 0x80000000)
str[0] = '-';
}
</pre>
[3]よりもだいたい 1.5 倍くらい早い
<h3>[5]std::string::data() で内部メモリに直接書く</h3>
[4]を修正し、str.data() で取得したアドレスに直接書いてみた。
<pre class="brush:cpp">
int snum = num & 0x80000000 ? ~num + 1 : num;
int len = snum < 10000 ? (snum < 100 ? ( snum < 10 ? 1 : 2 ) : snum < 1000 ? 3 : 4)
: snum < 100000000 ? (snum < 1000000 ? ( snum < 100000 ? 5 : 6 ) : snum < 10000000 ? 7 : 8)
: snum < 1000000000 ? 9 : 10;
if(num<0)
++len;
str.resize(len);
char *ptr = (char *)str.data()+len;
while(snum > 0){
*(--ptr) = '0' + snum % 10;
snum /= 10;
}
if(num & 0x80000000)
*(--ptr) = '-';
}
</pre>
[4]より1.2倍くらい早くなった。
<h3>[6]再度sprintf</h3>
内部メモリに直接書く方法で、sprintf を使う方法にしてみた。
<pre class="brush:cpp">
void intToString6(int num, std::string &str){
int snum = num & 0x80000000 ? ~num + 1 : num;
int len = snum < 10000 ? (snum < 100 ? ( snum < 10 ? 1 : 2 ) : snum < 1000 ? 3 : 4)
: snum < 100000000 ? (snum < 1000000 ? ( snum < 100000 ? 5 : 6 ) : snum < 10000000 ? 7 : 8)
: snum < 1000000000 ? 9 : 10;
if(num<0)
++len;
str.resize(len);
char *ptr = (char *)str.data()+len;
sprintf(ptr, "%d", num);
}
</pre>
[5]に比べると、5倍~6倍くらい遅くなってしまった。
<h3>[7]大きい位の数から順に決めていく</h3>
長さを先に決めているので、大きい位から代入していくことにした。
<pre class="brush:cpp">
void intToString7(int num, std::string &str){
int snum = num & 0x80000000 ? ~num + 1 : num;
int len = snum < 10000 ? (snum < 100 ? ( snum < 10 ? 1 : 2 ) : snum < 1000 ? 3 : 4)
: snum < 100000000 ? (snum < 1000000 ? ( snum < 100000 ? 5 : 6 ) : snum < 10000000 ? 7 : 8)
: snum < 1000000000 ? 9 : 10;
if(num & 0x80000000)
++len;
str.resize(len);
char *ptr = (char *)str.data()-1;
if( num & 0x80000000 ){
*(++ptr) = '-';
--len;
}
int one;
if( len > 9 )
one = snum / 1000000000, *(++ptr) = '0' + one, snum -= 1000000000 * one;
if( len > 8 )
one = snum / 100000000, *(++ptr) = '0' + one, snum -= 100000000 * one;
if( len > 7 )
one = snum / 10000000, *(++ptr) = '0' + one, snum -= 10000000 * one;
if( len > 6 )
one = snum / 1000000, *(++ptr) = '0' + one, snum -= 1000000 * one;
if( len > 5 )
one = snum / 100000, *(++ptr) = '0' + one, snum -= 100000 * one;
if( len > 4 )
one = snum / 10000, *(++ptr) = '0' + one, snum -= 10000 * one;
if( len > 3 )
one = snum / 1000, *(++ptr) = '0' + one, snum -= 1000 * one;
if( len > 2 )
one = snum / 100, *(++ptr) = '0' + one, snum -= 100 * one;
if( len > 1 )
one = snum / 10, *(++ptr) = '0' + one, snum -= 10 * one;
*(++ptr) = '0' + snum;
}
</pre>
これが、今回最も早い方法で、[5]よりも少し速くなった。
<h3>[8]少し改良</h3>
[7]を while を使って、キレイに書いてみた。
<pre class="brush:cpp">
void intToString8(int num, std::string &str){
static int tens[]={ 0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
int snum = num & 0x80000000 ? ~num + 1 : num;
int len = snum < 10000 ? (snum < 100 ? ( snum < 10 ? 1 : 2 ) : snum < 1000 ? 3 : 4)
: snum < 100000000 ? (snum < 1000000 ? ( snum < 100000 ? 5 : 6 ) : snum < 10000000 ? 7 : 8)
: snum < 1000000000 ? 9 : 10;
if(num & 0x80000000)
++len;
str.resize(len);
char *ptr = (char *)str.data();
if(num & 0x80000000){
*(ptr++) = '-';
--len;
}
--ptr;
int one = 0;
int *tptr = &tens[len];
while(*(--tptr)){
one = snum / *tptr;
*(++ptr) = '0' + one;
snum -= *tptr * one;
}
*(++ptr) = '0' + snum;
}
</pre>
なぜか、このコードは比較的遅いという結果になった。
配列tensから値を引くところが遅いようである。
[7]を配列tensを使うように変えると遅くなり、O2か、O3を指定すると[7]と同じ速度になった。
<p>
以上の計測結果は以下のとおり。
</p>
<pre class="brush:html">
./out speed (最適化コンパイルなし )
intToString1 time:1.052384
intToString2 time:0.232779
intToString3 time:0.114349
intToString4 time:0.127272
intToString5 time:0.095429
intToString6 time:0.214056
intToString7 time:0.073023
intToString8 time:0.186148
./out1 speed ( -O コンパイルオプション )
intToString1 time:0.745957
intToString2 time:0.215731
intToString3 time:0.066834
intToString4 time:0.042813
intToString5 time:0.031119
intToString6 time:0.177850
intToString7 time:0.036448
intToString8 time:0.116570
./out2 speed ( -O2 コンパイルオプション )
intToString1 time:0.714182
intToString2 time:0.223773
intToString3 time:0.062432
intToString4 time:0.048148
intToString5 time:0.033870
intToString6 time:0.192560
intToString7 time:0.032088
intToString8 time:0.115626
./out3 speed ( -O3 コンパイルオプション )
intToString1 time:0.780855
intToString2 time:0.201429
intToString3 time:0.061252
intToString4 time:0.048085
intToString5 time:0.034723
intToString6 time:0.186857
intToString7 time:0.032486
intToString8 time:0.115503
</pre>
<p>
こうしてみると、最速の[7] が、stringstream [1] よりも 20倍くらい異なる結果となった。
しかし単位はマイクロタイムなので、少し改良したところで大した差にはならない上、現状でもかなり速い。
改善するなら、全てビット演算だけで記述できればもっと改善できるかもしれない。
</p>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-19902940023292219102010-08-08T00:26:00.003+09:002010-08-08T00:29:39.318+09:00C言語(C++)で microtime を取得する<p>
C言語で microtime を計算する方法が分からなかったので調べてみた。
</p>
<pre class="brush:html">
#include <sys/time.h>
static long start, end;
void getMicroTime(long &sec, long &usec ){
struct timeval now;
int rv = gettimeofday(&now, 0);
if (rv != 0){
sec = 0;
usec = 0;
return;
}
sec = now.tv_sec;
usec = now.tv_usec;
}
double getMicroTimeDouble(){
struct timeval now;
int rv = gettimeofday(&now, 0);
if (rv != 0){
return 0;
}
return (double)now.tv_sec + (double)now.tv_usec / 1000000;
}
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-33591243874478337902010-08-02T04:18:00.005+09:002010-08-02T04:27:02.348+09:00zlib の deflate inflate sample<p>
zlib を少し調べたので、std::string に対して、
deflate と inflate を行うクラスを作ってみた。
</p>
//ZlibUtil.h
<script type="syntaxhighlighter" class="brush: html">
#include <stdio.h>
#include <string.h>
#include <string>
#include "zlib.h"
#define CHUNK 16384
class ZlibUtil{
public:
inline int def(const std::string &src, std::string &dst, int level=6);
inline int inf(const std::string &src, std::string &dst);
};
int ZlibUtil::def(const std::string &src, std::string &dst, int level){
dst = "";
char in[CHUNK+1];
char out[CHUNK+1];
//
// allocate deflate state
//
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
int ret = deflateInit(&strm, level);
if( ret != Z_OK ){
return ret;
}
int start = 0;
int srclen = src.length();
const char *srcptr = src.c_str();
int flush = Z_NO_FLUSH;
while(start < srclen ){
int cplen = srclen - start;
if( cplen > CHUNK ){
cplen = CHUNK;
}
memcpy(in, srcptr+start, cplen);
in[cplen] = '\0';
start += cplen;
if( start >= srclen ){
flush = Z_FINISH;
}
strm.avail_in = cplen;
strm.next_in = (unsigned char *)in;
do {
strm.avail_out = CHUNK;
strm.next_out = (unsigned char *)out;
ret = deflate(&strm, flush); /* no bad return value */
if( ret == Z_STREAM_ERROR ){
return ret;
}
int have = CHUNK - strm.avail_out;
out[have] = '\0';
dst += std::string(out, have);
} while (strm.avail_out == 0);
}
(void)deflateEnd(&strm);
return Z_OK;
}
int ZlibUtil::inf(const std::string &src, std::string &dst){
dst = "";
int ret;
char in[CHUNK+1];
char out[CHUNK+1];
//
// allocate inflate state
//
z_stream strm;
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
int start = 0;
int srclen = src.length();
const char *srcptr = src.c_str();
while(start < srclen ){
int cplen = srclen - start;
if( cplen > CHUNK ){
cplen = CHUNK;
}
memcpy(in, srcptr+start, cplen);
start += cplen;
in[cplen] = '\0';
strm.avail_in = cplen;
strm.next_in = (unsigned char *)in;
do {
strm.avail_out = CHUNK;
strm.next_out = (unsigned char *)out;
ret = inflate(&strm, Z_NO_FLUSH);
if( ret == Z_STREAM_ERROR ){
return ret;
}
int have = CHUNK - strm.avail_out;
out[have] = '\0';
dst += out;
} while (strm.avail_out == 0);
}
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
</script>
//ZlibUtilTest.cc
<pre class="brush:html">
#include "ZlibUtil.h"
int main(int argc, char **argv)
{
int ret;
ZlibUtil zlib;
std::string from, to;
from = "あいうえおあいうえおあいうえおあいうえおあいうえお";
ret = zlib.def(from, to, 9);
printf("compress=%s %d\n", to.c_str(), to.length());
ret = zlib.inf(to, from);
printf("decompress=%s %d\n", from.c_str(), from.length());
}
</pre>
<pre class="brush:html">
[sikaku@localhost compress]$ ./zlibutil
compress=xレ{ワリア蚋cロ翦?])・27
decompress=あいうえおあいうえおあいうえおあいうえおあいうえお 75
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-41462539312795474162010-08-02T04:05:00.005+09:002010-08-02T04:28:08.772+09:00difference between strncpy and memcpy<p>
思いっきりはまってしまったので、メモ。
strncpy と memcpy の違い。
</p>
<p>
strncpy は、src 側の文字列に(途中に) \0 が含まれると、copy をやめてしまう。
</p>
<p>
また、当たり前だが、const char * を string のコンストラクタに入れると、
\0 まで読み込んで止まってしまうので、サイズも一緒に入れてやるとよい。
</p>
<script type="syntaxhighlighter" class="brush: html">
#include <stdio.h>
#include <string>
int main(){
char in[8] = {'0', '1', '2', '\0', '4', '5', '6', '\0'};
char memcpy_data[8] = {0};
char strncpy_data[8] = {0};
memcpy(memcpy_data, in, 8);
for(int i=0;i<8;i++){
printf("%c ", memcpy_data[i]);
}
puts("");
strncpy(strncpy_data, in, 8);
for(int i=0;i<8;i++){
printf("%c ", strncpy_data[i]);
}
puts("");
std::string collect_str;
collect_str = std::string(memcpy_data, 8);
printf("%d \n", collect_str.length());
std::string wrong_str;
wrong_str = memcpy_data;
printf("%d \n", wrong_str.length());
}
</script>
<pre class="brush:html">
[sikaku@localhost compress]$ ./a.out
0 1 2 4 5 6
0 1 2
8
3
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-9747799075416550842010-07-25T19:35:00.006+09:002010-07-25T20:31:12.909+09:00linux で /usr/local/lib を search library path に追加<p>
共有オブジェクトの search library path に /usr/local/lib を追加し、
また、その際、reboot 時にも反映されるようにする。
さらに、/etc/ld.so.cache を更新する。
</p>
<pre class="brush:html">
echo -e "/usr/local/lib/" | sudo tee /etc/ld.so.conf.d/local_lib.conf
sudo /sbin/ldconfig
</pre>
<p>
一時的に追加するだけなら、以下のようにする
</p>
<pre class="brush:html">
sudo /sbin/ldconfig /usr/local/lib
</pre>
<p>
参考<br />
<a href="http://www.eyrie.org/~eagle/notes/rpath.html">http://www.eyrie.org/~eagle/notes/rpath.html</a>
</p>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-54619107685944974322010-07-20T02:31:00.003+09:002010-07-20T02:41:25.659+09:00tdb を 64bit 対応にする<p>
tdb(Trivial Database) は、dbm の一種で、key/value の形でデータを保存できる。
install の仕方は、以下のとおり
</p>
<pre class="brush:html">
以下から download する
http://sourceforge.net/projects/tdb/
$ wget "http://downloads.sourceforge.net/project/tdb/tdb/1.0.6/tdb-1.0.6.tar.gz?use_mirror=jaist&ts=1279553081"
$ tar zxvf tdb-1.0.6.tar.gz
$ cd tdb-1.0.6
$ ./configure --prefix=$HOME/local --host="i860-linux-gnu" --enable-shared
$ perl -pi -e 's/$/\\n\\/ if( $.>=172 && $.<=187)' tdbtool.c
$ perl -pi -e 's/#define u32 unsigned/#define u32 unsigned long long/' tdb.h
$ make
$ make install
</pre>
<p>
tdb は、ファイル1つに対しデータベースを作っており、offset と size でデータを取り出したり、
保存したりしている。
offset の指定が unsigned int になっているので、4GB を超えるあたりで、動かなくなる問題があったので、
改善方法を考えてみた。
</p>
<p>
offset は u32 型で定義しているので、以下のようにmacroを書き換えればよい
</p>
<pre class="brush:html">
$ perl -pi -e 's/#define u32 unsigned/#define u32 unsigned long long/' tdb.h
</pre>
<p>
正常に動くかどうかは、以下のプログラムを動かして確認した。
</p>
<pre class="brush:html">
$ cat tdb_overflow.cc
#include <stdio.h>
#include <string>
#include "tdb.h"
#include <fcntl.h>
#include <stdarg.h>
using namespace std;
#define TDB_DB "tdb.db"
#define TDB_HASH_SIZE 2000*10000
void log(TDB_CONTEXT *tdb, int Num, const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
void get_tdb_val(TDB_CONTEXT *tdb, int num, TDB_DATA *tkey, TDB_DATA *tvalue){
static string pre_key = "";
static string pre_value = "";
if( "" == pre_key ){
pre_key = "key";
}
if( "" == pre_value ){
for(int i=0;i<100*5000;++i){
pre_value += "0123456789";
}
}
char numStr[1024];
snprintf(numStr, 1024, "%d", num);
static string key;
key = pre_key + numStr;
tkey->dptr = (char *)key.c_str();
tkey->dsize = key.length() + 1;
static string value;
value = pre_value + numStr;
tvalue->dptr = (char *)value.c_str();
tvalue->dsize = value.length() + 1;
}
int main(){
printf("tdb file:%s\n", TDB_DB);
printf("hash size:%u\n", TDB_HASH_SIZE);
TDB_CONTEXT *tdb;
tdb = tdb_open_ex(TDB_DB, TDB_HASH_SIZE, TDB_CLEAR_IF_FIRST|TDB_NOMMAP, O_RDWR|O_CREAT, S_IRWXU, &log);
if(NULL == tdb){
fprintf(stderr, "can't open tdb\n");
return -1;
}
// set
TDB_DATA tkey;
TDB_DATA tvalue;
for(int i=0;i<1000;++i){
get_tdb_val(tdb, i, &tkey, &tvalue);
if(0 != tdb_store(tdb, tkey, tvalue, TDB_INSERT)){
printf("fault. key:%s val:%s\n", tkey.dptr, tvalue.dptr);
continue;
}
printf("success set %d\n", i);
}
// get
for(int i=0;i<1000;++i){
TDB_DATA tret;
get_tdb_val(tdb, i, &tkey, &tvalue);
tret = tdb_fetch(tdb, tkey);
if( strcmp(tvalue.dptr, tret.dptr) ){
printf("fault. key:%s val:%s ret:%s\n", tkey.dptr, tvalue.dptr, tret.dptr);
continue;
}
delete tret.dptr;
printf("success. get %d\n", i);
}
tdb_close(tdb);
printf("success end.\n");
}
</pre>
<pre class="brush:html">
$ cat Makefile
INCDIR=/home/sikaku/local/include
LIBDIR=/home/sikaku/local/lib
default: all
tdb_overflow:tdb_overflow.cc
g++ -g -I$(INCDIR) -L$(LIBDIR) -ltdb tdb_overflow.cc -o $@
all:tdb_overflow
clean:
rm ./tdb_overflow
test:
LD_LIBRARY_PATH=$(LIBDIR) ./tdb_overflow
</pre>
<p>
5160394752byte の tdb.db が作成されて、正常に終了した。
</p>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-62725077114972045852010-06-08T02:02:00.004+09:002010-06-08T02:05:35.035+09:002ch の live28 httpd.conf 設定2ch の最新 live28 サーバの httpd.conf の設定
<pre class="brush:html">
<IfModule mpm_prefork_module>
StartServers 704
MinSpareServers 703
MaxSpareServers 704
ServerLimit 704
MaxClients 704
MaxRequestsPerChild 10000
MaxMemFree 2000
</IfModule>
</pre>
64bit で mpm-worker にすれば 700 も子プロセス(スレッド)増やせれるのか。
仕事でセットアップしてる apache は MaxClients 32 しかないのだが・・。sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-35694082427232460692010-06-03T01:00:00.007+09:002010-06-03T01:05:58.034+09:00指定したコマンドを daemon で起動するプログラム(c 言語)指定したコマンドを daemon で起動するプログラムを作ってみた。
<pre class="brush:html">
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void usage(){
printf("usage: daemon [command]+\n");
}
int main(int argc, char *argv[]) {
if( argc < 2 ){
usage();
exit(1);
}
pid_t pid;
pid = fork();
if (pid < 0) {
fprintf(stderr, "cant fork()\n");
exit(1);
} else if (pid > 0) {
// end parent process
exit(0);
}
umask(0);
pid_t sid = setsid();
if (sid < 0) {
fprintf(stderr, "cant setsid()\n");
exit(1);
}
if ((chdir("/")) < 0) {
fprintf(stderr, "cant chdir()\n");
exit(1);
}
int i;
for (i=getdtablesize();i>=0;--i){
close(i);
}
// handle standard I/O
i=open("/dev/null",O_RDWR);
dup(i);
dup(i);
// execute command, and don't return
execvp(argv[1],argv+1);
return 0;
}
</pre>
参考ページ<p>
<a href="http://systhread.net/texts/200506cdaemon1.php">http://systhread.net/texts/200506cdaemon1.php</a><br>
<a href="http://www.enderunix.org/documents/eng/daemon.php">http://www.enderunix.org/documents/eng/daemon.php</a><br>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-76954861268880892662010-05-17T00:54:00.008+09:002010-05-17T01:13:08.813+09:00使いやすそうなカラーピッカーを作ってみた<p>
YUIの colorpicker + button をちょっと修正しました。<br>
サンプル<br>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.8.1/build/assets/skins/sam/skin.css">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/fonts/fonts-min.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.1/build/yahoo-dom-event/yahoo-dom-event.js&2.8.1/build/element/element-min.js&2.8.1/build/button/button-min.js&2.8.1/build/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/slider/slider-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/colorpicker/colorpicker-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/container/container_core-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/menu/menu-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/button/button-min.js"></script>
<style type="text/css">
body {
margin:0;
padding:0;
}
div.yuimenu .bd {
zoom: normal;
}
.current-color {
display: block;
width: 1em;
height: 1em;
overflow: hidden;
text-indent: 1em;
background-color: #fff;
white-space: nowrap;
border: solid 1px #000;
}
.yui-menu-button-menu .yui-picker-controls,
.yui-menu-button-menu .yui-picker-swatch,
.yui-menu-button-menu .yui-picker-websafe-swatch {
display: none;
}
.yui-skin-sam .yui-button{
background:none;
border:none;
margin:0;
}
.yui-skin-sam .yui-button .first-child{
background:none;
border:none;
}
.yui-skin-sam .yui-menu-button button{
background:none;
margin:0;
padding:0;
}
</style>
<div class="yui-skin-sam">
<script type="text/javascript">
YAHOO.namespace('ypicker');
YAHOO.ypicker = function(container, input){
this.container = container;
this.input = input;
this.menu = YAHOO.util.Dom.generateId();
this.button = YAHOO.util.Dom.generateId();
this.pickerContainer = YAHOO.util.Dom.generateId();
this.pickerMenu = YAHOO.util.Dom.generateId();
this.currentColor = YAHOO.util.Dom.generateId();
YAHOO.util.Event.onContentReady(this.container, this.bind(this.init));
}
YAHOO.ypicker.prototype = {
bind:function(func, args){
if('undefined' == typeof args){
args = [];
}
var self = this;
return function(){
return func.apply(self, args);
};
},
onButton:function(){
if( this.isColorPickerInit ){
return;
}
this.isColorPickerInit = true;
this.oColorPicker = new YAHOO.widget.ColorPicker(this.oColorPickerMenu.body.id, {
showcontrols: false,
images: {
PICKER_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/picker_thumb.png",
HUE_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/hue_thumb.png"
}
});
this.oColorPicker.on("rgbChange", this.bind(function(e){
var sColor = "#" + this.oColorPicker.get("hex");
this.oColorPicker.set("value", sColor);
YAHOO.util.Dom.setStyle(this.currentColor, "backgroundColor", sColor);
YAHOO.util.Dom.get(this.input).value = sColor;
}));
},
init:function(){
// Create a Menu instance to house the ColorPicker instance
this.oColorPickerMenu = new YAHOO.widget.Menu(this.pickerMenu);
// Create a Button instance of type "split"
this.oButton = new YAHOO.widget.Button({
type: "menu",
id: this.button,
label: '<span id="'+this.currentColor+'" class="current-color"></span>',
menu: this.oColorPickerMenu,
container: this.container });
this.oButton.on("appendTo", this.bind(function () {
this.oColorPickerMenu.setBody(" ");
this.oColorPickerMenu.body.id = this.pickerContainer;
YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'width', '220px');
YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'height', '190px');
// Render the Menu into the Button instance's parent element
this.oColorPickerMenu.render(this.oButton.get("container"));
}));
this.isColorPickerInit = false;
this.oButton.on("click", this.bind(this.onButton));
}
}
</script>
<script>
(new YAHOO.ypicker("ybutton", "ybutton-value")),
(new YAHOO.ypicker("ybutton2", "ybutton-value2"));
</script>
<input id="ybutton-value" type="text" style="font-size:11px;"/><span id="ybutton"></span>
<input id="ybutton-value2" type="text" style="font-size:11px;"/><span id="ybutton2"></span>
</div>
<pre class="brush:html">
<script type="syntaxhighlighter" class="brush:html">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.8.1/build/assets/skins/sam/skin.css">
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.1/build/fonts/fonts-min.css" />
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.8.1/build/yahoo-dom-event/yahoo-dom-event.js&2.8.1/build/element/element-min.js&2.8.1/build/button/button-min.js&2.8.1/build/dragdrop/dragdrop-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/slider/slider-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/colorpicker/colorpicker-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/container/container_core-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/menu/menu-min.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.8.1/build/button/button-min.js"></script>
<style type="text/css">
body {
margin:0;
padding:0;
}
div.yuimenu .bd {
zoom: normal;
}
.current-color {
display: block;
width: 1em;
height: 1em;
overflow: hidden;
text-indent: 1em;
background-color: #fff;
white-space: nowrap;
border: solid 1px #000;
}
.yui-menu-button-menu .yui-picker-controls,
.yui-menu-button-menu .yui-picker-swatch,
.yui-menu-button-menu .yui-picker-websafe-swatch {
display: none;
}
.yui-skin-sam .yui-button{
background:none;
border:none;
margin:0;
}
.yui-skin-sam .yui-button .first-child{
background:none;
border:none;
}
.yui-skin-sam .yui-menu-button button{
background:none;
margin:0;
padding:0;
}
</style>
<div class="yui-skin-sam">
<script type="text/javascript">
YAHOO.namespace('ypicker');
YAHOO.ypicker = function(container, input){
this.container = container;
this.input = input;
this.menu = YAHOO.util.Dom.generateId();
this.button = YAHOO.util.Dom.generateId();
this.pickerContainer = YAHOO.util.Dom.generateId();
this.pickerMenu = YAHOO.util.Dom.generateId();
this.currentColor = YAHOO.util.Dom.generateId();
YAHOO.util.Event.onContentReady(this.container, this.bind(this.init));
}
YAHOO.ypicker.prototype = {
bind:function(func, args){
if('undefined' == typeof args){
args = [];
}
var self = this;
return function(){
return func.apply(self, args);
};
},
onButton:function(){
if( this.isColorPickerInit ){
return;
}
this.isColorPickerInit = true;
this.oColorPicker = new YAHOO.widget.ColorPicker(this.oColorPickerMenu.body.id, {
showcontrols: false,
images: {
PICKER_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/picker_thumb.png",
HUE_THUMB: "http://developer.yahoo.com/yui/build/colorpicker/assets/hue_thumb.png"
}
});
this.oColorPicker.on("rgbChange", this.bind(function(e){
var sColor = "#" + this.oColorPicker.get("hex");
this.oColorPicker.set("value", sColor);
YAHOO.util.Dom.setStyle(this.currentColor, "backgroundColor", sColor);
YAHOO.util.Dom.get(this.input).value = sColor;
}));
},
init:function(){
// Create a Menu instance to house the ColorPicker instance
this.oColorPickerMenu = new YAHOO.widget.Menu(this.pickerMenu);
// Create a Button instance of type "split"
this.oButton = new YAHOO.widget.Button({
type: "menu",
id: this.button,
label: '<span id="'+this.currentColor+'" class="current-color"></span>',
menu: this.oColorPickerMenu,
container: this.container });
this.oButton.on("appendTo", this.bind(function () {
this.oColorPickerMenu.setBody(" ");
this.oColorPickerMenu.body.id = this.pickerContainer;
YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'width', '220px');
YAHOO.util.Dom.setStyle( this.oColorPickerMenu.body, 'height', '190px');
// Render the Menu into the Button instance's parent element
this.oColorPickerMenu.render(this.oButton.get("container"));
}));
this.isColorPickerInit = false;
this.oButton.on("click", this.bind(this.onButton));
}
}
</script>
<script>
(new YAHOO.ypicker("ybutton", "ybutton-value")),
(new YAHOO.ypicker("ybutton2", "ybutton-value2"));
</script>
<input id="ybutton-value" type="text" style="font-size:11px;"/><span id="ybutton"></span>
<input id="ybutton-value2" type="text" style="font-size:11px;"/><span id="ybutton2"></span>
</div>
</script>
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-54437147337765623182010-05-09T19:15:00.002+09:002010-05-09T19:21:46.225+09:00ループバック用のIPアドレスの割り当て方(linux編)<p>
ループバック用のIPアドレスの割り当て方。<br>
とりあえず、192.56.76.4 に割り当ててみる。
<pre class="brush:cpp">
$ sudo /sbin/route add -host 192.56.76.4 dev eth0
$ sudo /sbin/ifconfig eth0:0 192.56.76.4
</pre>
ping を送ってみる。
<pre class="brush:cpp">
$ ping 192.56.76.4 -c 1
PING 192.56.76.4 (192.56.76.4) 56(84) bytes of data.
64 bytes from 192.56.76.4: icmp_seq=1 ttl=64 time=0.073 ms
--- 192.56.76.4 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.073/0.073/0.073/0.000 ms
</pre>
成功した。
<p>
削除するときは、
<pre class="brush:cpp">
$ sudo /sbin/route del -host 192.56.76.4 dev eth0
$ sudo /sbin/ifconfig eth0:0 down
</pre>
route は、ネットマスクを使って以下のように書いてもいい
<pre class="brush:cpp">
sudo /sbin/route add -net 192.56.76.0 netmask 255.255.255.0 dev eth0
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-75075368390566981022010-04-26T02:04:00.003+09:002010-04-26T02:05:53.547+09:00UnitTestしやすいクラスの作り方<p>
以下の要約。<br>
<a href="http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/">http://misko.hevery.com/2008/07/08/how-to-think-about-the-new-operator/</a>
<p>
Unit Test しやすいクラスは、クラス間の依存グラフにおいて、
終端に位置するクラス(以下、leafクラス)である。
なぜなら、それだけを Unit Test することができるから。
例えば、以下のようなクラス。
<pre class="brush:cpp">
class House {
private boolean isLocked;
private boolean isLocked() {
return isLocked;
}
private boolean lock() {
isLocked = true;
}
}
</pre>
<p>
しかし、以下のようなクラスでは、Kitchenクラスを生成せずに、
House クラスだけを生成できない。
理由は、House のロジック内に、Kitchen の new 演算子が
含まれているから。
そのため、House クラスのみを Unit Test することができない。
<pre class="brush:cpp">
class House {
private final Kitchen kitchen = new Kitchen();
private boolean isLocked;
private boolean isLocked() {
return isLocked;
}
private boolean lock() {
kitchen.lock();
isLocked = true;
}
}
</pre>
<p>
Houseだけを個別に Unit Test するには、偽の Kitchen
で、Houseを生成する必要がある。
<pre class="brush:cpp">
class House {
private final Kitchen kitchen;
private boolean isLocked;
public House(Kitchen kitchen) {
this.kitchen = kitchen;
}
private boolean isLocked() {
return isLocked;
}
private boolean lock() {
kitchen.lock();
isLocked = true;
}
}
</pre>
<p>
上のように、new演算子をロジックから取り除けば、
テストを簡単に行える。
Kitchen のモックを作れば、Houseだけを Unit Test できる。
これにより、leaf クラスでなくても、個別にテストを行える。
<p>
どこで、new演算子を使えばいいかというと、
以下のようにFactoryクラスを作ってやればよい。
<pre class="brush:cpp">
class ApplicationBuilder {
House build() {
return new House(new Kitchen(
new Sink(),
new Dishwasher(),
new Refrigerator())
);
}
}
</pre>
<p>
Main メソッドでは、このFactoryを使ってオブジェクトの依存関係を
生成すればよい。
<pre class="brush:cpp">
class Main {
public static void main(String...args) {
House house = new ApplicationBuilder().build();
house.lock();
}
}
</pre>sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0tag:blogger.com,1999:blog-1087005714217253064.post-87059378069990030242010-04-26T00:19:00.013+09:002010-04-26T01:01:46.552+09:00コードがシンプルで多機能なlight box系js<p>
コードがシンプルで多機能なlight box系js<br />
<a href="http://colorpowered.com/colorbox/">http://colorpowered.com/colorbox/</a>
<p>
<a class="colorbox1" href="http://www.google.com/">サンプル</a>
<link type="text/css" media="screen" rel="stylesheet" href="http://sikaku-chat.com/stt/colorbox/colorbox.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://sikaku-chat.com/stt/colorbox/jquery.colorbox.js"></script>
<script type="text/javascript">
$(".colorbox1").colorbox({height:"90%", width:"90%", iframe:true});
</script>
<script type="syntaxhighlighter" class="brush:html">
<a class="colorbox1" href="http://www.google.com/">サンプル</a>
<link type="text/css" media="screen" rel="stylesheet" href="http://sikaku-chat.com/stt/colorbox/colorbox.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="http://sikaku-chat.com/stt/colorbox/jquery.colorbox.js"></script>
<script type="text/javascript">
$(".colorbox1").colorbox({height:"90%", width:"90%", iframe:true});
</script>
</script>
<p>
iframe なども画像と同じように表示できたり、動的に生成されるURLに対しても問題なく使える。
ソース読み込み以外で js を書いてるところをタグ内に完全に埋めれるようにしたり、コード内でべた書き class 名を使ってしまってるところをキレイにしたい。
あと、会社でYUIを使ってるのでYUIバージョンを作りたい。sikaku444http://www.blogger.com/profile/14040328832586055409noreply@blogger.com0