Goでzsh_historyをパースするプログラムを書いてみる
zsh 文字化けしたzsh_historyファイルを読めるようにする, zsh マルチバイト文字をzsh_historyの形式に変換する の仕様に則って、パース処理を書いていく
package zhistconv
const (
// zsh_historyの仕様で、各バイトが0x83~0xA2のとき、その前に0x83を入れて6bit目を反転させる
x83 = 131
xA2 = 162
x20 = 32
)
// zsh_historyを読める形式に変換する
func ParseZshHistory(latin1Byte []byte) []byte {
isMarking := false
var byteBuffer []byte
for _, codePoint := range latin1Byte {
if codePoint == x83 {
isMarking = true
continue
}
if isMarking {
// 6bit目を反転させるために0x20をXORする
invertCodePoint := codePoint ^ x20
byteBuffer = append(byteBuffer, invertCodePoint)
isMarking = false
} else {
byteBuffer = append(byteBuffer, codePoint)
}
}
return byteBuffer
}
// プレーンなテキストをzsh_historyに変換する
func ConvertToZshHistory(latin1Byte []byte) []byte {
var byteBuffer []byte
for _, codePoint := range latin1Byte {
// 131は0metacharの10進数表現
if x83 <= codePoint && codePoint <= xA2 {
// 6bit目を反転させるために0x20をXORする
invertCodePoint := codePoint ^ x20
byteBuffer = append(byteBuffer, x83)
byteBuffer = append(byteBuffer, invertCodePoint)
} else {
byteBuffer = append(byteBuffer, codePoint)
}
}
return byteBuffer
}