2013年3月28日木曜日

UTF16化は正しい判断か?

私の作ってるC++の組版系S/Wは、UTF16で動作している。
しかし、今まではWindows系だったので、wchar_tでやっていた。

さて、こつこつとLINUX対応をしているのだが、どうにも美しくできない。
自分で、codingしてみて、はじめて、やっと、【PHP6の内部UTF16化計画頓挫】の意味がわかった気がした。

そもそも、組版というカテゴリの場合、サロゲートペアがあるかぎり、内部は最後にはUTF32でするべきだという結論はかわらない。
問題は、その上の部分だ。
そもそも、今時のUbuntuで、defaultで、strlen("あ")とやると、3が返ってくる。
だからというわけではないが、UTF8で実装するのが素直なとこなのかもしれない。

といったところで、UTF16で書いた部分を、UTF8で書き直してみて、美しいかどうか判定することにする。
やっぱり書いてみないとダメ。

まず書く。
まずcodingする。
まずやってみる。

全てを見通した設計ができほど、私は、頭がイイわけではないのだから。。。(-_-;)


2013年3月22日金曜日

C++でJSONを扱う件(3)

C++でJSONを扱う件(3)
JSONファイルそのものをどうやって読めばいいのかって点ですが。。。
ところで話は変わって、【オブジェクト指向】ってあるじゃないですか。
よく、直感的に、思考に近い形でとか言いますよね。
CODINGは、要するに、object指向かどうかが問題なのではなくて、
頭でわかりやすいかどうかです。
単純なものほどわかりやすいのは至極当然。
よって、TREE構造のものを読み込むことを考えたときに、、
全て展開したTREEを、上から1行ずつ読み込んでいくような、そんな感じで読み込みましょう。

ポイントは、いくつかの文字の判定とその分岐です。
考えるのは、、
【"】【:】【{】【}】【[】【]】【,】
の7つだけです。
といったところで、こんな感じでつくってみました。

//wpは文字列の配列
for(int w=0;wp[w]!=0;w++){
 if(ダブルクォーテーション){
  //-----------------------------
  if(bIn){
   // ここで文字列が終わるので、文字列の特定
  }
  //-----------------------------
  else{
   // 文字列の始まりを憶えて置く
  }
  //-----------------------------
  bIn = ! bIn;
 }
 if(bIn) continue;//次へ
 else if(コロン){     // 【:】
  // キーを確定させる
  // 値の開始位置を覚える
 }
 else if(中カッコ開始){    // 【{】
  // 現在のobjectをPUSHする
  // 現在のobjectの下にobjectを生成してそれを現在のobjectにする
 }
 else if(中カッコ終了){    // 【}】
  //キーと値を調べて、少なくとも値があったら現在のobjectに登録
  //キーは無い場合もある
  //現在のobjectをひとつPOPする
 }
 else if(大カッコ開始){    // 【[】
  // 現在のobjectをPUSHする
  // 現在のobjectの下にobjectを生成してそれを現在のobjectにする
 }
 else if(大カッコ終了){    // 【]】
  //キーと値を調べて、少なくとも値があったら現在のobjectに登録
  //キーは無い場合もある
  //現在のobjectをひとつPOPする
 }
 else if(カンマ){     // 【,】
  //キーと値を調べて、少なくとも値があったら現在のobjectに登録
  //キーは無い場合もある
 }
 //-----------------------------
}
/*
 ポイント
 文字列を判断すること
 キーと値を判断すること
*/
まぁ、昔ながらのよくある方法ですが、文字列の始まりの【"】のところを憶えておき、終わりの【"】の部分に\0を突っ込んで、char*(wchar_t*)で読むっていう算段です。
値については、【"】ではじまるかどうかで、文字列かどうかを判定するわけですね。
もちろん、このLOOPに入る前に、\\と\"をなんらかの方法で退避させ、値をobjectに登録するときに戻してやりますよ。。

たぶん、つづく。。。

2013年3月21日木曜日

C++でJSONを扱う件(2)

C++でJSONを扱う件(2)

STEP2
で、object型ですが、ここでは簡略化して、以下のように考えます。


struct objson{
    objson* parent; //    親
    objson* child;  //    子
    objson* prev;   //    兄
    objson* next;   //    弟
    char*   value;  //    データ部
    char    dat[4]; //    key部
    //その他いろいろあるけど省略
    objson& operator[](const char* c);   //["abc"]とかのため
    operator char*();                    //キャストするため
    void operator=(char* cp);            //代入するため
};

これは、objectのデータ長さが一定ではないためです。
もちろん、構造体のメンバの中に、VARIANT的な値をもつという方法もありますが、ここでは面倒になるのでやりません。
よって、bool/int/doulbeとかであれば、まぁあっても8バイトなわけなので、最初から確保するという荒業もありますが、文字列だとそうはいきません。
よって、こんな風に生成してみます。
int size = sizeof(objson) + strlen(moji) + strlen(key);
char* p = new char[size];
memset(p,0,size);
objson* o = (objson*)p;


keyを設定するには、datへcopy、値を設定するには、valueのポインタを設定してからstrcpyします。
strcpy(o->dat,key);
o->value = &o->dat[strlen(key)+1];
strcpy(o->value,value);

長さを算定してメモリを確保し、それにobjson*でキャストしています。

例えば、メモリ管理を自分で書けば、メモリを連続させたりすることもできるし、不要なnew-deleteを考えなくてもすみます。

ここでは、keyになる文字列と値になる文字列の分を足して、メモリを確保しています。


生成したあとは、parent/child/prev/nextを設定して階層をつくってやれば、
o->child->child->child
なんて指定も可能になります。

つづく。。

C++でJSONを扱う件。

C++でJSONを扱う件です。
もちろん、
double pw = doc.info.pw;
のような形でアクセスできればCODINGもラクですが、
structやらclassやらを専用に準備してなきゃできないわけで、
動的には無理なわけです。

ということで、いろんなパーサとかを見てまわったのですが、
なかなかイイ感じのものがない。
『どうする?』   →つくりましょう!

『だれがやる?』 →私でしょう!
『いつやるか?』 今でしょう!











ということで、つくりました。
といっても、上記のようにはできるわけもなく、ここはPHP方式でやります。
即ち、
double pw = doc.info.pw;
ではなく、

double pw = D["doc"]["info"]["pw"];
って形です。


STEP1
STEP1は、当然ながら、object型みたいなものを定義するところから始まります。
クラスでも構造体でもかまいませんが(C++において、classとSTRUCTはほとんど同じ)、
DOM的に、親、子、兄、弟を参照するポインタをもつobjectを定義すればいいのです。
さらに、このOBJECTを生成するようなコンテナもあったほうが、あとあと便利なので、そこからつくります。
即ち、
objectContainer C;
objson& o = *C.createObjectJson();
o["doc"]["info"]["pw"] = 297.0;
みたいな使い方です。
こうしておけば、Cのデストラクタで、createされたobjectをキレイに破棄できますよね。

。。つづく。。

2013年3月19日火曜日

mのn乗回LOOPをまわす方法。

