webAi.Tools - ソースコード

説明

Web AI」は、クロノス・クラウンの柳井政和が開発しているJavaScirptのライブラリです。「Web AI」を使うと、Web上からデータを取得して構築するWebページを、とても簡単に構築することができます。

「Web AI」は、Webからの検索結果やフィードの取得、短縮URLへのURLの変換、日本語文章からのキーワードや文章抽出、日本語文章のマルコフ連鎖、クエリーの管理などの機能を備えています。

このページでは、この「Web AI」のファイルの1つである「crocro.webAi.Tools.js」のソースコードを掲載します。

「crocro.webAi.Tools.js」

「crocro.webAi.Tools.js」には、URLのクエリーを便利に操作する機能がまとまっています。また、その他の雑多な機能も、このファイルには収録されています。「crocro.webAi.Tools.js」では主に、以下の2つの機能をサポートします。

URLクエリーの解析と構築。 URLクエリーの圧縮と解凍。

「crocro.webAi.Tools.js」は、その他のファイルとは違い、複数のオブジェクトが収録されています。収録されているオブジェクトは以下になります。

crocro.webAi.Tools crocro.webAi.Query crocro.webAi.Cmprs crocro.webAi.Base64 *crocro.webAi.Lzw

この内、ユーザーが実際に使用するのは、「crocro.webAi.Tools」「crocro.webAi.Query」の2つになります。その他は内部処理用のオブジェクトです。

「crocro.webAi.Query」を利用すれば、HTMLのクエリーを簡単に操作することができます。

使い方は、「Web AI」の各サンプルを参考にしてください。

ソースコード

以下、「crocro.webAi.Tools.js」のソースコードです。

/*    Web AI <http://crocro.com/write/web_ai/wiki.cgi>
    is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
    in a Japanese translation <http://sourceforge.jp/projects/opensource/wiki/licenses%2FMIT_license>
    Copyright (c) 2010 Masakazu Yanai / (c) 2010 Cronus Crown <webmaster@crocro.com>
*/

    // crocro.webAiの初期化
    if (! crocro) var crocro = {};
    if (! crocro.webAi) crocro.webAi = {};

    /**
     *    @variable    crocro.webAi.Tools
     *    @title    ツール群
     *    @description
     *
     *        プログラム記述用のツール群。
     *        newで初期化せずにそのまま利用する。
     */
    crocro.webAi.Tools = new function() {
        // 内部利用変数
        var majorVersion = "1";
        var minorVersion = "1";

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Tools.getVer()
         *    @title    バージョン取得
         *    @description
         *
         *        バージョン情報を取得する。
         *
         *    @return    バージョン情報。
         */
        this.getVer = function() {
            return majorVersion + "." + minorVersion;
        }

        /**
         *    @variable    Tools.getMajorVer()
         *    @title    メジャー・バージョン取得
         *    @description
         *
         *        メジャー・バージョン情報を取得する。
         *
         *    @return    メジャー・バージョン。
         */
        this.getMajorVer = function() {
            return majorVersion;
        }

        /**
         *    @variable    Tools.getMinorVer()
         *    @title    マイナー・バージョン取得
         *    @description
         *
         *        マイナー・バージョン情報を取得する。
         *
         *    @return    マイナー・バージョン。
         */
        this.getMinorVer = function() {
            return minorVersion;
        }

        /**
         *    @variable    Tools.isLocal()
         *    @title    ローカルの判定
         *    @description
         *
         *        ローカルか否かを戻す。
         *
         *    @return    ローカルか否か(true/false)。
         */
        this.isLocal = function() {
            if (location.protocol.indexOf("file") != 0) return false;    // ネット上
            return true;    // ローカル
        }

        /**
         *    @variable    Tools.getObjInf(obj, eleId)
         *    @title    オブジェクト情報の取得
         *    @description
         *
         *        オブジェクトのプロパティと内容(ハッシュのキーと値)を取得/挿入する。
         *
         *    @param    obj        表示するオブジェクト。
         *    @param    eleId    要素を挿入するエレメントID。指定がある場合は、その場所に整形済みHTMLを挿入する。
         *    @return    作成した文字列。
         */
        this.getObjInf = function(obj, eleId) {
            var resArr = [];
            if (! obj) return "";

            for (var key in obj) {
                resArr.push("key : " + key + " / " + typeof(obj[key]) + " / " + obj[key]);
            }

            if (eleId) {
                document.getElementById(eleId).innerHTML
                    = "<ul><li>"
                    + resArr.join("</li><li>")
                    + "</li></ul>";
            }

            // 戻り値を戻して終了
            var resStr = resArr.join("\n");
            return resStr;
        }

        /**
         *    @variable    Tools.shffl(srcArr)
         *    @title    配列シャッフル
         *    @description
         *
         *        シャッフルした配列を新たに作成して戻す。
         *
         *    @param    srcArr        元配列。
         *    @return    シャッフルした配列。
         */
        this.shffl = function(srcArr) {
            var resArr = srcArr.concat();

            var i = resArr.length;
            while (--i) {
                var j = Math.floor(Math.random() * (i + 1));
                if (i == j) continue;
                var k = resArr[i];
                resArr[i] = resArr[j];
                resArr[j] = k;
            }

            return resArr;
        }

        /**
         *    @variable    Tools.unq(srcArr)
         *    @title    配列ユニーク
         *    @description
         *
         *        ユニークにした配列を新たに作成して戻す。
         *
         *    @param    srcArr        元配列。
         *    @return    ユニークにした配列。
         */
        this.unq = function(srcArr) {
            var resArr = [];
            var hash = {}

            for (var i = 0; i < srcArr.length; i ++) {
                if (! srcArr[i] || srcArr[i] == 0) continue;
                hash[srcArr[i]] = 1;
            }
            for (var key in hash) {
                resArr.push(key);
            }

            return resArr;
        }
    }

    /**
     *    @variable    crocro.webAi.Query(arg)
     *    @title    クエリー
     *    @description
     *
     *        クエリーを抽象化するためのオブジェクト。Webページの「?」以降の値を、連想配列に格納する。
     *        「?」以降がない場合は「#」以降を対象にする。
     *        newで初期化してから利用する。
     */
    crocro.webAi.Query = function(arg) {
        // 内部利用変数
        var hash = {};
        var urlBdy = null;

        /**
         *    @variable    Query.cmprsKe
         *    @title    圧縮クエリー用キー
         *    @description
         *        圧縮クエリー使用時の、クエリーのキー。
         *
         *        デフォルトは「_cmp」。
         *        圧縮クエリー使用時には、「_cmp=~」といったクエリーになる。
         */
        this.cmprsKey = "_cmp";

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Query.set(key, prm)
         *    @title    データの書き込み
         *    @description
         *
         *        「hash」にデータを書き込む。
         *
         *    @param    key        キー。
         *    @param    prm        値。
         *    @return    なし。
         */
        this.set = function(key, prm) {
            hash[key] = prm;
        }

        /**
         *    @variable    Query.get(key)
         *    @title    データの読み込み
         *    @description
         *
         *        「hash」からデータを読み込む。
         *
         *    @param    key        キー。
         *    @return    値。
         */
        this.get = function(key) {
            if (! (key in hash)) return "";
            var resStr = hash[key]
                .replace(/&/g, "&")
                .replace(/</g, "<")
                .replace(/>/g, ">");
            return resStr;
        }

        /**
         *    @variable    Query.getRaw(key)
         *    @title    生データの読み込み
         *    @description
         *
         *        「hash」からデータをエスケープなしで読み込む。
         *        通常はセキュリティのために「get」の方を利用する。
         *
         *    @param    key        キー。
         *    @return    値。
         */
        this.getRaw = function(key) {
            if (! (key in hash)) return "";
            return hash[key];
        }

        /**
         *    @variable    Query.isKey(key)
         *    @title    キーの存在確認
         *    @description
         *
         *        「hash」内に、指定の「key」があるか確認する。
         *
         *    @param    key        キー
         *    @return    キー存在の有無(true/false)
         */
        this.isKey = function(key) {
            return (key in hash);
        }

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Query.prsFrmLocation(arg)
         *    @title    locationからのパース
         *    @description
         *
         *        locationからパースして、クエリーのハッシュを作成する。
         *
         *        Webページの「?」以降の値を、連想配列に格納する。
         *        指定によっては、「?」以降がない場合は「#」以降を対象にする。
         *
         *    @param    arg.useQ    クエリーの利用(true/false)デフォルトはyes。
         *    @param    arg.useH    ハッシュの利用(true/false)デフォルトはno。ローカルのデバッグ用。
         *    @return    なし。
         */
        this.prsFrmLocation = function(arg) {
            if (! arg) arg = {};        // 引数なしなら初期化
            arg.url = location.href;
            this.prsFrmUrl(arg);
        };

        /**
         *    @variable    Query.prsFrmUrl(arg)
         *    @title    URLからのパース
         *    @description
         *
         *        URLからパースして、クエリーのハッシュを作成する。
         *
         *        Webページの「?」以降の値を、連想配列に格納する。
         *        指定によっては、「?」以降がない場合は「#」以降を対象にする。
         *
         *    @param    arg.url        URL文字列。
         *    @param    arg.useQ    クエリーの利用(true/false)デフォルトはyes。
         *    @param    arg.useH    ハッシュの利用(true/false)デフォルトはno。ローカルのデバッグ用。
         *    @return    URL本体を戻す。
         */
        this.prsFrmUrl = function(arg) {
            // ユーザー変数
            var url  = "";            // URL
            var useQ = true;        // クエリーの利用(true/false)デフォルトはyes。
            var useH = false;        // ハッシュの利用(true/false)デフォルトはno。ローカルのデバッグ用。

            // ユーザー変数の設定
            if (arg) {
                if ("url"  in arg) url  = arg.url;
                if ("useQ" in arg) useQ = arg.useQ;
                if ("useH" in arg) useH = arg.useH;
            }
            if (! url || url == "") return "";

            // クエリーの取り出し
            var b = "" + (url.match(/^.+(?:[\?#])/) || url);    // URL本体の取得
            var q = "" + (url.match(/\?.+(?:#|$)/) || "");        // クエリーの取得
            var h = "" + (url.match(/#[^#].+$/) || "");            // ハッシュの取得

            if (useQ && q != "") {
                q = q.replace(/^\?/, "");    // 先頭の?の除去
            } else
            if (useH && h != ""){
                q = h.replace(/^#/, "");    // 先頭の#の除去
            }

            // URLの格納
            b = b.replace(/[\?#].*$/g, "");
            urlBdy = b;
            //alert("url " + url + "\nb " + b + "\nq " + q + "\nh " + h);

            // 文字列からのパース
            this.prsFrmStr(q);

            // URL本体を戻す
            return b;
        }

        /**
         *    @variable    Query.prsFrmStr(q)
         *    @title    文字列からのパース
         *    @description
         *
         *        クエリー部分を文字列からパースして、ハッシュを作成する。
         *
         *    @param    q    元の文字列。
         *    @return    なし。
         */
        this.prsFrmStr = function(q) {
            // 圧縮の確認
            if (q.indexOf(this.cmprsKey) == 0) {
                // 圧縮データがあるので解凍
                var cmpStr = q.substr(this.cmprsKey.length + 1);
                q = crocro.webAi.Cmprs.dcmprs(cmpStr);

                // ハッシュの作成
                var qArr = q.split("&");    // 配列化
                for (var i = 0; i < qArr.length; i ++) {
                    var tmpArr = qArr[i].split("=");
                    if (tmpArr.length != 2) continue;

                    // 値の格納
                    var key = tmpArr[0];
                    var prm = tmpArr[1];

                    // エスケープの戻し
                    key = key
                        .replace(/%3D/g, "=")
                        .replace(/%26/g, "&");
                    prm = prm
                        .replace(/%3D/g, "=")
                        .replace(/%26/g, "&");

                    hash[key] = prm;    // 圧縮時にエンコードしていないのでデコードは不要
                }
                return;
            }

            // ハッシュの作成
            var qArr = q.split("&");    // 配列化
            for (var i = 0; i < qArr.length; i ++) {
                var tmpArr = qArr[i].split("=");
                if (tmpArr.length != 2) continue;

                // 値の格納
                var key = tmpArr[0];
                hash[key] = decodeURIComponent(tmpArr[1]);
            }
        }

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Query.getPrms()
         *    @title    値リストの取得
         *    @description
         *
         *        値のリストを配列で取得する。
         *
         *    @return    値。
         */
        this.getPrms = function() {
            var resArr = [];
            for (var key in hash) {
                var prm = '{"' + key.replace(/"/g, '\"')
                    + '" : "' + hash[key].replace(/"/g, '\"') + '"}';
                resArr.push(prm);
            }
            return resArr;
        };

        /**
         *    @variable    Query.getQuer()
         *    @title    クエリー形式で値を取得
         *    @description
         *
         *        値のリストをクエリー形式で取得する。
         *
         *    @return    値リストのクエリー。
         */
        this.getQuery = function() {
            var resArr = [];
            for (var key in hash) {
                var prm = encodeURIComponent(hash[key]);
                key = encodeURIComponent(key);
                resArr.push(key + '=' + prm);
            }
            return resArr.join("&");
        }

        /**
         *    @variable    Query.getCmprsQuery()
         *    @title    圧縮クエリー形式で値を取得
         *    @description
         *
         *        値のリストを圧縮したクエリー形式にして取得する。
         *
         *    @return    値リストを圧縮したクエリー。
         */
        this.getCmprsQuery = function() {
            var resArr = [];
            for (var key in hash) {
                if (! hash[key]) continue;
                var prm = hash[key]
                    .replace(/=/g, "%3D")
                    .replace(/&/g, "%26");
                key = key
                    .replace(/=/g, "%3D")
                    .replace(/&/g, "%26");
                resArr.push(key + '=' + prm);
            }
            var qStr = resArr.join("&");
            var cmpStr = crocro.webAi.Cmprs.cmprs(qStr);
            var cmbStr = this.cmprsKey + "=" + cmpStr;
            return cmbStr;
        }

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Query.getUrl()
         *    @title    URL取得
         *    @description
         *
         *        クエリーを付加したURLを取得する。
         *
         *    @return    URL文字列。
         */
        this.getUrl = function() {
            return urlBdy + "?" +  this.getQuery();
        }

        /**
         *    @variable    Query.getCmprsUrl()
         *    @title    圧縮URL取得
         *    @description
         *
         *        クエリーを付加したURLを取得する。
         *        値のリストは圧縮したクエリー形式にして取得する。
         *
         *    @return    URL文字列。
         */
        this.getCmprsUrl = function() {
            return urlBdy + "?" +  this.getCmprsQuery();
        }
    };

    /*
     *--------------------------------------------------
     */

    /**
     *    @variable    crocro.webAi.Cmprs
     *    @title    【圧縮解凍】
     *    @description
     *
     *        クエリーを圧縮するためのオブジェクト。
     *        newせずにそのまま利用する。
     */
    crocro.webAi.Cmprs = new function() {
        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    Cmprs.cmprs(uStr)
         *    @title    圧縮
         *    @description
         *
         *        ユニコードの文字列をクエリーに利用できる形で圧縮する。
         *
         *    @param    uStr    ユニコードの文字列。
         *    @return    圧縮した文字列。
         */
        this.cmprs = function(uStr){
            // 文字列を圧縮してBase64化
            var bStr = crocro.webAi.Base64.u2B(uStr);            // バイト化した文字列に変換
            var cStr = crocro.webAi.Lzw.cmprs(bStr);            // 圧縮
            var b64s = crocro.webAi.Base64.toBs64(cStr);        // バイトの数値配列をBase64化
            return b64s;
        };

        /**
         *    @variable    Cmprs.dcmprs(b64s)
         *    @title    解凍
         *    @description
         *
         *        クエリーに利用できる形で圧縮した文字列を、ユニコードの文字列に解凍する。
         *
         *    @param    b64s    クエリーに利用できる形で圧縮した文字列。
         *    @return    ユニコードの文字列。
         */
        this.dcmprs = function(b64s){
            // Base64を解凍して文字列に
            var bStr = crocro.webAi.Base64.frmBs64(b64s);        // Base64をバイト化した文字列に
            var dStr = crocro.webAi.Lzw.dcmprs(bStr);            // 解凍
            var uStr = crocro.webAi.Base64.b2U(dStr);            // 解凍したデータをユニコード文字列に
            return uStr;
        };
    }

    /*
     *--------------------------------------------------
     */

    /**
     *    @variable    crocro.webAi.Base64
     *    @title    Base64
     *    @description
     *
     *        クエリーを圧縮するためのオブジェクト。通常は「Cmprs」内で利用する。
     *        newせずにそのまま利用する。
     *        Base64のコード、デコード、ユニコード文字列のバイト範囲化を行う。
     */
    crocro.webAi.Base64 = new function() {
        // ユニコード→バイト用変数
        var reChrNoAscii = /[^\x00-\xFF]/g;
        var repChrNoAscii = function(m){
            var n = m.charCodeAt(0);
            return n < 0x800
                ?      String.fromCharCode(0xc0 |  (n >>> 6))
                    + String.fromCharCode(0x80 |  (n  &  0x3f))
                :      String.fromCharCode(0xe0 | ((n >>> 12) & 0x0f))
                    + String.fromCharCode(0x80 | ((n >>> 6)  & 0x3f))
                    + String.fromCharCode(0x80 |  (n         & 0x3f));
        };

        /**
         *    @variable    Base64.u2B(uStr)
         *    @title    ユニコード→バイト
         *    @description
         *
         *        ユニコードの文字列をバイト処理用の文字列にして取得する。
         *
         *    @param    uStr    ユニコードの文字列。
         *    @return    バイト化した文字列。
         */
        this.u2B = function(uStr){
            return uStr.replace(reChrNoAscii, repChrNoAscii);
        };

        /*
         *--------------------------------------------------
         */

        // バイト→ユニコード用変数
        var reBytNoAscii
        = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
        var repBytNoAscii = function(m){
            var c0 = m.charCodeAt(0);
            var c1 = m.charCodeAt(1);
            if(c0 < 0xe0){
                return String.fromCharCode(((c0 & 0x1f) << 6) | (c1 & 0x3f));
            }else{
                var c2 = m.charCodeAt(2);
                return String.fromCharCode(
                    ((c0 & 0x0f) << 12) | ((c1 & 0x3f) <<  6) | (c2 & 0x3f)
                );
            }
        };

        /**
         *    @variable    Base64.b2U(bSt)
         *    @title    バイト→ユニコード
         *    @description
         *
         *        バイト処理用の文字列をユニコードの文字列にして取得する。
         *
         *    @param    bStr    バイト化した文字列。
         *    @return    ユニコードの文字列。
         */
        this.b2U = function(bStr){
            return bStr.replace(reBytNoAscii, repBytNoAscii);
        };

        /*
         *--------------------------------------------------
         */

        // Base64用変数
        var bs64chars
        = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

        var bs64tab = function(bin){
            var t = {};
            for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
            return t;
        }(bs64chars);

        // バイト→Base64用変数
        var repToBs64 = function(m){
            var n = (m.charCodeAt(0) << 16)
                  | (m.charCodeAt(1) <<  8)
                  | (m.charCodeAt(2)      );
            return bs64chars.charAt( n >>> 18)
                 + bs64chars.charAt((n >>> 12) & 63)
                 + bs64chars.charAt((n >>>  6) & 63)
                 + bs64chars.charAt( n           & 63);
        };

        /**
         *    @variable    Base64.toBs64(bin)
         *    @title    バイト→Base64
         *    @description
         *
         *        バイト処理用の文字列をBase64の文字列にして取得する。
         *
         *    @param    bin    バイト化した文字列。
         *    @return    Base64の文字列。
         */
        this.toBs64 = function(bin) {
            if (bin.match(/[^\x00-\xFF]/)) throw 'err';
            var padlen = 0;
            while(bin.length % 3) {
                bin += '\0';
                padlen ++;
            };
            var b64 = bin.replace(/[\x00-\xFF]{3}/g, repToBs64);
            if (! padlen) return b64;
            b64 = b64.substr(0, b64.length - padlen);
            while(padlen --) b64 += '_';
            return b64;
        };

        /*
         *--------------------------------------------------
         */

        /*
         *--------------------------------------------------
         */

        // Base64→バイト用変数
        var repfrmBs64 = function(m){
            var n = (bs64tab[ m.charAt(0) ] << 18)
                  | (bs64tab[ m.charAt(1) ] << 12)
                  | (bs64tab[ m.charAt(2) ] <<  6)
                  | (bs64tab[ m.charAt(3) ]);
            return String.fromCharCode( n >> 16)
                +  String.fromCharCode((n >>  8) & 0xff)
                +  String.fromCharCode( n         & 0xff);
        };

        /**
         *    @variable    Base64.frmBs64(b64)
         *    @title    Base64→バイト
         *    @description
         *
         *        Base64の文字列をバイト処理用の文字列にして取得する。
         *
         *    @param    b64    Base64の文字列。
         *    @return    バイト処理用の文字列。
         */
        this.frmBs64 = function(b64) {
            b64 = b64.replace(/[^A-Za-z0-9+\/]/g, '');
            var padlen = 0;
            while(b64.length % 4){
                b64 += 'A';
                padlen ++;
            }
            var bin = b64.replace(/[A-Za-z0-9+\/]{4}/g, repfrmBs64);
            bin = bin.substr(0, bin.length - padlen);
            return bin;
        };
    }

    /*
     *--------------------------------------------------
     */

    /**
     *    @variable    crocro.webAi.LZW
     *    @title    LZW
     *    @description
     *
     *        クエリーを圧縮するためのオブジェクト。通常は「Cmprs」内で利用する。
     *        newせずにそのまま利用する。
     *        圧縮後のデータの上位4バイトは、オフセット・サイズを記録するために使用。
     */
    crocro.webAi.Lzw = new function() {
        // ユーザー用変数
        /**
         *    @variable    LZW.tmOutMSec
         *    @title    タイムアウト用ミリ秒
         *    @description
         *        不正な文字列が与えられた際に、無限ループに至るのを回避するための設定。
         *
         *        デフォルトは「1000」。
         */
        this.tmOutMSec = 1000;        // タイムアウト用ミリ秒

        /*
         *--------------------------------------------------
         */

        // データ
        function Data(arg0, arg1) {
            this.byts = arg0 || [];
            this.ofst = 0;
            this.cnt  = arg1;

            this.write = function(v, n) {
                for(var i = 0; i < n; ++i) {
                    this.byts[this.ofst >>> 3] |= ((v >>> i) & 1) << (this.ofst & 7);
                    this.ofst ++;
                }
            }
            this.read = function(n) {
                if((this.ofst + n) > this.cnt) return null;
                var v = 0;
                for(var i = 0; i < n; ++ i) {
                    var tmp = this.byts[this.ofst >>> 3] >> (this.ofst & 7);
                    this.ofst ++;
                    v |= (tmp & 1) << i;
                }
                return v;
            }
        }
        function getLen(n) {
            return Math.ceil(Math.log(n) / Math.LN2);
        }

        // 辞書
        function Dic(isCmprs) {
            this.isCmprs = isCmprs;
            this.hash = {};
            this.sz   = 256;
            this.len  = this.isCmprs ? function() {return getLen(this.sz + 1);} : 9;

            for(var i = 0; i < this.sz; i ++) {
                this.isCmprs
                    ? (this.hash[String.fromCharCode(i)] = i)
                    : (this.hash[i] = String.fromCharCode(i));
            }

            this.is  = function(v) {return v in this.hash;};
            this.get = function(v) {return this.hash[v];};
            this.set = function(v) {
                if (this.isCmprs) {
                    var n = this.len();
                    this.hash[v] = this.sz ++;
                    return n;
                } else {
                    this.hash[this.sz ++] = v;
                    return this.len = getLen(this.sz + 2);
                }
            };
        }

        /*
         *--------------------------------------------------
         */

        /**
         *    @variable    LZW.cmprs(str)
         *    @title    圧縮
         *    @description
         *
         *        バイト文字列を圧縮する。
         *
         *    @param    str        バイト文字列。
         *    @return    圧縮した配列。
         */
        this.cmprs = function(str) {
            // 変数の初期化
            var len = str.length;
            var dat = new Data();
            if(len > 0) {
                var dic = new Dic(true);
                var n = dic.len();
                var w = "";

                // 圧縮
                for(var i = 0; i < len; i++) {
                    var c = str.charAt(i);
                    if(dic.is(w + c)) {
                        w += c;
                    } else {
                        n = dic.set(w + c);
                        dat.write(dic.get(w), n);
                        w = c;
                    }
                }
                dat.write(dic.get(w), n);
            }

            // オフセットを頭に記録
            var ofst = dat.ofst;
            var ofstArr = [
                ofst >>> 24,
                ofst >>> 16,
                ofst >>>  8,
                ofst & 255
            ];

            // バイト化した文字列を作成して戻す
            var resArr = ofstArr.concat(dat.byts);
            for (var i = 0; i < resArr.length; i ++) {
                resArr[i] = String.fromCharCode(resArr[i]);
            }
            return resArr.join("");
        };

        /**
         *    @variable    LZW.dcmprs(str)
         *    @title    解凍
         *    @description
         *
         *        バイト化した文字列を解凍する。
         *
         *    @param    str        バイト化した文字列。
         *    @return    解凍した文字列。
         */
        this.dcmprs = function(str) {
            // 配列の作成
            var byts = [];
            for (var i = 0; i < str.length; i ++) {
                byts.push(str.charCodeAt(i));
            }

            // オフセットの取り出し
            var ofst =
                  (byts.shift() << 24)
                + (byts.shift() << 16)
                + (byts.shift() << 8)
                +  byts.shift();
            if (ofst == 0) return "";

            // 変数の初期化
            var dat = new Data(byts, ofst);

            var dic = new Dic(false);
            var n = dic.len;
            var k = dat.read(n);
            var w = String.fromCharCode(k);
            var resArr = [w];
            var entry = "";

            // タイムアウトの初期化
            var tmStrt = (new Date()).getTime();
            var tmOutCnt = 0;

            // 解凍
            while ((k = dat.read(n)) != null) {
                // 不正なデータ時のタイムアウト処理
                if (tmOutCnt ++ >= 1000) {
                    if ((new Date()).getTime() - tmStrt >= this.tmOutMSec) break;
                }

                // 通常の解凍処理
                entry = (k < dic.sz) ? dic.get(k) : (w + w.charAt(0));
                resArr.push(entry);
                n = dic.set(w + entry.charAt(0));
                w = entry;
            }
            return resArr.join("");
        };
    }
Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2017 Cronus Crown (c)1997-2017 Masakazu Yanai
このWebPageに関するご意見・お問い合わせは
サイト情報 弊社への連絡
までお願いします。