Open8

gpgpdump の出力を再利用しやすくする

SpiegelSpiegel

現在の gpgpdump は元ネタの pgpdump の出力形式を引きずっていて,それはそれで悪くないのだが,再利用性は高くない。一応 JSON 形式での出力にも対応してるけど,やっぱり再利用し辛いんだよなぁ。

そこで,出力フォーマットを改善して再利用性を高めることを考えている。

SpiegelSpiegel

現時点で解析結果を格納する構造体の定義は以下の通り。

type Info struct {
    Packets []*Item `toml:"Packet,omitempty" json:"Packet,omitempty"`
}
type Item struct {
    Name  string  `toml:"name" json:"name"`
    Value string  `toml:"value,omitempty" json:"value,omitempty"`
    Dump  string  `toml:"dump,omitempty" json:"dump,omitempty"`
    Note  string  `toml:"note,omitempty" json:"note,omitempty"`
    Items []*Item `toml:"Item,omitempty" json:"Item,omitempty"`
}

ぶっちゃけ出力するテキストを種類ごとに要素に分けているだけ。あと TOML サポートは drop したので消してもいいか。

SpiegelSpiegel

文字列を解析して中身を評価するのは明らかにバッドノウハウ。
欲しいのは Item の種別と値(バイナリ値)かな。

SpiegelSpiegel

種別は列挙型を定義すればいいか。こんな感じでいいかな

type Types int

const (
    TypeTag Types = iota + 1
    TypeSub
    TypeVersion
)

func (t Types) String() string { ... }
func (t Types) MarshalJSON() ([]byte, error) { ... }

JSON テキストから構造体に Unmarshal することは考えなくてもいいかな。

SpiegelSpiegel

値は []byte でいいと思うけど,値がない Item もあるし,取り回しも考えると構造体で囲むのがいいか?

type ByteValue struct {
    value []byte
}
func (v *ByteValue) Append(b ...byte) { v.value = append(v.value, b...) }
func (v *ByteValue) String() string { ... }
func (v *ByteValue) MarshalJSON() ([]byte, error) { ... }

これなら16進ダンプ表記のメソッドを組み込むのも難しくないな。

SpiegelSpiegel

そういや JSON って16進数表記は NG なんだっけ。 JSON5 ならできるけど...
数値配列にするか文字列にするか悩ましいところだな。

SpiegelSpiegel

以上を踏まえて Item 構造体はこんな感じ?

type Item struct {
    Type        Types
    Value       *ByteValue `json:",omitempty"`
    Description string     `json:",omitempty"`
    Content     string     `json:",omitempty"`
    Note        string     `json:",omitempty"`
    Items       []*tems    `json:",omitempty"`
    dumpFlag    bool
}
  • NameDescription
  • valueContent
  • DumpValue と共用。テキストとして出力するかどうかは dumpFlag で判断する
SpiegelSpiegel

んー。この方針で考えを進めてみるか。でも年末は慌ただしいし,これに実際に手を付けるとなるとかなりdrastic な変更になるから,実際に手を付けるのは年明けだな。