mのn乗回LOOPをまわす方法な件なんですけどねー。
いやいや、
v = m * n;
for(int w=0;w<v;w++){
なんて、そんな話じゃないですよ。
だって、longとかlong longに収まる範囲でしかできない方法じゃダメなんですよ。
だからっていって、下手に再帰させるのもダメですよ。stackOverFlowもあるしね。
って、どんだけ大きな数を扱おうとしてるかって話でもなく、
ここでは、再帰よりも『美しく』codingしましょう。

ということで、やりかたはわからなかったのですが、
なんとなくcodingしてたら、案の定できました。
基本的には、タイガー計算機の如く、1ケタづつLOOPする変数を準備すればいいだけです。
まぁ制限としては、nもmもintの範囲っていうくらいの制限はありますが。^^;

で、できたのがこれ。
これなら、1000の1000乗のLOOPでもまわせます。そんなことしたら、おわりませんけど。
loopFuncが関数、countUpがサブの関数、theFuncsがテストなCallBack関数。
typedef int (*func1)(int*,int);

int countUp(int* dat,int mmm,int nnn){
    for(int w=0;w<nnn;w++){
        dat[w]++;
        if(dat[w] < mmm){
            return true;
        }
        dat[w] = 0;
    }
    return false;
}
int theFuncs(int* ip,int n){
    static int counter = 0;
    printf("<%d> ",counter++);
    for(int w=n-1;w>=0;w--){
        printf("[%d]",ip[w]);
    }
    printf("\n");
    return 0;
}
void loppFunc(int mmm,int nnn,func1 f){
    int* dat = new int[nnn];
    memset(dat,0,sizeof(int)*nnn);
    do{
        f(dat,nnn);
    }while( countUp(dat,mmm,nnn) );
    delete[] dat;
}
loppFunc(10,3,theFuncs);//呼び出し方

ケタの数だけ、配列して、関数に渡します。←日本語おかしいな^^;^^;
まぁどんな言語でもいけるっちゃいけますけど、かなり用途は狭いでしょうし、、ホントに巨大な数だけLOOPするようなものを、C(C++)以外でつくることも、そうそうないでしょうし。
あ、すんません。Fortranとかは授業でしかやったことないんで^^;使ったことないっすー。。。

2013年3月12日火曜日

スマフォWEBアプリで写真をタイル表示させる件。(2)

ということで、タイル状に配置する件ですが、タテ長の場合、ヨコ長の場合に、
おおまかに言えば、【必ず入るように配置】の場合と、【部分的に正方形で表示】の場合が考えられます。まぁやりかたとしては大してかわりませんが、
【必ず入るように配置】は、以下ですね。



そして、部分画像と割り切って、正方形としてしまうのが、以下です。
スマフォのアプリなんかはこっちです。


もちろん、部分画像にした方が、切れてしまう部分はあるものの、
解像度としては高くなり有利ではあります。
でも、それは、写真の一覧だからであって、何かしらの選択の場合に、やはり全体をみて欲しいときもあります。その場合は前者になりますね。

どっちにしてもPHPでの実装は非常に簡単で、まず前者の場合。
【画像をLOAD】→【タテとヨコを測る】→【タテヨコ大きい方の数値で正方形の画像を生成】
→【LOADした画像を中央に配置】→【作成した画像をそのまま出力】
で完成。
後者の場合も、
【画像をLOAD】→【タテとヨコを測る】→【タテヨコ小さい方の数値で正方形の画像を生成】
→【LOADした画像を中央に配置】→【作成した画像をそのまま出力】

ということで、正方形にする時の辺の長さをどこをとるかだけの差です。
もちろんその場合に、サムネイル用の場合を考えれば、
あえて、縮小した大きさの正方形で作成するというのも、用途によってはアリですね。

ということで、PHPを。
エラー処理とかしてませんので(-_-;)

 // $fn:ファイルパス
 $localimage = imagecreatefrompng($fn);  // PNGの時
// $localimage = imagecreatefromjpeg($fn); // JPEGの時
 //------------------
 $ww = imagesx ( $localimage );
 $hh = imagesy ( $localimage );
 //------------------
 if($ww > $hh){
  $hh2 = $ww;
  $ww2 = $ww;
 }else{
  $ww2 = $hh;
  $hh2 = $hh;
 }
 //------------------
 $image   = imagecreatetruecolor($ww2, $hh2);
 $bgColor  = imagecolorallocate($image, 0x0, 0x0, 0x0);
 imagefill($image, 0, 0, $bgColor);   // 背景を塗ってから
// imagecolortransparent($image,$bgColor);  // 透明にしたいとき
 $bb = imagecopy($image, $localimage, 
   (int)(($ww2 - $ww)/2), (int)(($hh2 - $hh)/2),   // COPY先
   0, 0,            // COPY元
   $ww, $hh);
 if(is_resource ( $localimage )) imagedestroy($localimage);
 header('Content-type: image/jpeg');
 imagejpeg($img);

2013年3月8日金曜日

スマフォWEBアプリで写真をタイル表示させる件。

スマフォのアプリの写真をviewするやつなんか見ると、
当然のように、一覧表示があります。
一覧はだいたいタイル状になっていて、その中に画像が縮小されて表示されてる。
まぁ、あたりまえのコトのように実装されてますよね。


いや、でも、しかし、、、←今でしょう!とかじゃなくて、、、
これを、WEBアプリでやろうとすると、、いやぁー。。大変です。
そもそも、とある矩形にピッタリに入るように、タテまたはヨコを縮小表示させるなんて、
CSS的には、いくら探しても無いわけで。
じゃぁどうする!作りましょう!PHP側で。

ってコトで、2通り考えます。
ひとつは、jpegで表示。
ひとつは、pngで表示。
jpegだと透過できないので、bgcolorとあわせる必要がある。
pngだと容量が大きくなる。


 まぁ、使い分けを考えて両方できるようにしましょう。

つづく。

2013年3月6日水曜日

An active access token must be used to query information about the current user.な件。


FaceBook連携のWEBアプリを作ってるときの話なのですが。。
An active access token must be used to query information about the current user.
というエラー。
出ました。ご他聞にもれず。
で、いろいろ情報収集。
まぁここらへんからたどれば、解決しそうな感じはしたのです。
http://fb.dev-plus.jp/forum/topic.php?id=67
でも、いっこうに改善されず。

ところが、ひょんなことから、localhost連携だと成功。
WEBサーバだと失敗。
んーーーー。よくある。それだ!
ってことで、WEBサーバ、リバースプロキシしてるんですよね。
だから、PHP、で$_SERVER['HTTP_HOST']がサーバ名になってまうわけです。
で、GREP。
その結果、以下のコードを発見。
  protected function getHttpHost() {
    if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
      return $_SERVER['HTTP_X_FORWARDED_HOST'];
    }
    return $_SERVER['HTTP_HOST'];
  }
