Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(11)

Unified Diff: upgrade/msg.go

Issue 6307061: upgrader: new command and upgrade package
Patch Set: upgrader: new command and upgrade package Created 13 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « state/internal_test.go ('k') | upgrade/upgrade.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: upgrade/msg.go
=== added file 'upgrade/msg.go'
--- upgrade/msg.go 1970-01-01 00:00:00 +0000
+++ upgrade/msg.go 2012-06-11 17:51:30 +0000
@@ -0,0 +1,125 @@
+package upgrade
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// ErrorMessage is an internal type but exported because it is
+// cross package.
+//
+// ErrorMessage represents a message holding an error.
+type ErrorMessage struct {
+ S string
+}
+
+func (e *ErrorMessage) Error() string {
+ return e.S
+}
+
+// ReadMsg is an internal function but exported because it is
+// cross-package; part of the implementation of the "upgrader" command.
+//
+// ReadMsg reads a message from r. If the message type is "error",
+// a *ErrorMessage value will be returned in err, otherwise if expect
+// is non-empty, it must match the message type.
+func ReadMsg(r io.Reader, expect string) (msg []string, err error) {
+ line, err := readLine(r)
+ if err != nil {
+ if err == io.EOF {
+ err = io.ErrUnexpectedEOF
+ }
+ return nil, err
+ }
+ if !bytes.HasPrefix(line, []byte("upgrade: ")) {
+ return nil, fmt.Errorf("bad message %q", line)
+ }
+ line = line[len("upgrade:"):]
+ var m quotedList
+ if _, err := fmt.Fscanf(bytes.NewReader(line), "%q", &m); err != nil {
+ return nil, fmt.Errorf("cannot parse message %q: %v", line, err)
+ }
+ switch {
+ case len(m) == 0:
+ return nil, errors.New("message has no content")
+ case m[0] == "error" && len(m) < 2:
+ return nil, errors.New("error with no message")
+ case m[0] == "error":
+ return nil, &ErrorMessage{m[1]}
+ case expect != "" && m[0] != expect:
+ return nil, fmt.Errorf("unexpected message; expected %q got %q", expect, m)
+ }
+ return m, nil
+}
+
+// WriteMsg is an internal function but exported because it is
+// cross-package; part of the implementation of the "upgrader" command.
+//
+// WriteMsg writes the given message to w.
+// The message type is given in the first element of m.
+func WriteMsg(w io.Writer, m ...string) error {
+ _, err := fmt.Fprintf(w, "upgrade: %q\n", m)
+ return err
+}
+
+// readLine reads a full line a byte at a time from the reader
+// so that we can avoid reading more than we need.
+func readLine(r io.Reader) (line []byte, err error) {
+ buf := make([]byte, 1)
+ for {
+ n, err := r.Read(buf)
+ if err != nil {
+ return nil, err
+ }
+ if n == 0 {
+ continue
+ }
+ if buf[0] == '\n' {
+ return line, nil
+ }
+ line = append(line, buf...)
+ }
+ panic("not reached")
+}
+
+// quotedList implements scanning of a quoted string list, as
+// produced by fmt.Printf("%q", []string{...})
+type quotedList []string
+
+func (q *quotedList) Scan(state fmt.ScanState, verb rune) error {
+ if verb != 'q' && verb != 'v' {
+ return errors.New("quoted list requires %q or %v verb")
+ }
+ state.SkipSpace()
+ r, _, err := state.ReadRune()
+ if err != nil {
+ return err
+ }
+ if r != '[' {
+ state.UnreadRune()
+ return fmt.Errorf("expected '[', found %#c", r)
+ }
+ var s string
+ for {
+ state.SkipSpace()
+ r, _, err = state.ReadRune()
+ if err != nil {
+ return err
+ }
+ if r == ']' {
+ return nil
+ }
+ state.UnreadRune()
+ if r != '"' {
+ return fmt.Errorf("expected ']' or '\"', found %#c", r)
+ }
+ _, err := fmt.Fscanf(state, "%q", &s)
+ if err != nil {
+ return err
+ }
+ *q = append(*q, s)
+ }
+ panic("not reached")
+}
« no previous file with comments | « state/internal_test.go ('k') | upgrade/upgrade.go » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b