Skip to content

Commit

Permalink
Merge pull request #2 from zetamatta/develop
Browse files Browse the repository at this point in the history
branch for v0.6.0 (develop)
  • Loading branch information
hymkor authored Nov 26, 2021
2 parents 4d5967e + 943a518 commit 074c9c8
Show file tree
Hide file tree
Showing 15 changed files with 320 additions and 82 deletions.
107 changes: 107 additions & 0 deletions application.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"fmt"
"regexp"
"strconv"

"github.com/zetamatta/binview/internal/encoding"
"github.com/zetamatta/binview/internal/large"
)

var (
rxUnicodeCodePoint = regexp.MustCompile(`^\s*[uU]\+([0-9A-Fa-f]+)`)
rxByte = regexp.MustCompile(`^\s*0x([0-9A-Fa-f]+)`)
rxDigit = regexp.MustCompile(`^\s*([0-9]+)`)
rxString = regexp.MustCompile(`^\s*[uU]?"([^"]+)"`)
)

func evalExpression(exp string, enc encoding.Encoding) ([]byte, error) {
bytes := make([]byte, 0)
for len(exp) > 0 {
if m := rxUnicodeCodePoint.FindStringSubmatch(exp); m != nil {
exp = exp[len(m[0]):]
theRune, err := strconv.ParseUint(m[1], 16, 32)
if err != nil {
return nil, err
}
if bin, err := enc.EncodeFromString(string(rune(theRune))); err == nil {
bytes = append(bytes, bin...)
}
} else if m := rxByte.FindStringSubmatch(exp); m != nil {
exp = exp[len(m[0]):]
theByte, err := strconv.ParseUint(m[1], 16, 16)
if err != nil {
return nil, err
}
bytes = append(bytes, byte(theByte))
} else if m := rxDigit.FindStringSubmatch(exp); m != nil {
exp = exp[len(m[0]):]
value, err := strconv.ParseUint(m[1], 10, 16)
if err != nil {
return nil, err
}
bytes = append(bytes, byte(value))
} else if m := rxString.FindStringSubmatch(exp); m != nil {
exp = exp[len(m[0]):]
if bin, err := enc.EncodeFromString(m[1]); err == nil {
bytes = append(bytes, bin...)
}
} else {
return bytes, fmt.Errorf("`%s` are ignored", exp)
}
}
return bytes, nil
}

func insertExp(exp string, enc encoding.Encoding, ptr *large.Pointer) (int, error) {
bytes, err := evalExpression(exp, enc)
if err != nil {
return 0, err
}
space := ptr.InsertSpace(len(bytes))
copy(space, bytes)
return len(bytes), nil
}

func (app *Application) InsertExp(exp string) error {
undoAddress := app.cursor.Address()
orgDirty := app.dirty
size, err := insertExp(exp, app.encoding, app.cursor)
if err == nil {
undo := func(app *Application) {
p := large.NewPointerAt(undoAddress, app.buffer)
p.RemoveSpace(size)
app.dirty = orgDirty
}
app.undoFuncs = append(app.undoFuncs, undo)
app.dirty = true
}
return err
}

func appendExp(exp string, enc encoding.Encoding, ptr *large.Pointer) (int, error) {
bytes, err := evalExpression(exp, enc)
if err != nil {
return 0, err
}
space := ptr.AppendSpace(len(bytes))
copy(space, bytes)
return len(bytes), nil
}

func (app *Application) AppendExp(exp string) error {
size, err := appendExp(exp, app.encoding, app.cursor)
undoAddress := app.cursor.Address() + 1
orgDirty := app.dirty
if err == nil {
undo := func(app *Application) {
p := large.NewPointerAt(undoAddress, app.buffer)
p.RemoveSpace(size)
app.dirty = orgDirty
}
app.undoFuncs = append(app.undoFuncs, undo)
app.dirty = true
}
return err
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ require (
github.com/mattn/go-runewidth v0.0.13
github.com/mattn/go-tty v0.0.4-0.20201120140209-72ed86c4554d
github.com/nyaosorg/go-readline-ny v0.5.1
github.com/nyaosorg/go-windows-mbcs v0.0.0-20210914102041-eb1f2d0081b2
golang.org/x/sys v0.0.0-20210921065528-437939a70204
)
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ github.com/mattn/go-tty v0.0.4-0.20201120140209-72ed86c4554d h1:JZrMI9SDEblDXV8d
github.com/mattn/go-tty v0.0.4-0.20201120140209-72ed86c4554d/go.mod h1:+0QBZrHExAnq8s9KMEZErKk7qTDOyCmOmXxHBLO8M2o=
github.com/nyaosorg/go-readline-ny v0.5.1 h1:RrcFbuZ6ZsGL55gbWheYNmrZK4bNukJYt/zRLuzBl/g=
github.com/nyaosorg/go-readline-ny v0.5.1/go.mod h1:Erw4lUMc6CHO06+ypXfbi4mHMDAhcEg9ZuD+iLPylBY=
github.com/nyaosorg/go-windows-mbcs v0.0.0-20210914102041-eb1f2d0081b2 h1:63zq43tW5SOajzXe4Q3/S3JERIfiPJQEedLNQkSK+nM=
github.com/nyaosorg/go-windows-mbcs v0.0.0-20210914102041-eb1f2d0081b2/go.mod h1:crZALOAOrrYt3D/d//MNN700AD3btyUBI+PeHT1zQg4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
Expand All @@ -28,6 +30,7 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210921065528-437939a70204 h1:JJhkWtBuTQKyz2bd5WG9H8iUsJRU3En/KRfN8B2RnDs=
golang.org/x/sys v0.0.0-20210921065528-437939a70204/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
24 changes: 24 additions & 0 deletions internal/encoding/encoding.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package encoding

import (
"unicode/utf16"
"unicode/utf8"

"github.com/nyaosorg/go-windows-mbcs"
)

type Pointer interface {
Expand All @@ -16,6 +19,7 @@ type Encoding interface {
Decode([]byte) (rune, int)
RuneOver(Pointer) (rune, int, int)
ModeString() string
EncodeFromString(string) ([]byte, error)
}

type UTF8Encoding struct{}
Expand All @@ -32,6 +36,10 @@ func (UTF8Encoding) Count(b byte, _ int64) int {
}
}

func (UTF8Encoding) EncodeFromString(s string) ([]byte, error) {
return []byte(s), nil
}

func (UTF8Encoding) Decode(data []byte) (rune, int) {
return utf8.DecodeRune(data)
}
Expand Down Expand Up @@ -70,6 +78,10 @@ func (DBCSEncoding) Count(value byte, _ int64) int {
}
}

func (DBCSEncoding) EncodeFromString(s string) ([]byte, error) {
return mbcs.UtoA(s, mbcs.ACP)
}

func (DBCSEncoding) Decode(data []byte) (rune, int) {
utf16s, err := ToWideChar(data...)
if err != nil {
Expand Down Expand Up @@ -123,6 +135,18 @@ func (this _UTF16) Decode(data []byte) (rune, int) {
}
}

func (this _UTF16) EncodeFromString(s string) ([]byte, error) {
bytes := make([]byte, 0, len(s)*2)
for _, utf16data := range utf16.Encode([]rune(s)) {
if this.isLittleEndian {
bytes = append(bytes, byte(utf16data), byte(utf16data>>8))
} else {
bytes = append(bytes, byte(utf16data>>8), byte(utf16data))
}
}
return bytes, nil
}

func (this _UTF16) RuneOver(cursor Pointer) (rune, int, int) {
currentPosInRune := 0
theRune := rune(cursor.Value())
Expand Down
3 changes: 2 additions & 1 deletion internal/encoding/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import (

var _ Encoding = UTF8Encoding{}
var _ Encoding = DBCSEncoding{}
var _ Encoding = UTF16LE{}
var _ Encoding = UTF16LE()
var _ Encoding = UTF16BE()

func TestIsDBCSLeadByte(t *testing.T) {
if !IsDBCSLeadByte(0x83) { // Japanese katakana SO
Expand Down
44 changes: 42 additions & 2 deletions internal/large/pointer.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,14 @@ func NewPointer(b *Buffer) *Pointer {
}
}

func NewPointerAt(at int64, b *Buffer) *Pointer {
p := NewPointer(b)
if p != nil {
p.Skip(at)
}
return p
}

func (p *Pointer) Value() byte {
return p.element.Value.(_Block)[p.offset]
}
Expand Down Expand Up @@ -141,13 +149,13 @@ func (p *Pointer) makeSpace(size int) _Block {
return block
}

func (p *Pointer) MakeSpace(size int) []byte {
func (p *Pointer) InsertSpace(size int) []byte {
block := p.makeSpace(size)
copy(block[p.offset+size:], block[p.offset:])
return block[p.offset : p.offset+size]
}

func (p Pointer) MakeSpaceAfter(size int) []byte {
func (p Pointer) AppendSpace(size int) []byte {
block := p.makeSpace(size)
copy(block[p.offset+size+1:], block[p.offset+1:])
return block[p.offset+1 : p.offset+size+1]
Expand Down Expand Up @@ -186,3 +194,35 @@ func (p *Pointer) Remove() int {
}
return RemoveSuccess
}

func (p *Pointer) RemoveSpace(space int) {
block := p.element.Value.(_Block)

if space <= 0 {
return
} else if p.offset == 0 && space > len(block) {
tmp := p.element.Next()
if tmp != nil {
p.buffer.lines.Remove(p.element)
p.element = tmp
p.buffer.allsize -= int64(len(block))
p.RemoveSpace(space - len(block))
}
return
} else if left := len(block) - p.offset; space > left {
p.element.Value = _Block(block[:p.offset])
tmp := p.element.Next()
p.buffer.allsize -= int64(left)
if tmp != nil {
p.element = tmp
p.offset = 0
p.RemoveSpace(space - left)
} else {
p.offset--
}
return
}
copy(block[p.offset:], block[p.offset+space:])
p.element.Value = _Block(block[:len(block)-space])
p.buffer.allsize -= int64(space)
}
Loading

0 comments on commit 074c9c8

Please sign in to comment.