1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kinx ライブラリ - Binary

Posted at

Binary

はじめに

「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。言語はライブラリが命。ということでライブラリの使い方編。

今回は Binary です。

バイナリ(Binary)は配列(Array)に似ているが、保持できる値が 0x00 ~ 0xFF までのバイト列である点が異なる。内部実装的にも単純にバイトの Vector として実装されており、バイナリデータを格納するのに適している。

Binary 特殊オブジェクト

Binary にも特殊オブジェクト Binary があり、Binary オブジェクトに対して関数定義することができる。尚、後述するがバイナリデータはスプレッド演算子を使って配列と相互変換できる。以下の例はバイナリを配列に変換して配列に対して map している例となる。

Binary.toStringArray = function(bin) {
    return [...bin].map(&(e) => *e);
};
System.println([...<97, 98, 99>]);            // => [97, 98, 99]
System.println(<97, 98, 99>.toStringArray()); // => ["a", "b", "c"]

Binary

ファイル・ロード

バイナリデータは以下のように File.BINARY を指定することでファイルから読み込むこともできる。指定しなかった場合は File.TEXT と同様、文字列としてファイルを読み込む。

var file = File.load("filename", File.BINARY);

組み込み特殊メソッド

Binary には Array と同じようなメソッドが登録されている。が、基本的にバイナリ列に適用することになるため、あまり複雑なことはできない。pushpopunshiftshift は破壊的な操作を行う。

メソッド 意味
Binary.length(bin) バイナリ bin の要素数を返す。
Binary.push(bin, e) バイナリ bin の最後の要素として e を追加する。
Binary.pop(bin) バイナリ bin の最後の要素を返し、要素から削除する。
Binary.unshift(bin, e) バイナリ bin の最初の要素として e を追加する。
Binary.shift(bin) バイナリ bin の最初の要素を返し、要素から削除する。後ろの要素は順次先頭方向に移動する。
Binary.join(bin, sep, fmt) バイナリ bin の要素を全てつなげた文字列として返す。要素と要素の間は sep でつなぐ。fmt が省略された場合 "0x02x" でフォーマットされる。
Binary.reverse(bin) バイナリ bin の要素を逆順にした新たなバイナリを返す。
Binary.toString(bin, sep, fmt) バイナリ bin を文字列化して返す。デフォルトのセパレータは ", "fmt が省略された場合 "0x02x" でフォーマットされる。
Binary.apply(bin, func) func(bin) を実行する。
Binary.each(bin, callback) bin の各要素 e に対して callback(e, index) を実行する。
Binary.map(bin, callback) bin の各要素 e に対して callback(e, index) の結果の集合となる新たなバイナリを返す。
Binary.filter(bin, callback) bin の各要素 e に対して callback(e, index) の結果が真となるもののみの集合として新たなバイナリを返す。
Binary.reject(bin, callback) bin の各要素 e に対して callback(e, index) の結果が偽となるもののみの集合として新たなバイナリを返す。
Binary.reduce(bin, callback, initr) 前の要素までの結果を r (初期値は initr、指定されていなければ null)として、ary の各要素 e に対し callback(r, e) を行った最終結果を返す。
Binary.sort(bin, comp) 任意の bin の要素 e1, e2 に対する comp(e1, e2) の結果を利用して bin 全体をソートした新たなバイナリを返す。
Binary.clone(bin) bin のコピーを作成する。
Binary.println(bin) bin の各要素 e に対して System.println(e) を適用する。

特殊オペレーター

後置 [] オペレーター

バイナリの要素にアクセスする。

var e = ary[5];  // index は 0 はじまりなので 6 番目の要素

左辺値にもなり、バイト列を直接書き換えることができる。

var bin = <1,2,3,4,5>;
bin[2] = 255;
System.println(bin);  // => <0x01, 0x02, 0xff, 0x04, 0x05>

二項 + オペレーター

バイナリ同士をつなげる。右辺値がバイナリではない場合、SystemException("Unsupported Operator") 例外が発生する。

var bin = <1, 2, 3>;
var r = bin + <2, 4>;  // => <0x01, 0x02, 0x03, 0x02, 0x04>

単項 * オペレーター

単項 * オペレーターをバイナリに適用した場合、バイナリを文字列に変換する。

var a = *<97, 98, 99>;  // => "abc"

尚、文字列に単項 * オペレーターを適用すると配列になるため、バイナリには戻らない。代わりに、バイナリは下記のスプレッド演算子で配列と相互変換ができる。

スプレッド演算子

配列とバイナリで相互変換可能。配列からバイナリに変換する際は、数値であれば 0x00~0xFF の値に丸められる。文字の場合は先頭の文字のみ使われる。

var a = <97, 98, 99>; // == <0x61, 0x62, 0x63>
var b = [...a];       // => [97, 98, 99]
var c = <...b>;       // => <0x61, 0x62, 0x63>
var d = <...[1024,1025,1026,"abc"]>;  // => <0x00, 0x01, 0x02, 0x61>
                                      //    0x61 == 97 == 'a'

おわりに

バイナリデータも割と扱いたくなるので、一通り機能を揃えてみました。バイト単位でゴニョゴニョできると良いことあるかもしれない。なんとなく例えば x64 向け JIT ライブラリとか作れそうですね。

では、また次回。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?