github.com/gogo/protobuf@v1.3.2/test/int64support/object_js.go (about) 1 package int64support 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "strconv" 8 ) 9 10 var ( 11 _ = json.Marshaler(new(Object)) 12 _ = json.Unmarshaler(new(Object)) 13 ) 14 15 func (o *Object) MarshalJSON() ([]byte, error) { 16 if o.OptionalNumber == nil { 17 return ([]byte)("{}"), nil 18 } 19 return ([]byte)(fmt.Sprintf("{\"optional_number\": %d}", *o.OptionalNumber)), nil 20 } 21 22 func (o *Object) UnmarshalJSON(b []byte) error { 23 var ( 24 trim = func(v []byte) []byte { return bytes.Trim(v, " \n\r\t") } 25 strip = func(v []byte, first, last byte) ([]byte, error) { 26 x := len(v) 27 if x < 2 || v[0] != first || v[x-1] != last { 28 return nil, fmt.Errorf("failed to strip %q and %q from byte sequence", first, last) 29 } 30 return v[1 : x-1], nil 31 } 32 ) 33 b, err := strip(trim(b), '{', '}') 34 if err != nil { 35 return err 36 } 37 // poor man parser: assume the only commas appear between JSON key-value pairs, 38 // and that object hierarchy is flat 39 for xf, f := range bytes.Split(b, ([]byte)(",")) { 40 parts := bytes.SplitN(f, ([]byte)(":"), 2) 41 if x := len(parts); x != 2 { 42 if xf == 0 && (x == 0 || (x == 1 && len(trim(parts[0])) == 0)) { 43 return nil // empty object 44 } 45 return fmt.Errorf("failed to parse field-value seperator char ':'") 46 } 47 fieldName, err := strip(trim(parts[0]), '"', '"') 48 if err != nil { 49 return err 50 } 51 if string(fieldName) != "optional_number" { 52 continue // ignore unknown field 53 } 54 fieldValue := trim(parts[1]) 55 v, err := strconv.ParseInt(string(fieldValue), 10, 64) 56 if err != nil { 57 return err 58 } 59 o.OptionalNumber = &v 60 break 61 } 62 return nil 63 }