コンストラクタにたは、
    if (isset($config['trustForwarded']) && $config['trustForwarded']) {
      $this->trustForwarded = true;
    }
そっか。ってことで、無事に、コンストラクタを以下にすることにより、解決。
 $facebook = new Facebook(array(
  'appId'  => $appId,
  'secret' => $secret,
  'trustForwarded' => true,
  'cookie' => true
 ));

でも、'trustForwarded'でぐぐっても、日本語情報、ほとんど皆無っすー。

2013年3月5日火曜日

iPhoneブラウザでのwindows.close

iPhoneブラウザでのwindows.closeのできる時、できないの判断がわからない。

●このhtml(PHP)、iPhoneだとDownloadにならずにjpegが表示されてしまう!
header( "Content-Type: application/octet-stream");
header( "Content-Disposition: attachment; filename={$filename}.jpg");
@readfile($jpegfile);

2013年3月1日金曜日

●このjavascript、iPhoneのサファリでフリーズ!

●このjavascript、iPhoneのサファリでフリーズ!
※name=uploadはfile。
$(function(){
    $('input[name=upload]').change(function() {
  var size = this.files[0].size;
  alert(size);
...略...

で結局、JSONPathのラッパークラスを書く。。(2)

●使い方サンプル
まぁ問題は、JSONPathのpathの文字列に慣れてないことくらい^^;^^;
 
 $p = new gJPath;
 $jstr = file_get_contents(******************);
 $json = json_decode($jstr,true);

 $p->setJson($json);
// $p->json = json_decode($jstr,true); //まぁこれでも同じですが。。

 $xpath = "$..name";
 $v = $p->getValueOne($xpath); // 所得

 $xpath = "$..layers.[*].name";
 $v = $p->getValueOne($xpath); // 所得

 $xpath = "$..imgurl";
 $v = $p->getValueOne($xpath); // 所得

 $xpath = "$..layers.[*].name"; // 配列として所得
 $v = $p->getValue($xpath);
 foreach($v as $one) echo "【{$one}】";//表示させてみたりとか

 $xpath = "$..layers.[*].name";
 $v = $p->getPathOne($xpath);

 $xpath = "$..layers.[*].items[?(@['name']=='札文字')]";
 $v = $p->getValueOne($xpath); // 所得
 $v = $p->getValue($xpath); // 配列として所得

 $xpath = "$..name";
 $p->setValue($xpath,"new 'Name' DA\\YO!");//一括更新

 $xpath = "$..items[?(@['name']=='札文字')]";
 $patstr = $p->getPathOne($xpath);
 $patstr .= "['mtext']";
 $v = $p->getValueDirect($patstr);  // patstrから値を所得
 $p->setValueDirect($patstr,"でへへへ!");// patstrから値を設定
 $v = $p->getValueDirect($patstr); // patstrから値を所得(当然かわっている)
●クラス
 require_once "./jsonpath-0.8.1.php";
 //---------------------------------------
class gJPath{
 public $json;   // object
 //-------------------------
 /* 初期値 */
 //-------------------------
 function __construct(){
  $this->json = null;
 }
 //-------------------------
 // objectをセットする
 //-------------------------
 public function setJson(&$v){
  $this->json = &$v; // ここで&を忘れちゃダメよ。
 }
 //-------------------------
 function __destruct(){
  // とりあえず特にやることなし。
 }
 //-------------------------
 // マッチしたものを返す。
 // falseでなければ、Arrayを返す
 //-------------------------
 public function getValue($pat){
  $match = jsonPath($this->json, $pat);
  return $match;
 }
 //-------------------------
 // マッチしたものを返す。
 // falseか値かどっちかを返す。
 // $patが必ず1コか0コが確定している場合とかに使う。
 //-------------------------
 public function getValueOne($pat){
  $match = $this->getValue($pat);
  if($match == false) return false;
  return $match[0];
 }
 //-------------------------
 // マッチしたPATHを返す。
 // falseでなければ、Arrayを返す
 //-------------------------
 public function getPath($pat){
  $match = jsonPath($this->json, $pat, array("resultType" => "PATH"));
  return $match;
 }
 //-------------------------
 // 
 //-------------------------
 public function getPathOne($pat){
  $match = $this->getPath($pat);
  if($match == false) return false;
  return $match[0];
 }
 //-------------------------
 // マッチするものに全て値を設定する。
 //-------------------------
 public function setValue($pat,$value){
  $match = $this->getPath($pat);
  if($match != false){
   foreach($match as $u){
    $this->setValueDirect($u,$value);
   }
  }
 }
 //-------------------------
 // 【$['abc'][0]】のような文字列と値を引数にしてセットする。
 // arrayとかをvalueにするなよ!
 // $pathはパターンじゃないから注意!
 //-------------------------
 public function setValueDirect($path,$value){
  $evalstr = "\x24this->json" . substr($path,1);
  $valuestr = "";
  if(is_string($value)){
   $value = preg_replace("/\x5c\x5c/", "\x5c\x5c\x5c\x5c",$value);  // 【\】 を 【\\】 にする
   $value = preg_replace("/\x27/",  "\x5c\x27",$value);    // 【'】 を 【\'】 にする
   $valuestr = "'{$value}'";
  }else{
   $valuestr = "{$value}";
  }
  @eval("{$evalstr}={$valuestr};");
 }
 //-------------------------
 // $pathはパターンじゃないから注意!
 //-------------------------
 public function getValueDirect($path){
  $evalstr = "\x24this->json" . substr($path,1);
  @eval("\x24v={$evalstr};");
  return $v;
 }
 //-------------------------

JSONPathのサイトの説明の間違い。


いやいや。。。。。
ライブラリの説明サンプルが、しっかり間違っていたのか、
それとも、仕様が変わったのにサンプルを修正していなかったのか、、
こぉーゆーことがあるとちょっとめげますが。。。。
http://goessner.net/articles/JsonPath
ということで、正誤表。
priceが10以下をselectするJSONPathですが。。。(-_-;)

誤: $..book[?(@.price<10)]

正: $..book[?(@['price']<10)]

です。