OLD | NEW |
1 // Go support for Protocol Buffers - Google's data interchange format | 1 // Go support for Protocol Buffers - Google's data interchange format |
2 // | 2 // |
3 // Copyright 2010 The Go Authors. All rights reserved. | 3 // Copyright 2010 The Go Authors. All rights reserved. |
4 // http://code.google.com/p/goprotobuf/ | 4 // http://code.google.com/p/goprotobuf/ |
5 // | 5 // |
6 // Redistribution and use in source and binary forms, with or without | 6 // Redistribution and use in source and binary forms, with or without |
7 // modification, are permitted provided that the following conditions are | 7 // modification, are permitted provided that the following conditions are |
8 // met: | 8 // met: |
9 // | 9 // |
10 // * Redistributions of source code must retain the above copyright | 10 // * Redistributions of source code must retain the above copyright |
(...skipping 17 matching lines...) Expand all Loading... |
28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 28 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 29 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 30 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | 31 |
32 package proto | 32 package proto |
33 | 33 |
34 // Functions for parsing the Text protocol buffer format. | 34 // Functions for parsing the Text protocol buffer format. |
35 // TODO: message sets. | 35 // TODO: message sets. |
36 | 36 |
37 import ( | 37 import ( |
| 38 "encoding" |
38 "errors" | 39 "errors" |
39 "fmt" | 40 "fmt" |
40 "reflect" | 41 "reflect" |
41 "strconv" | 42 "strconv" |
42 "strings" | 43 "strings" |
43 "unicode/utf8" | 44 "unicode/utf8" |
44 ) | 45 ) |
45 | 46 |
46 // textUnmarshaler is implemented by Messages that can unmarshal themsleves. | |
47 // It is identical to encoding.TextUnmarshaler, introduced in go 1.2, | |
48 // which will eventually replace it. | |
49 type textUnmarshaler interface { | |
50 UnmarshalText(text []byte) error | |
51 } | |
52 | |
53 type ParseError struct { | 47 type ParseError struct { |
54 Message string | 48 Message string |
55 Line int // 1-based line number | 49 Line int // 1-based line number |
56 Offset int // 0-based byte offset from start of input | 50 Offset int // 0-based byte offset from start of input |
57 } | 51 } |
58 | 52 |
59 func (p *ParseError) Error() string { | 53 func (p *ParseError) Error() string { |
60 if p.Line == 1 { | 54 if p.Line == 1 { |
61 // show offset only for first line | 55 // show offset only for first line |
62 return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) | 56 return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 case reflect.Struct: | 646 case reflect.Struct: |
653 var terminator string | 647 var terminator string |
654 switch tok.value { | 648 switch tok.value { |
655 case "{": | 649 case "{": |
656 terminator = "}" | 650 terminator = "}" |
657 case "<": | 651 case "<": |
658 terminator = ">" | 652 terminator = ">" |
659 default: | 653 default: |
660 return p.errorf("expected '{' or '<', found %q", tok.val
ue) | 654 return p.errorf("expected '{' or '<', found %q", tok.val
ue) |
661 } | 655 } |
662 » » // TODO: Handle nested messages which implement textUnmarshaler. | 656 » » // TODO: Handle nested messages which implement encoding.TextUnm
arshaler. |
663 return p.readStruct(fv, terminator) | 657 return p.readStruct(fv, terminator) |
664 case reflect.Uint32: | 658 case reflect.Uint32: |
665 if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { | 659 if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { |
666 fv.SetUint(uint64(x)) | 660 fv.SetUint(uint64(x)) |
667 return nil | 661 return nil |
668 } | 662 } |
669 case reflect.Uint64: | 663 case reflect.Uint64: |
670 if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { | 664 if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { |
671 fv.SetUint(x) | 665 fv.SetUint(x) |
672 return nil | 666 return nil |
673 } | 667 } |
674 } | 668 } |
675 return p.errorf("invalid %v: %v", v.Type(), tok.value) | 669 return p.errorf("invalid %v: %v", v.Type(), tok.value) |
676 } | 670 } |
677 | 671 |
678 // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb | 672 // UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb |
679 // before starting to unmarshal, so any existing data in pb is always removed. | 673 // before starting to unmarshal, so any existing data in pb is always removed. |
680 // If a required field is not set and no other error occurs, | 674 // If a required field is not set and no other error occurs, |
681 // UnmarshalText returns *RequiredNotSetError. | 675 // UnmarshalText returns *RequiredNotSetError. |
682 func UnmarshalText(s string, pb Message) error { | 676 func UnmarshalText(s string, pb Message) error { |
683 » if um, ok := pb.(textUnmarshaler); ok { | 677 » if um, ok := pb.(encoding.TextUnmarshaler); ok { |
684 err := um.UnmarshalText([]byte(s)) | 678 err := um.UnmarshalText([]byte(s)) |
685 return err | 679 return err |
686 } | 680 } |
687 pb.Reset() | 681 pb.Reset() |
688 v := reflect.ValueOf(pb) | 682 v := reflect.ValueOf(pb) |
689 if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { | 683 if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { |
690 return pe | 684 return pe |
691 } | 685 } |
692 return nil | 686 return nil |
693 } | 687 } |
OLD | NEW |