Refactor encoding to use *string instead of string as input

I don't want to clone the whole input string
This commit is contained in:
2024-07-31 12:58:02 +02:00
parent 7b4fcf3de1
commit 7001f2c51a
5 changed files with 19 additions and 18 deletions

View File

@@ -4,8 +4,9 @@ import "bytes"
type ASCIICoder struct{} type ASCIICoder struct{}
func (c *ASCIICoder) Encode(s string, buf *bytes.Buffer) error { func (c *ASCIICoder) Encode(s *string, buf *bytes.Buffer) error {
buf.WriteString(s) // These should be ASCII but UTF8 is a superset of ASCII so hopefully this'll be fine
buf.WriteString(*s)
return nil return nil
} }

View File

@@ -11,7 +11,7 @@ func TestASCIIEncodeSimpleASCIIString(t *testing.T) {
input := "Hello, World!" input := "Hello, World!"
expected := []byte{72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33} expected := []byte{72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33}
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)
@@ -46,7 +46,7 @@ func TestASCIIEncodeEmptyString(t *testing.T) {
input := "" input := ""
expected := []byte{} expected := []byte{}
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)

View File

@@ -3,6 +3,6 @@ package encoding
import "bytes" import "bytes"
type Coder interface { type Coder interface {
Encode(s string, buf *bytes.Buffer) error Encode(s *string, buf *bytes.Buffer) error
Decode(buf *bytes.Buffer) (string, error) Decode(buf *bytes.Buffer) (string, error)
} }

View File

@@ -11,15 +11,15 @@ type GSM7Coder struct{}
// Otherwise Encode will allocate memory as it sees fit // Otherwise Encode will allocate memory as it sees fit
// Which is fine but not optimal // Which is fine but not optimal
// Preallocate the buffer with the size of EncodesInto bytes // Preallocate the buffer with the size of EncodesInto bytes
func (c *GSM7Coder) Encode(s string, buf *bytes.Buffer) error { func (c *GSM7Coder) Encode(s *string, buf *bytes.Buffer) error {
// utf8 := *(*[]byte)(unsafe.Pointer(&s)) // utf8 := *(*[]byte)(unsafe.Pointer(&s))
utf8 := []byte(s) utf8 := []byte(*s)
var ( var (
offset int = 1 offset int = 1
bitshift byte = 0 bitshift byte = 0
leap, shift bool leap, shift bool
) )
encodedSize := GSM7EncodesInto(&s) encodedSize := GSM7EncodesInto(s)
cap := buf.Cap() cap := buf.Cap()
if cap < encodedSize { if cap < encodedSize {
buf.Grow(encodedSize - cap) buf.Grow(encodedSize - cap)

View File

@@ -22,7 +22,7 @@ func TestGSM7EncodeSimpleASCIIString(t *testing.T) {
input := short8nString input := short8nString
expected := short8nStringEncodedBytes expected := short8nStringEncodedBytes
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)
@@ -39,7 +39,7 @@ func TestGSM7EncodeComplexASCIIString(t *testing.T) {
input := longNot8nString input := longNot8nString
expected := longNot8nStringEncodedBytes expected := longNot8nStringEncodedBytes
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)
@@ -56,7 +56,7 @@ func TestGSM7EncodeComplex8nASCIIString(t *testing.T) {
input := "Ducks are fucking great, they quacks, O quackers, what the fuck." input := "Ducks are fucking great, they quacks, O quackers, what the fuck."
expected := long8nStringEncodedBytes expected := long8nStringEncodedBytes
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)
@@ -74,7 +74,7 @@ func TestGSM7EncodeDoesNotAllocateMoreThanNecessary(t *testing.T) {
buf.Reset() buf.Reset()
expected := buf.Cap() expected := buf.Cap()
err := coder.Encode(input, buf) err := coder.Encode(&input, buf)
actual := buf.Cap() actual := buf.Cap()
if err != nil { if err != nil {
@@ -93,7 +93,7 @@ func TestGSM7EncodeDoesAllocateWhenNecessary(t *testing.T) {
buf.Reset() buf.Reset()
original := buf.Cap() original := buf.Cap()
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
modified := buf.Cap() modified := buf.Cap()
if err != nil { if err != nil {
@@ -111,7 +111,7 @@ func TestGSM7EncodeEmptyString(t *testing.T) {
input := "" input := ""
expected := []byte{} expected := []byte{}
err := coder.Encode(input, &buf) err := coder.Encode(&input, &buf)
if err != nil { if err != nil {
t.Errorf("Expected no error, but got %v", err) t.Errorf("Expected no error, but got %v", err)
@@ -330,7 +330,7 @@ func BenchmarkGSM7EncodeSimpleASCIIString(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
coder.Encode(input, &buf) coder.Encode(&input, &buf)
} }
} }
@@ -341,7 +341,7 @@ func BenchmarkGSM7EncodeComplexASCIIString(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
coder.Encode(input, &buf) coder.Encode(&input, &buf)
} }
} }
@@ -352,7 +352,7 @@ func BenchmarkGSM7EncodeComplex8nASCIIString(b *testing.B) {
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
coder.Encode(input, &buf) coder.Encode(&input, &buf)
} }
} }
@@ -364,6 +364,6 @@ func BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
buf := bytes.NewBuffer(make([]byte, GSM7EncodesInto(&input))) buf := bytes.NewBuffer(make([]byte, GSM7EncodesInto(&input)))
buf.Reset() buf.Reset()
coder.Encode(input, buf) coder.Encode(&input, buf)
} }
} }