Added serialization package. Encode user input.

This commit is contained in:
Kelvin Clement Mwinuka
2023-06-22 22:54:37 +08:00
parent 84220cd82c
commit d1953c89e9
3 changed files with 115 additions and 0 deletions

View File

@@ -2,6 +2,7 @@ package main
import ( import (
"bufio" "bufio"
"bytes"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"encoding/json" "encoding/json"
@@ -12,6 +13,7 @@ import (
"os" "os"
"path" "path"
"github.com/kelvinmwinuka/memstore/serialization"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
) )
@@ -108,4 +110,33 @@ func main() {
} }
defer conn.Close() defer conn.Close()
done := make(chan struct{})
// connRW := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
stdioRW := bufio.NewReadWriter(bufio.NewReader(os.Stdin), bufio.NewWriter(os.Stdout))
go func() {
for {
stdioRW.Write([]byte("\n> "))
stdioRW.Flush()
if in, err := stdioRW.ReadBytes(byte('\n')); err != nil {
stdioRW.Write([]byte(fmt.Sprintf("ERROR: %s\n", err)))
stdioRW.Flush()
} else {
in := bytes.TrimSpace(in)
// Check for exit command
if bytes.Equal(bytes.ToLower(in), []byte("exit")) {
break
}
stdioRW.Write(serialization.Encode(in))
stdioRW.Flush()
}
}
done <- struct{}{}
}()
<-done
} }

1
serialization/decode.go Normal file
View File

@@ -0,0 +1 @@
package serialization

83
serialization/encode.go Normal file
View File

@@ -0,0 +1,83 @@
package serialization
import (
"bytes"
"errors"
"fmt"
"log"
)
func tokenize(b []byte) ([][]byte, error) {
qOpen := false
transformed := []byte("")
for _, c := range b {
if c != ' ' && c != '"' {
transformed = append(transformed, c)
continue
}
if c == '"' {
qOpen = !qOpen
if qOpen && !bytes.HasSuffix(transformed, []byte(" ")) {
transformed = append(transformed, ' ')
}
transformed = append(transformed, c)
continue
}
if c == ' ' && qOpen {
transformed = append(transformed, []byte("*-*")...)
continue
}
if c == ' ' && !qOpen {
transformed = append(transformed, c)
continue
}
}
if qOpen {
return nil, errors.New("open quote in command")
}
tokens := bytes.Split(transformed, []byte(" "))
for i := 0; i < len(tokens); i++ {
tokens[i] = bytes.Trim(tokens[i], "\"")
tokens[i] = bytes.ReplaceAll(tokens[i], []byte("*-*"), []byte(" "))
}
return tokens, nil
}
func Encode(b []byte) []byte {
tokens, err := tokenize(b)
if err != nil {
log.Fatal(err)
}
if len(tokens) <= 0 {
return b
}
if len(tokens) == 1 && bytes.Equal(bytes.ToLower(tokens[0]), []byte("ping")) {
return []byte(fmt.Sprintf("+%s\r\n", string(bytes.ToUpper(tokens[0]))))
}
if len(tokens) > 1 && bytes.Equal(bytes.ToLower(tokens[0]), []byte("ping")) {
enc := []byte(fmt.Sprintf("*%d\r\n$%d\r\n%s\r\n",
len(tokens), len(tokens[0]), string(bytes.ToUpper(tokens[0]))))
for i := 1; i < len(tokens); i++ {
token := tokens[i]
enc = append(enc, []byte(fmt.Sprintf("$%d\r\n%s\r\n", len(token), token))...)
}
return enc
}
return b
}