diff --git a/src/adapt.go b/src/adapt.go index 476b7da..de24e6a 100755 --- a/src/adapt.go +++ b/src/adapt.go @@ -65,90 +65,85 @@ func adapt(ctx context.Context, config Config, conn net.Conn) error { return io.EOF } -func readMessage(reader *bufio.Reader) ([]byte, []any, error) { +func readMessage(reader *bufio.Reader) ([]byte, error) { w := bytes.NewBuffer(nil) - arr, err := readMessageTo(w, reader) - return w.Bytes(), arr, err + err := readMessageTo(w, reader) + return w.Bytes(), err } -func readMessageTo(w io.Writer, reader *bufio.Reader) ([]any, error) { +func readMessageTo(w io.Writer, reader *bufio.Reader) error { w2 := bufio.NewWriter(w) defer w2.Flush() - arr, err := _readMessageTo(w2, reader) + err := _readMessageTo(w2, reader) if err != nil { - return nil, err + return err } - return arr, w2.Flush() + return w2.Flush() } -func _readMessageTo(w io.Writer, reader *bufio.Reader) ([]any, error) { +func _readMessageTo(w io.Writer, reader *bufio.Reader) error { firstLine, _, err := reader.ReadLine() if err != nil { - return nil, err + return err } firstLine = bytes.TrimSuffix(firstLine, []byte("\r\n")) if len(firstLine) == 0 { - return nil, nil + return nil } fmt.Fprintf(w, "%s\r\n", firstLine) switch firstLine[0] { case '+': // simple string, like +OK - return []any{string(firstLine[1:])}, nil + return nil case '-': // simple error, like -message - return []any{string(firstLine)}, nil + return nil case ':': // number, like /[+-][0-9]+/ - firstLine = bytes.TrimPrefix(firstLine[1:], []byte("+")) - n, err := strconv.Atoi(string(firstLine)) - if err != nil { - return nil, fmt.Errorf("num not a num: %q: %w", firstLine, err) - } - return []any{n}, err + return err case '$': // long string, like $-1 for nil, like $LEN\r\nSTRING\r\n if firstLine[1] == '-' { - return []any{nil}, nil + return nil } firstLine = bytes.TrimPrefix(firstLine[1:], []byte("+")) n, err := strconv.Atoi(string(firstLine)) if err != nil { - return nil, fmt.Errorf("num not a num: %q: %w", firstLine, err) + return fmt.Errorf("num not a num: %q: %w", firstLine, err) } - //log.Printf("reading %v+2 bytes for bulk string", n) nextLine := make([]byte, n+2) nAt := 0 for nAt < n+2 { nMore, err := reader.Read(nextLine[nAt:]) if err != nil { - return nil, fmt.Errorf("couldnt read %v more/%v bytes for long string: %w", n+2-nAt, n+2, err) + return fmt.Errorf("couldnt read %v more/%v bytes for long string: %w", n+2-nAt, n+2, err) } nAt += nMore } fmt.Fprintf(w, "%s", nextLine) - return []any{string(nextLine)}, err - case '*': // array, like *-1 for nil, like *4 for [1,2,3,4] + return err + case '*', '%': // *=array %=map, like *-1 for nil, like *4 for [1,2,3,4] n, err := strconv.Atoi(string(firstLine[1:])) if err != nil { - return nil, fmt.Errorf("arr not a num: %q: %w", firstLine, err) + return fmt.Errorf("arr not a num: %q: %w", firstLine, err) } else if n == -1 { - return nil, nil + return nil + } + if firstLine[0] == '%' { + n *= 2 } - var result []any for i := 0; i < n; i++ { - more, err := _readMessageTo(w, reader) + err := _readMessageTo(w, reader) if err != nil { - return nil, err + return err } - result = append(result, more...) } - return result, nil + return nil case '_': // nil - return nil, nil + return nil case '#': // boolean, like #t or #f - return []any{firstLine[1] == 't'}, nil + return nil case ',': // double - log.Fatal("not impl") + return nil } log.Fatalf("not impl: %q", firstLine) - return nil, nil + return nil } diff --git a/src/config.go b/src/config.go index 39257e8..ce626dc 100755 --- a/src/config.go +++ b/src/config.go @@ -73,7 +73,7 @@ func NewConfig(ctx context.Context) (Config, error) { v.Close() return nil } - if raw, _, err := readMessage(bufio.NewReader(v)); err != nil { + if raw, err := readMessage(bufio.NewReader(v)); err != nil { log.Printf("! failed read hello %q: %v", forward, err) v.Close() return nil