IFC文字列のTypeScriptでのdecode

やりたいこと

\X2\64CD4F5C5BA4\X0\操作室に変換したいです.

できたもの

const decode_ifc_str = (s: string) => {
    const expr = /\\X2\\.*?\\X0\\/g;
    let ret = s;

    let matchedStrings = ret.matchAll(expr);
    if (matchedStrings) {
        const decoder = new TextDecoder("UTF-16be");
        for (let matches of matchedStrings) {
            for (let m of matches) {
                let hex = m.replace("\\X2\\", "").replace("\\X0\\", "");
                let bf = Buffer.from(hex, 'hex');
                let decodedString = decoder.decode(bf);
                ret = ret.replaceAll(m, decodedString);
            }
        }
    }
    return ret;
}

IFC文字列

こういう文字列のことをIFC文字列とここでは呼んでいます.
\X2\64CD4F5C5BA4\X0\

ISO 10303で定められている文字列のエンコード方法に従って,/X2/, /X0/でUTFエンコードされたバイト文字列のことです.
参考:
https://www.loc.gov/preservation/digital/formats/fdd/fdd000448.shtml
https://www.steptools.com/stds/step/IS_final_p21e3.html

pythonとRubyでの実装

Unicodeエスケープされた文字列を変換する
How to decoding IFC using Ruby

pythonとRubyでの実装は上記の通り見つけられましたが,IFCjs上で変換したかったので,TypeScriptでの実装をしたかったのです.

IFCjsのIssueであげられた実装

https://github.com/IFCjs/web-ifc/issues/368#issuecomment-1485711502
ここにありますが,これを使って\X2\64CD4F5C5BA4\X0\をデコードした結果が下記です.
##

多分,const unicodeChar = String.fromCharCode (parseInt (match[1], 16));が怪しい.

できたもの

上の見出しをクリックして頂ければ,上のコードに戻ります.

ちょっとだけ説明

\X2\, \X0\で囲まれた文字列を正規表現で取得します.
一つの文字列内に複数ある場合に備えて,matchAll()を使います.
matchAll()の返り値はRegExpMatchArrayのIteratorなので,不格好にfor文を2回回しています.参考
正規表現で取れたのが\X2\, \X0\も含む全体が取れてしまっていたので,その部分を削除します.
削除するとバイト列が文字になっている状態なので,Buffer.from(hex, 'hex')でバイト列に変換します.
おもむろにUTF-16beでデコードして終わりです.

詰まったところを解消するのにお世話になったサイトたち

index pageへ戻る