mirror of
https://github.com/jixishi/SerialTerminalForWindowsTerminal.git
synced 2026-06-15 16:42:46 +00:00
refactor: extract pkg/charset and internal/event packages
Extract ConvertChunk/FormatHexFrame into pkg/charset (zero external deps). Extract UIEvent/UIEventKind/UIPanelKind types into internal/event. Update all references across main package to use qualified imports. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
// Package charset provides character-set conversion and hex formatting utilities.
|
||||
package charset
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zimolab/charsetconv"
|
||||
)
|
||||
|
||||
// ConvertChunk converts a byte chunk from srcCode charset to dstCode charset.
|
||||
// Returns nil, nil when input is empty. Returns a copied slice when charsets match.
|
||||
func ConvertChunk(chunk []byte, srcCode, dstCode string) ([]byte, error) {
|
||||
if len(chunk) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if strings.EqualFold(srcCode, dstCode) {
|
||||
dup := make([]byte, len(chunk))
|
||||
copy(dup, chunk)
|
||||
return dup, nil
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err := charsetconv.ConvertWith(bytes.NewReader(chunk), charsetconv.Charset(srcCode), &buf, charsetconv.Charset(dstCode), false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// FormatHexFrame formats a byte frame as hex + printable representation.
|
||||
// Optionally prefixes with a timestamp using the given format string.
|
||||
func FormatHexFrame(frame []byte, withTimestamp bool, tsFmt string) string {
|
||||
if withTimestamp {
|
||||
return fmt.Sprintf("%v % X %q \n", time.Now().Format(tsFmt), frame, frame)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("% X %q \n", frame, frame)
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package charset
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestConvertChunk(t *testing.T) {
|
||||
t.Run("empty", func(t *testing.T) {
|
||||
out, err := ConvertChunk(nil, "UTF-8", "UTF-8")
|
||||
if err != nil {
|
||||
t.Fatalf("ConvertChunk(nil) unexpected error: %v", err)
|
||||
}
|
||||
if out != nil {
|
||||
t.Fatalf("ConvertChunk(nil) expected nil output")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("same-charset-copy", func(t *testing.T) {
|
||||
in := []byte("hello")
|
||||
out, err := ConvertChunk(in, "UTF-8", "UTF-8")
|
||||
if err != nil {
|
||||
t.Fatalf("ConvertChunk same charset unexpected error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(out, in) {
|
||||
t.Fatalf("ConvertChunk same charset mismatch got=%q want=%q", out, in)
|
||||
}
|
||||
|
||||
out[0] = 'H'
|
||||
if in[0] != 'h' {
|
||||
t.Fatalf("ConvertChunk should return a copied slice")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestFormatHexFrame(t *testing.T) {
|
||||
frame := []byte("AB")
|
||||
out := FormatHexFrame(frame, false, "")
|
||||
if !strings.Contains(out, "41 42") {
|
||||
t.Fatalf("FormatHexFrame missing hex bytes: %q", out)
|
||||
}
|
||||
if !strings.Contains(out, "\"AB\"") {
|
||||
t.Fatalf("FormatHexFrame missing quoted bytes: %q", out)
|
||||
}
|
||||
|
||||
outTS := FormatHexFrame([]byte("A"), true, "2006")
|
||||
if !strings.Contains(outTS, "41") || !strings.Contains(outTS, "\"A\"") {
|
||||
t.Fatalf("FormatHexFrame(withTimestamp) malformed output: %q", outTS)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertChunkCharsetConversion(t *testing.T) {
|
||||
t.Run("gbk-to-utf8", func(t *testing.T) {
|
||||
// Chinese "你好" in GBK: 0xC4 0xE3 0xBA 0xC3
|
||||
gbkHello := []byte{0xC4, 0xE3, 0xBA, 0xC3}
|
||||
out, err := ConvertChunk(gbkHello, "GBK", "UTF-8")
|
||||
if err != nil {
|
||||
t.Fatalf("ConvertChunk GBK->UTF-8 unexpected error: %v", err)
|
||||
}
|
||||
if string(out) != "你好" {
|
||||
t.Fatalf("ConvertChunk GBK->UTF-8 got=%q want=%q", string(out), "你好")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("same-charset-different-case", func(t *testing.T) {
|
||||
in := []byte("hello")
|
||||
out, err := ConvertChunk(in, "utf-8", "UTF-8")
|
||||
if err != nil {
|
||||
t.Fatalf("ConvertChunk case-diff unexpected error: %v", err)
|
||||
}
|
||||
if !bytes.Equal(out, in) {
|
||||
t.Fatalf("ConvertChunk case-diff mismatch got=%q want=%q", out, in)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("invalid-charset", func(t *testing.T) {
|
||||
_, err := ConvertChunk([]byte("hello"), "INVALID-CHARSET-NAME", "UTF-8")
|
||||
if err == nil {
|
||||
t.Fatalf("ConvertChunk invalid charset should error")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("empty-input", func(t *testing.T) {
|
||||
out, err := ConvertChunk([]byte{}, "GBK", "UTF-8")
|
||||
if err != nil {
|
||||
t.Fatalf("ConvertChunk empty unexpected error: %v", err)
|
||||
}
|
||||
if out != nil {
|
||||
t.Fatalf("ConvertChunk empty input should return nil")
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user