1// Copyright 2013 Google Inc. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package googleapi
6
7import (
8	"encoding/json"
9	"errors"
10	"strconv"
11)
12
13// Int64s is a slice of int64s that marshal as quoted strings in JSON.
14type Int64s []int64
15
16func (q *Int64s) UnmarshalJSON(raw []byte) error {
17	*q = (*q)[:0]
18	var ss []string
19	if err := json.Unmarshal(raw, &ss); err != nil {
20		return err
21	}
22	for _, s := range ss {
23		v, err := strconv.ParseInt(s, 10, 64)
24		if err != nil {
25			return err
26		}
27		*q = append(*q, int64(v))
28	}
29	return nil
30}
31
32// Int32s is a slice of int32s that marshal as quoted strings in JSON.
33type Int32s []int32
34
35func (q *Int32s) UnmarshalJSON(raw []byte) error {
36	*q = (*q)[:0]
37	var ss []string
38	if err := json.Unmarshal(raw, &ss); err != nil {
39		return err
40	}
41	for _, s := range ss {
42		v, err := strconv.ParseInt(s, 10, 32)
43		if err != nil {
44			return err
45		}
46		*q = append(*q, int32(v))
47	}
48	return nil
49}
50
51// Uint64s is a slice of uint64s that marshal as quoted strings in JSON.
52type Uint64s []uint64
53
54func (q *Uint64s) UnmarshalJSON(raw []byte) error {
55	*q = (*q)[:0]
56	var ss []string
57	if err := json.Unmarshal(raw, &ss); err != nil {
58		return err
59	}
60	for _, s := range ss {
61		v, err := strconv.ParseUint(s, 10, 64)
62		if err != nil {
63			return err
64		}
65		*q = append(*q, uint64(v))
66	}
67	return nil
68}
69
70// Uint32s is a slice of uint32s that marshal as quoted strings in JSON.
71type Uint32s []uint32
72
73func (q *Uint32s) UnmarshalJSON(raw []byte) error {
74	*q = (*q)[:0]
75	var ss []string
76	if err := json.Unmarshal(raw, &ss); err != nil {
77		return err
78	}
79	for _, s := range ss {
80		v, err := strconv.ParseUint(s, 10, 32)
81		if err != nil {
82			return err
83		}
84		*q = append(*q, uint32(v))
85	}
86	return nil
87}
88
89// Float64s is a slice of float64s that marshal as quoted strings in JSON.
90type Float64s []float64
91
92func (q *Float64s) UnmarshalJSON(raw []byte) error {
93	*q = (*q)[:0]
94	var ss []string
95	if err := json.Unmarshal(raw, &ss); err != nil {
96		return err
97	}
98	for _, s := range ss {
99		v, err := strconv.ParseFloat(s, 64)
100		if err != nil {
101			return err
102		}
103		*q = append(*q, float64(v))
104	}
105	return nil
106}
107
108func quotedList(n int, fn func(dst []byte, i int) []byte) ([]byte, error) {
109	dst := make([]byte, 0, 2+n*10) // somewhat arbitrary
110	dst = append(dst, '[')
111	for i := 0; i < n; i++ {
112		if i > 0 {
113			dst = append(dst, ',')
114		}
115		dst = append(dst, '"')
116		dst = fn(dst, i)
117		dst = append(dst, '"')
118	}
119	dst = append(dst, ']')
120	return dst, nil
121}
122
123func (s Int64s) MarshalJSON() ([]byte, error) {
124	return quotedList(len(s), func(dst []byte, i int) []byte {
125		return strconv.AppendInt(dst, s[i], 10)
126	})
127}
128
129func (s Int32s) MarshalJSON() ([]byte, error) {
130	return quotedList(len(s), func(dst []byte, i int) []byte {
131		return strconv.AppendInt(dst, int64(s[i]), 10)
132	})
133}
134
135func (s Uint64s) MarshalJSON() ([]byte, error) {
136	return quotedList(len(s), func(dst []byte, i int) []byte {
137		return strconv.AppendUint(dst, s[i], 10)
138	})
139}
140
141func (s Uint32s) MarshalJSON() ([]byte, error) {
142	return quotedList(len(s), func(dst []byte, i int) []byte {
143		return strconv.AppendUint(dst, uint64(s[i]), 10)
144	})
145}
146
147func (s Float64s) MarshalJSON() ([]byte, error) {
148	return quotedList(len(s), func(dst []byte, i int) []byte {
149		return strconv.AppendFloat(dst, s[i], 'g', -1, 64)
150	})
151}
152
153// RawMessage is a raw encoded JSON value.
154// It is identical to json.RawMessage, except it does not suffer from
155// https://golang.org/issue/14493.
156type RawMessage []byte
157
158// MarshalJSON returns m.
159func (m RawMessage) MarshalJSON() ([]byte, error) {
160	return m, nil
161}
162
163// UnmarshalJSON sets *m to a copy of data.
164func (m *RawMessage) UnmarshalJSON(data []byte) error {
165	if m == nil {
166		return errors.New("googleapi.RawMessage: UnmarshalJSON on nil pointer")
167	}
168	*m = append((*m)[:0], data...)
169	return nil
170}
171
172/*
173 * Helper routines for simplifying the creation of optional fields of basic type.
174 */
175
176// Bool is a helper routine that allocates a new bool value
177// to store v and returns a pointer to it.
178func Bool(v bool) *bool { return &v }
179
180// Int32 is a helper routine that allocates a new int32 value
181// to store v and returns a pointer to it.
182func Int32(v int32) *int32 { return &v }
183
184// Int64 is a helper routine that allocates a new int64 value
185// to store v and returns a pointer to it.
186func Int64(v int64) *int64 { return &v }
187
188// Float64 is a helper routine that allocates a new float64 value
189// to store v and returns a pointer to it.
190func Float64(v float64) *float64 { return &v }
191
192// Uint32 is a helper routine that allocates a new uint32 value
193// to store v and returns a pointer to it.
194func Uint32(v uint32) *uint32 { return &v }
195
196// Uint64 is a helper routine that allocates a new uint64 value
197// to store v and returns a pointer to it.
198func Uint64(v uint64) *uint64 { return &v }
199
200// String is a helper routine that allocates a new string value
201// to store v and returns a pointer to it.
202func String(v string) *string { return &v }
203