"Fossies" - the Fresh Open Source Software Archive 
Member "gdrive-2.1.1/vendor/google.golang.org/api/googleapi/internal/uritemplates/uritemplates.go" (28 May 2021, 5224 Bytes) of package /linux/misc/gdrive-2.1.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 // Copyright 2013 Joshua Tacoma. 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
5 // Package uritemplates is a level 3 implementation of RFC 6570 (URI
6 // Template, http://tools.ietf.org/html/rfc6570).
7 // uritemplates does not support composite values (in Go: slices or maps)
8 // and so does not qualify as a level 4 implementation.
9 package uritemplates
10
11 import (
12 "bytes"
13 "errors"
14 "regexp"
15 "strconv"
16 "strings"
17 )
18
19 var (
20 unreserved = regexp.MustCompile("[^A-Za-z0-9\\-._~]")
21 reserved = regexp.MustCompile("[^A-Za-z0-9\\-._~:/?#[\\]@!$&'()*+,;=]")
22 validname = regexp.MustCompile("^([A-Za-z0-9_\\.]|%[0-9A-Fa-f][0-9A-Fa-f])+$")
23 hex = []byte("0123456789ABCDEF")
24 )
25
26 func pctEncode(src []byte) []byte {
27 dst := make([]byte, len(src)*3)
28 for i, b := range src {
29 buf := dst[i*3 : i*3+3]
30 buf[0] = 0x25
31 buf[1] = hex[b/16]
32 buf[2] = hex[b%16]
33 }
34 return dst
35 }
36
37 func escape(s string, allowReserved bool) string {
38 if allowReserved {
39 return string(reserved.ReplaceAllFunc([]byte(s), pctEncode))
40 }
41 return string(unreserved.ReplaceAllFunc([]byte(s), pctEncode))
42 }
43
44 // A uriTemplate is a parsed representation of a URI template.
45 type uriTemplate struct {
46 raw string
47 parts []templatePart
48 }
49
50 // parse parses a URI template string into a uriTemplate object.
51 func parse(rawTemplate string) (*uriTemplate, error) {
52 split := strings.Split(rawTemplate, "{")
53 parts := make([]templatePart, len(split)*2-1)
54 for i, s := range split {
55 if i == 0 {
56 if strings.Contains(s, "}") {
57 return nil, errors.New("unexpected }")
58 }
59 parts[i].raw = s
60 continue
61 }
62 subsplit := strings.Split(s, "}")
63 if len(subsplit) != 2 {
64 return nil, errors.New("malformed template")
65 }
66 expression := subsplit[0]
67 var err error
68 parts[i*2-1], err = parseExpression(expression)
69 if err != nil {
70 return nil, err
71 }
72 parts[i*2].raw = subsplit[1]
73 }
74 return &uriTemplate{
75 raw: rawTemplate,
76 parts: parts,
77 }, nil
78 }
79
80 type templatePart struct {
81 raw string
82 terms []templateTerm
83 first string
84 sep string
85 named bool
86 ifemp string
87 allowReserved bool
88 }
89
90 type templateTerm struct {
91 name string
92 explode bool
93 truncate int
94 }
95
96 func parseExpression(expression string) (result templatePart, err error) {
97 switch expression[0] {
98 case '+':
99 result.sep = ","
100 result.allowReserved = true
101 expression = expression[1:]
102 case '.':
103 result.first = "."
104 result.sep = "."
105 expression = expression[1:]
106 case '/':
107 result.first = "/"
108 result.sep = "/"
109 expression = expression[1:]
110 case ';':
111 result.first = ";"
112 result.sep = ";"
113 result.named = true
114 expression = expression[1:]
115 case '?':
116 result.first = "?"
117 result.sep = "&"
118 result.named = true
119 result.ifemp = "="
120 expression = expression[1:]
121 case '&':
122 result.first = "&"
123 result.sep = "&"
124 result.named = true
125 result.ifemp = "="
126 expression = expression[1:]
127 case '#':
128 result.first = "#"
129 result.sep = ","
130 result.allowReserved = true
131 expression = expression[1:]
132 default:
133 result.sep = ","
134 }
135 rawterms := strings.Split(expression, ",")
136 result.terms = make([]templateTerm, len(rawterms))
137 for i, raw := range rawterms {
138 result.terms[i], err = parseTerm(raw)
139 if err != nil {
140 break
141 }
142 }
143 return result, err
144 }
145
146 func parseTerm(term string) (result templateTerm, err error) {
147 // TODO(djd): Remove "*" suffix parsing once we check that no APIs have
148 // mistakenly used that attribute.
149 if strings.HasSuffix(term, "*") {
150 result.explode = true
151 term = term[:len(term)-1]
152 }
153 split := strings.Split(term, ":")
154 if len(split) == 1 {
155 result.name = term
156 } else if len(split) == 2 {
157 result.name = split[0]
158 var parsed int64
159 parsed, err = strconv.ParseInt(split[1], 10, 0)
160 result.truncate = int(parsed)
161 } else {
162 err = errors.New("multiple colons in same term")
163 }
164 if !validname.MatchString(result.name) {
165 err = errors.New("not a valid name: " + result.name)
166 }
167 if result.explode && result.truncate > 0 {
168 err = errors.New("both explode and prefix modifers on same term")
169 }
170 return result, err
171 }
172
173 // Expand expands a URI template with a set of values to produce a string.
174 func (t *uriTemplate) Expand(values map[string]string) string {
175 var buf bytes.Buffer
176 for _, p := range t.parts {
177 p.expand(&buf, values)
178 }
179 return buf.String()
180 }
181
182 func (tp *templatePart) expand(buf *bytes.Buffer, values map[string]string) {
183 if len(tp.raw) > 0 {
184 buf.WriteString(tp.raw)
185 return
186 }
187 var first = true
188 for _, term := range tp.terms {
189 value, exists := values[term.name]
190 if !exists {
191 continue
192 }
193 if first {
194 buf.WriteString(tp.first)
195 first = false
196 } else {
197 buf.WriteString(tp.sep)
198 }
199 tp.expandString(buf, term, value)
200 }
201 }
202
203 func (tp *templatePart) expandName(buf *bytes.Buffer, name string, empty bool) {
204 if tp.named {
205 buf.WriteString(name)
206 if empty {
207 buf.WriteString(tp.ifemp)
208 } else {
209 buf.WriteString("=")
210 }
211 }
212 }
213
214 func (tp *templatePart) expandString(buf *bytes.Buffer, t templateTerm, s string) {
215 if len(s) > t.truncate && t.truncate > 0 {
216 s = s[:t.truncate]
217 }
218 tp.expandName(buf, t.name, len(s) == 0)
219 buf.WriteString(escape(s, tp.allowReserved))
220 }