開発

[binllion] 編集用バッファを実装する

大まかな外枠の表示ができたので編集用データの構造体を作っていきたいとおもいます。

エディター向けの構造体を調べたところ、Gap BufferやRope、Peace Table等があるようです。1 2 3 4

ただしこれらは行単位でデータを持つ前提のようなのでバイナリのような一塊のデータを扱う上で便利なのかどうかわかりませんでした。

後でデータ構造は変更するかもしれませんが、Vecでも良さそうなのですが、とりあえずVecDequeを使っていこうとおもいます。

BinDataという構造体を定義して編集用バッファとしたいとおもいます。

// 編集用構造体
struct BinData {
    buf: VecDeque<u8>,
}

impl BinData {
    pub(crate) fn new() -> Self {
        BinData { buf: VecDeque::new() }
    }

    pub(crate) fn push_back(&mut self, new_buf: Vec<u8>) {
        let mut new_data: VecDeque<u8> = VecDeque::from(new_buf);
        self.buf.make_contiguous();
        self.buf.append(&mut new_data);
    }

    pub(crate) fn insert(&mut self, index: usize, value: u8) {
        self.buf.make_contiguous();
        self.buf.insert(index, value);
    }

    pub(crate) fn update(&mut self, index: usize, value: u8) {
        self.buf.make_contiguous();
        if let Some(elem) = self.buf.get_mut(index) {
            *elem = value;
        }
    }

    pub(crate) fn buf(&self) -> &[u8] {
        let (res, _) = self.buf.as_slices();
        res
    }

}

impl From<Vec<u8>> for BinData {
    fn from(buf: Vec<u8>) -> Self {
        BinData { buf: VecDeque::from(buf) }
    }
}

impl Default for BinData {
    fn default() -> Self {
        Self::new()
    }
}
Code language: PHP (php)

バイナリエディタは普段使いしている訳ではないのでどのような機能の需要があるのかわからないのですが、データを読み込んで必要な箇所だけ書き換えるというのが経験上多いです。

そのため、当面は上記のメソッドだけで十分かな、とおもいます。

データの読み込みはVecから渡される想定で下記のような形でデータ読み込みを想定します。

    // 仮データ
    let mut bin_data = BinData::new();
    bin_data.push_back(vec![
        0x01, 0x02, 0x03, 0x00, 0x63, 0x71, 0x00, 0x61, 0x62, 0x0f, 0x01, 0x02, 0x03, 0x00, 0x63,
        0x71, 0x0f, 0x61, 0x62, 0x63, 0x01, 0xff, 0x03, 0x00, 0x63, 0x71, 0x0f, 0x61, 0x62, 0x63,
    ]);Code language: JavaScript (javascript)

トレイト

BinDataの定義の中でimpl From<Vec<u8>> for BinData {の文があります。

これはFromトレイトをBinDataに実装する、という文です。

トレイトとは、様々な型でも使えそうなメソッドや関数等の機能が集まったものです。5

例えば、u8やi16で足し算や引き算、Vecや配列にイテレータ処理をする操作は共通の機能として個々にまとめることができます。

このまとめたものがトレイトになります。例えばイテレータの機能をまとめたものはIteratorトレイトです。

トレイトを利用することで処理を個別に実装する手間が省けたり共通化できます。

プログラミングに於ける一種のインターフェイスポリモーフィズムダックタイピング的なものと理解できるかもしれません。


  1. Windows 用テキストエディタ viviさんの技術文書が詳しい。その1その2 ↩︎
  2. 同じくvivi作者の方ですね。その3 ↩︎
  3. Ropeについてはこちらが参考になります。その1その2 ↩︎
  4. PeaceTableについてはこちらが参考になります。その1 ↩︎
  5. メソッド定義等なく識別子として機能するマーカートレイトというものもあります。 ↩︎

GitHubにコードをアップロードしています。0.1.0バージョン

コードのコメントに書かれているfirst_stepなどをcargoコマンドに渡すと実行できます。

# Example
$ cargo run --example first_stepCode language: Bash (bash)

管理人

Recent Posts

情報セキュリティマネジメント試験取得への道

スキルアップを図るべく情報セキ…

2か月 ago

ファイナンシャルプランナー3級試験取得への道

スキルアップを図るべくファイナ…

2か月 ago

[rust] New Type Patternを使ってみる

DDDの考えを取り入れることで…

5か月 ago

RustでDDDの要素を取り入れてみる

前回SOLID原則というものを…

5か月 ago

期間限定!書籍無料キャンペーン2025

「mdBookではじめるKin…

5か月 ago