Progressive Parser

妄想レベルだけど。

require_once 'PrograssiveParser.php';
require_once 'SWF/Type/RECT.php';
require_once 'SWF/Tag.php';

class SWFParser extends ProgressiveParser() {
    function __constructor() {
        return return array('Header' => 'SWFParser::RECT',
                            'Tags' => 'SWFParser::Tags');
    }
    function Header() {
        return array ('Signature' => Array('String', '3.0'),
                      'Version'   => Array('UINT', '1.0'),
                      'FileLength' => Array('UINT', '4.0', 'self::MovieHeader + $'),
                      'Tags' => 'SWFParser::Tags');
    }
    function MovieHeader() {
        return array ('FrameSize' => 'SWF_Type_RECT',
                      ...);
    }
    function Tags() {
       return array ('Tags' => Array('Array' => 'SWF_Tag'));
    }
}

こんな感じでクラス定義をすると、

$pp = new ProgressiveParser();
$pp->input($swddata);
$rect = $pp->get('Header.FrameSize');
var_dump($rect);

で、バイナリ断片が取得できて。

$pp->input($swfdata);
var_dump($pp->get(''))

これで、ダンプ出来て。

$pp->input($swfdata);
$pp->replace('Header.FrameRate', '12.0');
echo $pp->output();

こんな風に書き換えられたり出来るといいな。

備考

  • いわゆる、インクリメンタルパーサです。バイナリに特化した。
  • データ取得/書き換えに最低限必要なバイナリだけ分解する
  • 分解した分もなるべくデータをコピーせずに元データとオフセットで管理。
  • 書き換えた分は仕方ないので、メモリをアロケート。
  • Array の2つ目は 'byte.bit' の形式
  • Array の3つ目は build 時に書きこむ値で自動化出来るもの (オフセットの計算式。$ はファイル末尾 + 1)