Skip to content

Instantly share code, notes, and snippets.

@apage43
Created September 27, 2013 21:12
Show Gist options
  • Save apage43/6735260 to your computer and use it in GitHub Desktop.
Save apage43/6735260 to your computer and use it in GitHub Desktop.
package main
import (
"bufio"
"bytes"
"fmt"
"os"
)
type State int
const (
INSIDE State = iota
OUTSIDE
ESCAPED
)
type Machine struct {
state State
Stringbuf bytes.Buffer
Output *bufio.Writer
}
func (m *Machine) Tick(inchar rune) {
incomingState := m.state
if m.state == ESCAPED {
m.state = INSIDE
} else {
switch inchar {
case '"':
switch m.state {
case OUTSIDE:
m.state = INSIDE
case INSIDE:
// Do stuff with content of Stringbuf
m.state = OUTSIDE
}
case '\\':
if m.state == INSIDE {
m.state = ESCAPED
}
}
}
if (m.state == INSIDE || m.state == ESCAPED) && (incomingState == INSIDE || incomingState == ESCAPED) {
m.Stringbuf.WriteRune(inchar)
}
if m.state == OUTSIDE || incomingState == OUTSIDE {
m.Output.WriteRune(inchar)
}
}
func main() {
test := "[1,2,\"three \\\"thirty\", 4, \"four\", {\"what\":\"yeah\"}]"
machine := Machine{OUTSIDE, bytes.Buffer{}, bufio.NewWriter(os.Stdout)}
for _, char := range test {
machine.Tick(char)
}
fmt.Printf("stringbuf: %v\n", machine.Stringbuf.String())
machine.Output.Flush()
}
@dustin
Copy link

dustin commented Sep 29, 2013

I've got this basically working. It takes an io.Reader and gives me a new io.Reader -- all JSON flowing through it has each string go through a transformer that takes a string and spits out a new string. Now I just need to figure out how to describe what I want to it.

func rewriteJson(in io.Reader, trans transformer) io.Reader {
    pr, pw := io.Pipe()

    go func() {
        m := newMachine(os.Stdout, trans)
        pw.CloseWithError(m.rage(bufio.NewReader(in)))
    }()

    return pr
}

func main() {
    test := "[1,2,\"three \\\"thirty\", 4, \"four\", {\"what\":\"yeah\"}]"
    r := rewriteJson(strings.NewReader(test), strings.Title)
    _, err := io.Copy(os.Stdout, r)
    if err != nil {
        panic(err)
    }
}

@dustin
Copy link

dustin commented Sep 29, 2013

Applied: https://github.com/couchbaselabs/consolio/blob/master/tools/confsed/confsed.go#L39

You point this thing to a URL and give it a JSON map and it issues a new request that looks just like the original, but to the destination you want, and then rewrites the results, retaining headers and stuff. Probably not the most correct behavior for a proxy, but it does the thing I want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment