package main import ( "bufio" "errors" "fmt" "io" "log" "net" "strings" ) func getCommand(reader io.Reader) (string, error) { scanner := bufio.NewScanner(reader) for scanner.Scan() { str := scanner.Text() return str, nil } return "", scanner.Err() } func isCommand(str string) bool { switch str { case "GET": fallthrough case "SET": fallthrough case "DEL": return true default: return false } } func parseCmd(line string) (string, string, string, error) { cmd, key, val := "", "", "" var err error parts := strings.Split(line, " ") if len(parts) != 2 && len(parts) != 3 { err = errors.New("Invalid number of arguments") } else { for i, part := range parts { switch i { case 0: if isCommand(part) { cmd = part } else { err = errors.New("Unknown command") break } case 1: key = part case 2: if cmd == "SET" { val = part } else { err = errors.New("Invalid number of arguments") } } } } return cmd, key, val, err } func respond(writer io.Writer, ret string) { _, err := io.WriteString(writer, ret+"\n") if err != nil { log.Println(err) } } func main() { db := make(map[string]string) ln, err := net.Listen("tcp", ":9000") if err != nil { panic(err) } defer ln.Close() for { conn, err := ln.Accept() if err != nil { panic(err) } go func() { line, err := getCommand(conn) if err != nil { respond(conn, fmt.Sprint(err)) } cmd, key, val, err := parseCmd(line) if err != nil { respond(conn, fmt.Sprint(err)) } switch cmd { case "DEL": log.Println("Deleting", key) delete(db, key) case "GET": log.Println("Getting", key) ret, ok := db[key] if ok { log.Println("Value found", ret) respond(conn, ret) } else { log.Println("Unknown key", key) } case "SET": log.Println("Setting", key) db[key] = val } defer conn.Close() }() } }