Codebase list golang-yaml.v2 / upstream/2.2.1
New upstream version 2.2.1 Anthony Fok 6 years ago
19 changed file(s) with 1299 addition(s) and 336 deletion(s). Raw diff Collapse all Expand all
33 - 1.4
44 - 1.5
55 - 1.6
6 - 1.7
7 - 1.8
8 - 1.9
69 - tip
710
811 go_import_path: gopkg.in/yaml.v2
0 Copyright 2011-2016 Canonical Ltd.
1
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5
6 http://www.apache.org/licenses/LICENSE-2.0
7
8 Unless required by applicable law or agreed to in writing, software
9 distributed under the License is distributed on an "AS IS" BASIS,
10 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 See the License for the specific language governing permissions and
12 limitations under the License.
0 Apache License
1 Version 2.0, January 2004
2 http://www.apache.org/licenses/
3
4 TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
5
6 1. Definitions.
7
8 "License" shall mean the terms and conditions for use, reproduction,
9 and distribution as defined by Sections 1 through 9 of this document.
10
11 "Licensor" shall mean the copyright owner or entity authorized by
12 the copyright owner that is granting the License.
13
14 "Legal Entity" shall mean the union of the acting entity and all
15 other entities that control, are controlled by, or are under common
16 control with that entity. For the purposes of this definition,
17 "control" means (i) the power, direct or indirect, to cause the
18 direction or management of such entity, whether by contract or
19 otherwise, or (ii) ownership of fifty percent (50%) or more of the
20 outstanding shares, or (iii) beneficial ownership of such entity.
21
22 "You" (or "Your") shall mean an individual or Legal Entity
23 exercising permissions granted by this License.
24
25 "Source" form shall mean the preferred form for making modifications,
26 including but not limited to software source code, documentation
27 source, and configuration files.
28
29 "Object" form shall mean any form resulting from mechanical
30 transformation or translation of a Source form, including but
31 not limited to compiled object code, generated documentation,
32 and conversions to other media types.
33
34 "Work" shall mean the work of authorship, whether in Source or
35 Object form, made available under the License, as indicated by a
36 copyright notice that is included in or attached to the work
37 (an example is provided in the Appendix below).
38
39 "Derivative Works" shall mean any work, whether in Source or Object
40 form, that is based on (or derived from) the Work and for which the
41 editorial revisions, annotations, elaborations, or other modifications
42 represent, as a whole, an original work of authorship. For the purposes
43 of this License, Derivative Works shall not include works that remain
44 separable from, or merely link (or bind by name) to the interfaces of,
45 the Work and Derivative Works thereof.
46
47 "Contribution" shall mean any work of authorship, including
48 the original version of the Work and any modifications or additions
49 to that Work or Derivative Works thereof, that is intentionally
50 submitted to Licensor for inclusion in the Work by the copyright owner
51 or by an individual or Legal Entity authorized to submit on behalf of
52 the copyright owner. For the purposes of this definition, "submitted"
53 means any form of electronic, verbal, or written communication sent
54 to the Licensor or its representatives, including but not limited to
55 communication on electronic mailing lists, source code control systems,
56 and issue tracking systems that are managed by, or on behalf of, the
57 Licensor for the purpose of discussing and improving the Work, but
58 excluding communication that is conspicuously marked or otherwise
59 designated in writing by the copyright owner as "Not a Contribution."
60
61 "Contributor" shall mean Licensor and any individual or Legal Entity
62 on behalf of whom a Contribution has been received by Licensor and
63 subsequently incorporated within the Work.
64
65 2. Grant of Copyright License. Subject to the terms and conditions of
66 this License, each Contributor hereby grants to You a perpetual,
67 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68 copyright license to reproduce, prepare Derivative Works of,
69 publicly display, publicly perform, sublicense, and distribute the
70 Work and such Derivative Works in Source or Object form.
71
72 3. Grant of Patent License. Subject to the terms and conditions of
73 this License, each Contributor hereby grants to You a perpetual,
74 worldwide, non-exclusive, no-charge, royalty-free, irrevocable
75 (except as stated in this section) patent license to make, have made,
76 use, offer to sell, sell, import, and otherwise transfer the Work,
77 where such license applies only to those patent claims licensable
78 by such Contributor that are necessarily infringed by their
79 Contribution(s) alone or by combination of their Contribution(s)
80 with the Work to which such Contribution(s) was submitted. If You
81 institute patent litigation against any entity (including a
82 cross-claim or counterclaim in a lawsuit) alleging that the Work
83 or a Contribution incorporated within the Work constitutes direct
84 or contributory patent infringement, then any patent licenses
85 granted to You under this License for that Work shall terminate
86 as of the date such litigation is filed.
87
88 4. Redistribution. You may reproduce and distribute copies of the
89 Work or Derivative Works thereof in any medium, with or without
90 modifications, and in Source or Object form, provided that You
91 meet the following conditions:
92
93 (a) You must give any other recipients of the Work or
94 Derivative Works a copy of this License; and
95
96 (b) You must cause any modified files to carry prominent notices
97 stating that You changed the files; and
98
99 (c) You must retain, in the Source form of any Derivative Works
100 that You distribute, all copyright, patent, trademark, and
101 attribution notices from the Source form of the Work,
102 excluding those notices that do not pertain to any part of
103 the Derivative Works; and
104
105 (d) If the Work includes a "NOTICE" text file as part of its
106 distribution, then any Derivative Works that You distribute must
107 include a readable copy of the attribution notices contained
108 within such NOTICE file, excluding those notices that do not
109 pertain to any part of the Derivative Works, in at least one
110 of the following places: within a NOTICE text file distributed
111 as part of the Derivative Works; within the Source form or
112 documentation, if provided along with the Derivative Works; or,
113 within a display generated by the Derivative Works, if and
114 wherever such third-party notices normally appear. The contents
115 of the NOTICE file are for informational purposes only and
116 do not modify the License. You may add Your own attribution
117 notices within Derivative Works that You distribute, alongside
118 or as an addendum to the NOTICE text from the Work, provided
119 that such additional attribution notices cannot be construed
120 as modifying the License.
121
122 You may add Your own copyright statement to Your modifications and
123 may provide additional or different license terms and conditions
124 for use, reproduction, or distribution of Your modifications, or
125 for any such Derivative Works as a whole, provided Your use,
126 reproduction, and distribution of the Work otherwise complies with
127 the conditions stated in this License.
128
129 5. Submission of Contributions. Unless You explicitly state otherwise,
130 any Contribution intentionally submitted for inclusion in the Work
131 by You to the Licensor shall be under the terms and conditions of
132 this License, without any additional terms or conditions.
133 Notwithstanding the above, nothing herein shall supersede or modify
134 the terms of any separate license agreement you may have executed
135 with Licensor regarding such Contributions.
136
137 6. Trademarks. This License does not grant permission to use the trade
138 names, trademarks, service marks, or product names of the Licensor,
139 except as required for reasonable and customary use in describing the
140 origin of the Work and reproducing the content of the NOTICE file.
141
142 7. Disclaimer of Warranty. Unless required by applicable law or
143 agreed to in writing, Licensor provides the Work (and each
144 Contributor provides its Contributions) on an "AS IS" BASIS,
145 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
146 implied, including, without limitation, any warranties or conditions
147 of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
148 PARTICULAR PURPOSE. You are solely responsible for determining the
149 appropriateness of using or redistributing the Work and assume any
150 risks associated with Your exercise of permissions under this License.
151
152 8. Limitation of Liability. In no event and under no legal theory,
153 whether in tort (including negligence), contract, or otherwise,
154 unless required by applicable law (such as deliberate and grossly
155 negligent acts) or agreed to in writing, shall any Contributor be
156 liable to You for damages, including any direct, indirect, special,
157 incidental, or consequential damages of any character arising as a
158 result of this License or out of the use or inability to use the
159 Work (including but not limited to damages for loss of goodwill,
160 work stoppage, computer failure or malfunction, or any and all
161 other commercial damages or losses), even if such Contributor
162 has been advised of the possibility of such damages.
163
164 9. Accepting Warranty or Additional Liability. While redistributing
165 the Work or Derivative Works thereof, You may choose to offer,
166 and charge a fee for, acceptance of support, warranty, indemnity,
167 or other liability obligations and/or rights consistent with this
168 License. However, in accepting such obligations, You may act only
169 on Your own behalf and on Your sole responsibility, not on behalf
170 of any other Contributor, and only if You agree to indemnify,
171 defend, and hold each Contributor harmless for any liability
172 incurred by, or claims asserted against, such Contributor by reason
173 of your accepting any such warranty or additional liability.
174
175 END OF TERMS AND CONDITIONS
176
177 APPENDIX: How to apply the Apache License to your work.
178
179 To apply the Apache License to your work, attach the following
180 boilerplate notice, with the fields enclosed by brackets "{}"
181 replaced with your own identifying information. (Don't include
182 the brackets!) The text should be enclosed in the appropriate
183 comment syntax for the file format. We also recommend that a
184 file or class name and description of purpose be included on the
185 same "printed page" as the copyright notice for easier
186 identification within third-party archives.
187
188 Copyright {yyyy} {name of copyright owner}
189
190 Licensed under the Apache License, Version 2.0 (the "License");
191 you may not use this file except in compliance with the License.
192 You may obtain a copy of the License at
193
194 http://www.apache.org/licenses/LICENSE-2.0
195
196 Unless required by applicable law or agreed to in writing, software
197 distributed under the License is distributed on an "AS IS" BASIS,
198 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
199 See the License for the specific language governing permissions and
200 limitations under the License.
0 Copyright 2011-2016 Canonical Ltd.
1
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5
6 http://www.apache.org/licenses/LICENSE-2.0
7
8 Unless required by applicable law or agreed to in writing, software
9 distributed under the License is distributed on an "AS IS" BASIS,
10 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 See the License for the specific language governing permissions and
12 limitations under the License.
6464 d: [3, 4]
6565 `
6666
67 // Note: struct fields must be public in order for unmarshal to
68 // correctly populate the data.
6769 type T struct {
6870 A string
6971 B struct {
11
22 import (
33 "io"
4 "os"
54 )
65
76 func yaml_insert_token(parser *yaml_parser_t, pos int, token *yaml_token_t) {
4746 return n, nil
4847 }
4948
50 // File read handler.
51 func yaml_file_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
52 return parser.input_file.Read(buffer)
49 // Reader read handler.
50 func yaml_reader_read_handler(parser *yaml_parser_t, buffer []byte) (n int, err error) {
51 return parser.input_reader.Read(buffer)
5352 }
5453
5554 // Set a string input.
6362 }
6463
6564 // Set a file input.
66 func yaml_parser_set_input_file(parser *yaml_parser_t, file *os.File) {
65 func yaml_parser_set_input_reader(parser *yaml_parser_t, r io.Reader) {
6766 if parser.read_handler != nil {
6867 panic("must set the input source only once")
6968 }
70 parser.read_handler = yaml_file_read_handler
71 parser.input_file = file
69 parser.read_handler = yaml_reader_read_handler
70 parser.input_reader = r
7271 }
7372
7473 // Set the source encoding.
8079 }
8180
8281 // Create a new emitter object.
83 func yaml_emitter_initialize(emitter *yaml_emitter_t) bool {
82 func yaml_emitter_initialize(emitter *yaml_emitter_t) {
8483 *emitter = yaml_emitter_t{
8584 buffer: make([]byte, output_buffer_size),
8685 raw_buffer: make([]byte, 0, output_raw_buffer_size),
8786 states: make([]yaml_emitter_state_t, 0, initial_stack_size),
8887 events: make([]yaml_event_t, 0, initial_queue_size),
8988 }
90 return true
9189 }
9290
9391 // Destroy an emitter object.
10199 return nil
102100 }
103101
104 // File write handler.
105 func yaml_file_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
106 _, err := emitter.output_file.Write(buffer)
102 // yaml_writer_write_handler uses emitter.output_writer to write the
103 // emitted text.
104 func yaml_writer_write_handler(emitter *yaml_emitter_t, buffer []byte) error {
105 _, err := emitter.output_writer.Write(buffer)
107106 return err
108107 }
109108
117116 }
118117
119118 // Set a file output.
120 func yaml_emitter_set_output_file(emitter *yaml_emitter_t, file io.Writer) {
119 func yaml_emitter_set_output_writer(emitter *yaml_emitter_t, w io.Writer) {
121120 if emitter.write_handler != nil {
122121 panic("must set the output target only once")
123122 }
124 emitter.write_handler = yaml_file_write_handler
125 emitter.output_file = file
123 emitter.write_handler = yaml_writer_write_handler
124 emitter.output_writer = w
126125 }
127126
128127 // Set the output encoding.
251250 //
252251
253252 // Create STREAM-START.
254 func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) bool {
253 func yaml_stream_start_event_initialize(event *yaml_event_t, encoding yaml_encoding_t) {
255254 *event = yaml_event_t{
256255 typ: yaml_STREAM_START_EVENT,
257256 encoding: encoding,
258257 }
259 return true
260258 }
261259
262260 // Create STREAM-END.
263 func yaml_stream_end_event_initialize(event *yaml_event_t) bool {
261 func yaml_stream_end_event_initialize(event *yaml_event_t) {
264262 *event = yaml_event_t{
265263 typ: yaml_STREAM_END_EVENT,
266264 }
267 return true
268265 }
269266
270267 // Create DOCUMENT-START.
271 func yaml_document_start_event_initialize(event *yaml_event_t, version_directive *yaml_version_directive_t,
272 tag_directives []yaml_tag_directive_t, implicit bool) bool {
268 func yaml_document_start_event_initialize(
269 event *yaml_event_t,
270 version_directive *yaml_version_directive_t,
271 tag_directives []yaml_tag_directive_t,
272 implicit bool,
273 ) {
273274 *event = yaml_event_t{
274275 typ: yaml_DOCUMENT_START_EVENT,
275276 version_directive: version_directive,
276277 tag_directives: tag_directives,
277278 implicit: implicit,
278279 }
279 return true
280280 }
281281
282282 // Create DOCUMENT-END.
283 func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) bool {
283 func yaml_document_end_event_initialize(event *yaml_event_t, implicit bool) {
284284 *event = yaml_event_t{
285285 typ: yaml_DOCUMENT_END_EVENT,
286286 implicit: implicit,
287287 }
288 return true
289288 }
290289
291290 ///*
347346 }
348347
349348 // Create MAPPING-START.
350 func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) bool {
349 func yaml_mapping_start_event_initialize(event *yaml_event_t, anchor, tag []byte, implicit bool, style yaml_mapping_style_t) {
351350 *event = yaml_event_t{
352351 typ: yaml_MAPPING_START_EVENT,
353352 anchor: anchor,
355354 implicit: implicit,
356355 style: yaml_style_t(style),
357356 }
358 return true
359357 }
360358
361359 // Create MAPPING-END.
362 func yaml_mapping_end_event_initialize(event *yaml_event_t) bool {
360 func yaml_mapping_end_event_initialize(event *yaml_event_t) {
363361 *event = yaml_event_t{
364362 typ: yaml_MAPPING_END_EVENT,
365363 }
366 return true
367364 }
368365
369366 // Destroy an event object.
470467 // } context
471468 // tag_directive *yaml_tag_directive_t
472469 //
473 // context.error = YAML_NO_ERROR // Eliminate a compliler warning.
470 // context.error = YAML_NO_ERROR // Eliminate a compiler warning.
474471 //
475472 // assert(document) // Non-NULL document object is expected.
476473 //
33 "encoding"
44 "encoding/base64"
55 "fmt"
6 "io"
67 "math"
78 "reflect"
89 "strconv"
2122 kind int
2223 line, column int
2324 tag string
24 value string
25 implicit bool
26 children []*node
27 anchors map[string]*node
25 // For an alias node, alias holds the resolved alias.
26 alias *node
27 value string
28 implicit bool
29 children []*node
30 anchors map[string]*node
2831 }
2932
3033 // ----------------------------------------------------------------------------
3134 // Parser, produces a node tree out of a libyaml event stream.
3235
3336 type parser struct {
34 parser yaml_parser_t
35 event yaml_event_t
36 doc *node
37 parser yaml_parser_t
38 event yaml_event_t
39 doc *node
40 doneInit bool
3741 }
3842
3943 func newParser(b []byte) *parser {
4145 if !yaml_parser_initialize(&p.parser) {
4246 panic("failed to initialize YAML emitter")
4347 }
44
4548 if len(b) == 0 {
4649 b = []byte{'\n'}
4750 }
48
4951 yaml_parser_set_input_string(&p.parser, b)
50
51 p.skip()
52 if p.event.typ != yaml_STREAM_START_EVENT {
53 panic("expected stream start event, got " + strconv.Itoa(int(p.event.typ)))
54 }
55 p.skip()
5652 return &p
53 }
54
55 func newParserFromReader(r io.Reader) *parser {
56 p := parser{}
57 if !yaml_parser_initialize(&p.parser) {
58 panic("failed to initialize YAML emitter")
59 }
60 yaml_parser_set_input_reader(&p.parser, r)
61 return &p
62 }
63
64 func (p *parser) init() {
65 if p.doneInit {
66 return
67 }
68 p.expect(yaml_STREAM_START_EVENT)
69 p.doneInit = true
5770 }
5871
5972 func (p *parser) destroy() {
6376 yaml_parser_delete(&p.parser)
6477 }
6578
66 func (p *parser) skip() {
79 // expect consumes an event from the event stream and
80 // checks that it's of the expected type.
81 func (p *parser) expect(e yaml_event_type_t) {
82 if p.event.typ == yaml_NO_EVENT {
83 if !yaml_parser_parse(&p.parser, &p.event) {
84 p.fail()
85 }
86 }
87 if p.event.typ == yaml_STREAM_END_EVENT {
88 failf("attempted to go past the end of stream; corrupted value?")
89 }
90 if p.event.typ != e {
91 p.parser.problem = fmt.Sprintf("expected %s event but got %s", e, p.event.typ)
92 p.fail()
93 }
94 yaml_event_delete(&p.event)
95 p.event.typ = yaml_NO_EVENT
96 }
97
98 // peek peeks at the next event in the event stream,
99 // puts the results into p.event and returns the event type.
100 func (p *parser) peek() yaml_event_type_t {
67101 if p.event.typ != yaml_NO_EVENT {
68 if p.event.typ == yaml_STREAM_END_EVENT {
69 failf("attempted to go past the end of stream; corrupted value?")
70 }
71 yaml_event_delete(&p.event)
102 return p.event.typ
72103 }
73104 if !yaml_parser_parse(&p.parser, &p.event) {
74105 p.fail()
75106 }
107 return p.event.typ
76108 }
77109
78110 func (p *parser) fail() {
80112 var line int
81113 if p.parser.problem_mark.line != 0 {
82114 line = p.parser.problem_mark.line
115 // Scanner errors don't iterate line before returning error
116 if p.parser.error == yaml_SCANNER_ERROR {
117 line++
118 }
83119 } else if p.parser.context_mark.line != 0 {
84120 line = p.parser.context_mark.line
85121 }
102138 }
103139
104140 func (p *parser) parse() *node {
105 switch p.event.typ {
141 p.init()
142 switch p.peek() {
106143 case yaml_SCALAR_EVENT:
107144 return p.scalar()
108145 case yaml_ALIAS_EVENT:
117154 // Happens when attempting to decode an empty buffer.
118155 return nil
119156 default:
120 panic("attempted to parse unknown event: " + strconv.Itoa(int(p.event.typ)))
157 panic("attempted to parse unknown event: " + p.event.typ.String())
121158 }
122159 }
123160
133170 n := p.node(documentNode)
134171 n.anchors = make(map[string]*node)
135172 p.doc = n
136 p.skip()
173 p.expect(yaml_DOCUMENT_START_EVENT)
137174 n.children = append(n.children, p.parse())
138 if p.event.typ != yaml_DOCUMENT_END_EVENT {
139 panic("expected end of document event but got " + strconv.Itoa(int(p.event.typ)))
140 }
141 p.skip()
175 p.expect(yaml_DOCUMENT_END_EVENT)
142176 return n
143177 }
144178
145179 func (p *parser) alias() *node {
146180 n := p.node(aliasNode)
147181 n.value = string(p.event.anchor)
148 p.skip()
182 n.alias = p.doc.anchors[n.value]
183 if n.alias == nil {
184 failf("unknown anchor '%s' referenced", n.value)
185 }
186 p.expect(yaml_ALIAS_EVENT)
149187 return n
150188 }
151189
155193 n.tag = string(p.event.tag)
156194 n.implicit = p.event.implicit
157195 p.anchor(n, p.event.anchor)
158 p.skip()
196 p.expect(yaml_SCALAR_EVENT)
159197 return n
160198 }
161199
162200 func (p *parser) sequence() *node {
163201 n := p.node(sequenceNode)
164202 p.anchor(n, p.event.anchor)
165 p.skip()
166 for p.event.typ != yaml_SEQUENCE_END_EVENT {
203 p.expect(yaml_SEQUENCE_START_EVENT)
204 for p.peek() != yaml_SEQUENCE_END_EVENT {
167205 n.children = append(n.children, p.parse())
168206 }
169 p.skip()
207 p.expect(yaml_SEQUENCE_END_EVENT)
170208 return n
171209 }
172210
173211 func (p *parser) mapping() *node {
174212 n := p.node(mappingNode)
175213 p.anchor(n, p.event.anchor)
176 p.skip()
177 for p.event.typ != yaml_MAPPING_END_EVENT {
214 p.expect(yaml_MAPPING_START_EVENT)
215 for p.peek() != yaml_MAPPING_END_EVENT {
178216 n.children = append(n.children, p.parse(), p.parse())
179217 }
180 p.skip()
218 p.expect(yaml_MAPPING_END_EVENT)
181219 return n
182220 }
183221
186224
187225 type decoder struct {
188226 doc *node
189 aliases map[string]bool
227 aliases map[*node]bool
190228 mapType reflect.Type
191229 terrors []string
230 strict bool
192231 }
193232
194233 var (
196235 durationType = reflect.TypeOf(time.Duration(0))
197236 defaultMapType = reflect.TypeOf(map[interface{}]interface{}{})
198237 ifaceType = defaultMapType.Elem()
238 timeType = reflect.TypeOf(time.Time{})
239 ptrTimeType = reflect.TypeOf(&time.Time{})
199240 )
200241
201 func newDecoder() *decoder {
202 d := &decoder{mapType: defaultMapType}
203 d.aliases = make(map[string]bool)
242 func newDecoder(strict bool) *decoder {
243 d := &decoder{mapType: defaultMapType, strict: strict}
244 d.aliases = make(map[*node]bool)
204245 return d
205246 }
206247
249290 //
250291 // If n holds a null value, prepare returns before doing anything.
251292 func (d *decoder) prepare(n *node, out reflect.Value) (newout reflect.Value, unmarshaled, good bool) {
252 if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "" && n.implicit) {
293 if n.tag == yaml_NULL_TAG || n.kind == scalarNode && n.tag == "" && (n.value == "null" || n.value == "~" || n.value == "" && n.implicit) {
253294 return out, false, false
254295 }
255296 again := true
306347 }
307348
308349 func (d *decoder) alias(n *node, out reflect.Value) (good bool) {
309 an, ok := d.doc.anchors[n.value]
310 if !ok {
311 failf("unknown anchor '%s' referenced", n.value)
312 }
313 if d.aliases[n.value] {
350 if d.aliases[n] {
351 // TODO this could actually be allowed in some circumstances.
314352 failf("anchor '%s' value contains itself", n.value)
315353 }
316 d.aliases[n.value] = true
317 good = d.unmarshal(an, out)
318 delete(d.aliases, n.value)
354 d.aliases[n] = true
355 good = d.unmarshal(n.alias, out)
356 delete(d.aliases, n)
319357 return good
320358 }
321359
327365 }
328366 }
329367
330 func (d *decoder) scalar(n *node, out reflect.Value) (good bool) {
368 func (d *decoder) scalar(n *node, out reflect.Value) bool {
331369 var tag string
332370 var resolved interface{}
333371 if n.tag == "" && !n.implicit {
351389 }
352390 return true
353391 }
354 if s, ok := resolved.(string); ok && out.CanAddr() {
355 if u, ok := out.Addr().Interface().(encoding.TextUnmarshaler); ok {
356 err := u.UnmarshalText([]byte(s))
392 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
393 // We've resolved to exactly the type we want, so use that.
394 out.Set(resolvedv)
395 return true
396 }
397 // Perhaps we can use the value as a TextUnmarshaler to
398 // set its value.
399 if out.CanAddr() {
400 u, ok := out.Addr().Interface().(encoding.TextUnmarshaler)
401 if ok {
402 var text []byte
403 if tag == yaml_BINARY_TAG {
404 text = []byte(resolved.(string))
405 } else {
406 // We let any value be unmarshaled into TextUnmarshaler.
407 // That might be more lax than we'd like, but the
408 // TextUnmarshaler itself should bowl out any dubious values.
409 text = []byte(n.value)
410 }
411 err := u.UnmarshalText(text)
357412 if err != nil {
358413 fail(err)
359414 }
364419 case reflect.String:
365420 if tag == yaml_BINARY_TAG {
366421 out.SetString(resolved.(string))
367 good = true
368 } else if resolved != nil {
422 return true
423 }
424 if resolved != nil {
369425 out.SetString(n.value)
370 good = true
426 return true
371427 }
372428 case reflect.Interface:
373429 if resolved == nil {
374430 out.Set(reflect.Zero(out.Type()))
431 } else if tag == yaml_TIMESTAMP_TAG {
432 // It looks like a timestamp but for backward compatibility
433 // reasons we set it as a string, so that code that unmarshals
434 // timestamp-like values into interface{} will continue to
435 // see a string and not a time.Time.
436 // TODO(v3) Drop this.
437 out.Set(reflect.ValueOf(n.value))
375438 } else {
376439 out.Set(reflect.ValueOf(resolved))
377440 }
378 good = true
441 return true
379442 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
380443 switch resolved := resolved.(type) {
381444 case int:
382445 if !out.OverflowInt(int64(resolved)) {
383446 out.SetInt(int64(resolved))
384 good = true
447 return true
385448 }
386449 case int64:
387450 if !out.OverflowInt(resolved) {
388451 out.SetInt(resolved)
389 good = true
452 return true
390453 }
391454 case uint64:
392455 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
393456 out.SetInt(int64(resolved))
394 good = true
457 return true
395458 }
396459 case float64:
397460 if resolved <= math.MaxInt64 && !out.OverflowInt(int64(resolved)) {
398461 out.SetInt(int64(resolved))
399 good = true
462 return true
400463 }
401464 case string:
402465 if out.Type() == durationType {
403466 d, err := time.ParseDuration(resolved)
404467 if err == nil {
405468 out.SetInt(int64(d))
406 good = true
469 return true
407470 }
408471 }
409472 }
412475 case int:
413476 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
414477 out.SetUint(uint64(resolved))
415 good = true
478 return true
416479 }
417480 case int64:
418481 if resolved >= 0 && !out.OverflowUint(uint64(resolved)) {
419482 out.SetUint(uint64(resolved))
420 good = true
483 return true
421484 }
422485 case uint64:
423486 if !out.OverflowUint(uint64(resolved)) {
424487 out.SetUint(uint64(resolved))
425 good = true
488 return true
426489 }
427490 case float64:
428491 if resolved <= math.MaxUint64 && !out.OverflowUint(uint64(resolved)) {
429492 out.SetUint(uint64(resolved))
430 good = true
493 return true
431494 }
432495 }
433496 case reflect.Bool:
434497 switch resolved := resolved.(type) {
435498 case bool:
436499 out.SetBool(resolved)
437 good = true
500 return true
438501 }
439502 case reflect.Float32, reflect.Float64:
440503 switch resolved := resolved.(type) {
441504 case int:
442505 out.SetFloat(float64(resolved))
443 good = true
506 return true
444507 case int64:
445508 out.SetFloat(float64(resolved))
446 good = true
509 return true
447510 case uint64:
448511 out.SetFloat(float64(resolved))
449 good = true
512 return true
450513 case float64:
451514 out.SetFloat(resolved)
452 good = true
515 return true
516 }
517 case reflect.Struct:
518 if resolvedv := reflect.ValueOf(resolved); out.Type() == resolvedv.Type() {
519 out.Set(resolvedv)
520 return true
453521 }
454522 case reflect.Ptr:
455523 if out.Type().Elem() == reflect.TypeOf(resolved) {
457525 elem := reflect.New(out.Type().Elem())
458526 elem.Elem().Set(reflect.ValueOf(resolved))
459527 out.Set(elem)
460 good = true
461 }
462 }
463 if !good {
464 d.terror(n, tag, out)
465 }
466 return good
528 return true
529 }
530 }
531 d.terror(n, tag, out)
532 return false
467533 }
468534
469535 func settableValueOf(i interface{}) reflect.Value {
480546 switch out.Kind() {
481547 case reflect.Slice:
482548 out.Set(reflect.MakeSlice(out.Type(), l, l))
549 case reflect.Array:
550 if l != out.Len() {
551 failf("invalid array: want %d elements but got %d", out.Len(), l)
552 }
483553 case reflect.Interface:
484554 // No type hints. Will have to use a generic sequence.
485555 iface = out
498568 j++
499569 }
500570 }
501 out.Set(out.Slice(0, j))
571 if out.Kind() != reflect.Array {
572 out.Set(out.Slice(0, j))
573 }
502574 if iface.IsValid() {
503575 iface.Set(out)
504576 }
559631 }
560632 e := reflect.New(et).Elem()
561633 if d.unmarshal(n.children[i+1], e) {
562 out.SetMapIndex(k, e)
634 d.setMapIndex(n.children[i+1], out, k, e)
563635 }
564636 }
565637 }
566638 d.mapType = mapType
567639 return true
640 }
641
642 func (d *decoder) setMapIndex(n *node, out, k, v reflect.Value) {
643 if d.strict && out.MapIndex(k) != zeroValue {
644 d.terrors = append(d.terrors, fmt.Sprintf("line %d: key %#v already set in map", n.line+1, k.Interface()))
645 return
646 }
647 out.SetMapIndex(k, v)
568648 }
569649
570650 func (d *decoder) mappingSlice(n *node, out reflect.Value) (good bool) {
614694 elemType = inlineMap.Type().Elem()
615695 }
616696
697 var doneFields []bool
698 if d.strict {
699 doneFields = make([]bool, len(sinfo.FieldsList))
700 }
617701 for i := 0; i < l; i += 2 {
618702 ni := n.children[i]
619703 if isMerge(ni) {
624708 continue
625709 }
626710 if info, ok := sinfo.FieldsMap[name.String()]; ok {
711 if d.strict {
712 if doneFields[info.Id] {
713 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s already set in type %s", ni.line+1, name.String(), out.Type()))
714 continue
715 }
716 doneFields[info.Id] = true
717 }
627718 var field reflect.Value
628719 if info.Inline == nil {
629720 field = out.Field(info.Num)
637728 }
638729 value := reflect.New(elemType).Elem()
639730 d.unmarshal(n.children[i+1], value)
640 inlineMap.SetMapIndex(name, value)
731 d.setMapIndex(n.children[i+1], inlineMap, name, value)
732 } else if d.strict {
733 d.terrors = append(d.terrors, fmt.Sprintf("line %d: field %s not found in type %s", ni.line+1, name.String(), out.Type()))
641734 }
642735 }
643736 return true
11
22 import (
33 "errors"
4 . "gopkg.in/check.v1"
5 "gopkg.in/yaml.v2"
4 "io"
65 "math"
7 "net"
86 "reflect"
97 "strings"
108 "time"
9
10 . "gopkg.in/check.v1"
11 "gopkg.in/yaml.v2"
1112 )
1213
1314 var unmarshalIntTest = 123
1819 }{
1920 {
2021 "",
21 &struct{}{},
22 }, {
22 (*struct{})(nil),
23 },
24 {
2325 "{}", &struct{}{},
2426 }, {
2527 "v: hi",
127129 "bin: -0b101010",
128130 map[string]interface{}{"bin": -42},
129131 }, {
132 "bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
133 map[string]interface{}{"bin": -9223372036854775808},
134 }, {
130135 "decimal: +685_230",
131136 map[string]int{"decimal": 685230},
132137 },
238243 }, {
239244 "a: [1, 2]",
240245 &struct{ A []int }{[]int{1, 2}},
246 }, {
247 "a: [1, 2]",
248 &struct{ A [2]int }{[2]int{1, 2}},
241249 }, {
242250 "a: 1",
243251 &struct{ B int }{0},
397405 "v: !!float '1.1'",
398406 map[string]interface{}{"v": 1.1},
399407 }, {
408 "v: !!float 0",
409 map[string]interface{}{"v": float64(0)},
410 }, {
411 "v: !!float -1",
412 map[string]interface{}{"v": float64(-1)},
413 }, {
400414 "v: !!null ''",
401415 map[string]interface{}{"v": nil},
402416 }, {
403417 "%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
404418 map[string]interface{}{"v": 1},
419 },
420
421 // Non-specific tag (Issue #75)
422 {
423 "v: ! test",
424 map[string]interface{}{"v": "test"},
405425 },
406426
407427 // Anchors and aliases.
418438 }, {
419439 "a: &a [1, 2]\nb: *a",
420440 &struct{ B []int }{[]int{1, 2}},
421 }, {
422 "b: *a\na: &a {c: 1}",
423 &struct {
424 A, B struct {
425 C int
426 }
427 }{struct{ C int }{1}, struct{ C int }{1}},
428441 },
429442
430443 // Bug #1133337
433446 map[string]*string{"foo": new(string)},
434447 }, {
435448 "foo: null",
449 map[string]*string{"foo": nil},
450 }, {
451 "foo: null",
436452 map[string]string{"foo": ""},
437453 }, {
438454 "foo: null",
455 map[string]interface{}{"foo": nil},
456 },
457
458 // Support for ~
459 {
460 "foo: ~",
461 map[string]*string{"foo": nil},
462 }, {
463 "foo: ~",
464 map[string]string{"foo": ""},
465 }, {
466 "foo: ~",
439467 map[string]interface{}{"foo": nil},
440468 },
441469
495523 map[string]interface{}{"a": "50cent_of_dollar"},
496524 },
497525
526 // issue #295 (allow scalars with colons in flow mappings and sequences)
527 {
528 "a: {b: https://github.com/go-yaml/yaml}",
529 map[string]interface{}{"a": map[interface{}]interface{}{
530 "b": "https://github.com/go-yaml/yaml",
531 }},
532 },
533 {
534 "a: [https://github.com/go-yaml/yaml]",
535 map[string]interface{}{"a": []interface{}{"https://github.com/go-yaml/yaml"}},
536 },
537
498538 // Duration
499539 {
500540 "a: 3s",
546586 // Support encoding.TextUnmarshaler.
547587 {
548588 "a: 1.2.3.4\n",
549 map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
589 map[string]textUnmarshaler{"a": textUnmarshaler{S: "1.2.3.4"}},
550590 },
551591 {
552592 "a: 2015-02-24T18:19:39Z\n",
553 map[string]time.Time{"a": time.Unix(1424801979, 0).In(time.UTC)},
593 map[string]textUnmarshaler{"a": textUnmarshaler{"2015-02-24T18:19:39Z"}},
594 },
595
596 // Timestamps
597 {
598 // Date only.
599 "a: 2015-01-01\n",
600 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
601 },
602 {
603 // RFC3339
604 "a: 2015-02-24T18:19:39.12Z\n",
605 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, .12e9, time.UTC)},
606 },
607 {
608 // RFC3339 with short dates.
609 "a: 2015-2-3T3:4:5Z",
610 map[string]time.Time{"a": time.Date(2015, 2, 3, 3, 4, 5, 0, time.UTC)},
611 },
612 {
613 // ISO8601 lower case t
614 "a: 2015-02-24t18:19:39Z\n",
615 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
616 },
617 {
618 // space separate, no time zone
619 "a: 2015-02-24 18:19:39\n",
620 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
621 },
622 // Some cases not currently handled. Uncomment these when
623 // the code is fixed.
624 // {
625 // // space separated with time zone
626 // "a: 2001-12-14 21:59:43.10 -5",
627 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
628 // },
629 // {
630 // // arbitrary whitespace between fields
631 // "a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
632 // map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
633 // },
634 {
635 // explicit string tag
636 "a: !!str 2015-01-01",
637 map[string]interface{}{"a": "2015-01-01"},
638 },
639 {
640 // explicit timestamp tag on quoted string
641 "a: !!timestamp \"2015-01-01\"",
642 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
643 },
644 {
645 // explicit timestamp tag on unquoted string
646 "a: !!timestamp 2015-01-01",
647 map[string]time.Time{"a": time.Date(2015, 1, 1, 0, 0, 0, 0, time.UTC)},
648 },
649 {
650 // quoted string that's a valid timestamp
651 "a: \"2015-01-01\"",
652 map[string]interface{}{"a": "2015-01-01"},
653 },
654 {
655 // explicit timestamp tag into interface.
656 "a: !!timestamp \"2015-01-01\"",
657 map[string]interface{}{"a": "2015-01-01"},
658 },
659 {
660 // implicit timestamp tag into interface.
661 "a: 2015-01-01",
662 map[string]interface{}{"a": "2015-01-01"},
554663 },
555664
556665 // Encode empty lists as zero-length slices.
588697 }, {
589698 "a: 123456E1\n",
590699 M{"a": "123456E1"},
700 },
701 // yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
702 {
703 "First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
704 map[interface{}]interface{}{
705 "Reuse anchor": "Bar",
706 "First occurrence": "Foo",
707 "Second occurrence": "Foo",
708 "Override anchor": "Bar",
709 },
710 },
711 // Single document with garbage following it.
712 {
713 "---\nhello\n...\n}not yaml",
714 "hello",
591715 },
592716 }
593717
603727 }
604728
605729 func (s *S) TestUnmarshal(c *C) {
606 for _, item := range unmarshalTests {
730 for i, item := range unmarshalTests {
731 c.Logf("test %d: %q", i, item.data)
607732 t := reflect.ValueOf(item.value).Type()
608 var value interface{}
609 switch t.Kind() {
610 case reflect.Map:
611 value = reflect.MakeMap(t).Interface()
612 case reflect.String:
613 value = reflect.New(t).Interface()
614 case reflect.Ptr:
615 value = reflect.New(t.Elem()).Interface()
616 default:
617 c.Fatalf("missing case for %s", t)
618 }
619 err := yaml.Unmarshal([]byte(item.data), value)
733 value := reflect.New(t)
734 err := yaml.Unmarshal([]byte(item.data), value.Interface())
620735 if _, ok := err.(*yaml.TypeError); !ok {
621736 c.Assert(err, IsNil)
622737 }
623 if t.Kind() == reflect.String {
624 c.Assert(*value.(*string), Equals, item.value)
625 } else {
626 c.Assert(value, DeepEquals, item.value)
738 c.Assert(value.Elem().Interface(), DeepEquals, item.value, Commentf("error: %v", err))
739 }
740 }
741
742 // TODO(v3): This test should also work when unmarshaling onto an interface{}.
743 func (s *S) TestUnmarshalFullTimestamp(c *C) {
744 // Full timestamp in same format as encoded. This is confirmed to be
745 // properly decoded by Python as a timestamp as well.
746 var str = "2015-02-24T18:19:39.123456789-03:00"
747 var t time.Time
748 err := yaml.Unmarshal([]byte(str), &t)
749 c.Assert(err, IsNil)
750 c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location()))
751 c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
752 }
753
754 func (s *S) TestDecoderSingleDocument(c *C) {
755 // Test that Decoder.Decode works as expected on
756 // all the unmarshal tests.
757 for i, item := range unmarshalTests {
758 c.Logf("test %d: %q", i, item.data)
759 if item.data == "" {
760 // Behaviour differs when there's no YAML.
761 continue
627762 }
628 }
763 t := reflect.ValueOf(item.value).Type()
764 value := reflect.New(t)
765 err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(value.Interface())
766 if _, ok := err.(*yaml.TypeError); !ok {
767 c.Assert(err, IsNil)
768 }
769 c.Assert(value.Elem().Interface(), DeepEquals, item.value)
770 }
771 }
772
773 var decoderTests = []struct {
774 data string
775 values []interface{}
776 }{{
777 "",
778 nil,
779 }, {
780 "a: b",
781 []interface{}{
782 map[interface{}]interface{}{"a": "b"},
783 },
784 }, {
785 "---\na: b\n...\n",
786 []interface{}{
787 map[interface{}]interface{}{"a": "b"},
788 },
789 }, {
790 "---\n'hello'\n...\n---\ngoodbye\n...\n",
791 []interface{}{
792 "hello",
793 "goodbye",
794 },
795 }}
796
797 func (s *S) TestDecoder(c *C) {
798 for i, item := range decoderTests {
799 c.Logf("test %d: %q", i, item.data)
800 var values []interface{}
801 dec := yaml.NewDecoder(strings.NewReader(item.data))
802 for {
803 var value interface{}
804 err := dec.Decode(&value)
805 if err == io.EOF {
806 break
807 }
808 c.Assert(err, IsNil)
809 values = append(values, value)
810 }
811 c.Assert(values, DeepEquals, item.values)
812 }
813 }
814
815 type errReader struct{}
816
817 func (errReader) Read([]byte) (int, error) {
818 return 0, errors.New("some read error")
819 }
820
821 func (s *S) TestDecoderReadError(c *C) {
822 err := yaml.NewDecoder(errReader{}).Decode(&struct{}{})
823 c.Assert(err, ErrorMatches, `yaml: input error: some read error`)
629824 }
630825
631826 func (s *S) TestUnmarshalNaN(c *C) {
641836 {"v: !!float 'error'", "yaml: cannot decode !!str `error` as a !!float"},
642837 {"v: [A,", "yaml: line 1: did not find expected node content"},
643838 {"v:\n- [A,", "yaml: line 2: did not find expected node content"},
839 {"a:\n- b: *,", "yaml: line 2: did not find expected alphabetic or numeric character"},
644840 {"a: *b\n", "yaml: unknown anchor 'b' referenced"},
645841 {"a: &a\n b: *a\n", "yaml: anchor 'a' value contains itself"},
646842 {"value: -", "yaml: block sequence entries are not allowed in this context"},
647843 {"a: !!binary ==", "yaml: !!binary value contains invalid base64 data"},
648844 {"{[.]}", `yaml: invalid map key: \[\]interface \{\}\{"\."\}`},
649845 {"{{.}}", `yaml: invalid map key: map\[interface\ \{\}\]interface \{\}\{".":interface \{\}\(nil\)\}`},
846 {"b: *a\na: &a {c: 1}", `yaml: unknown anchor 'a' referenced`},
847 {"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "yaml: did not find expected whitespace"},
650848 }
651849
652850 func (s *S) TestUnmarshalErrors(c *C) {
851 for i, item := range unmarshalErrorTests {
852 c.Logf("test %d: %q", i, item.data)
853 var value interface{}
854 err := yaml.Unmarshal([]byte(item.data), &value)
855 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
856 }
857 }
858
859 func (s *S) TestDecoderErrors(c *C) {
653860 for _, item := range unmarshalErrorTests {
654861 var value interface{}
655 err := yaml.Unmarshal([]byte(item.data), &value)
862 err := yaml.NewDecoder(strings.NewReader(item.data)).Decode(&value)
656863 c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
657864 }
658865 }
9651172 v := struct{ A []int }{[]int{1}}
9661173 yaml.Unmarshal([]byte("a: [2]"), &v)
9671174 c.Assert(v.A, DeepEquals, []int{2})
1175 }
1176
1177 var unmarshalStrictTests = []struct {
1178 data string
1179 value interface{}
1180 error string
1181 }{{
1182 data: "a: 1\nc: 2\n",
1183 value: struct{ A, B int }{A: 1},
1184 error: `yaml: unmarshal errors:\n line 2: field c not found in type struct { A int; B int }`,
1185 }, {
1186 data: "a: 1\nb: 2\na: 3\n",
1187 value: struct{ A, B int }{A: 3, B: 2},
1188 error: `yaml: unmarshal errors:\n line 3: field a already set in type struct { A int; B int }`,
1189 }, {
1190 data: "c: 3\na: 1\nb: 2\nc: 4\n",
1191 value: struct {
1192 A int
1193 inlineB `yaml:",inline"`
1194 }{
1195 A: 1,
1196 inlineB: inlineB{
1197 B: 2,
1198 inlineC: inlineC{
1199 C: 4,
1200 },
1201 },
1202 },
1203 error: `yaml: unmarshal errors:\n line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
1204 }, {
1205 data: "c: 0\na: 1\nb: 2\nc: 1\n",
1206 value: struct {
1207 A int
1208 inlineB `yaml:",inline"`
1209 }{
1210 A: 1,
1211 inlineB: inlineB{
1212 B: 2,
1213 inlineC: inlineC{
1214 C: 1,
1215 },
1216 },
1217 },
1218 error: `yaml: unmarshal errors:\n line 4: field c already set in type struct { A int; yaml_test.inlineB "yaml:\\",inline\\"" }`,
1219 }, {
1220 data: "c: 1\na: 1\nb: 2\nc: 3\n",
1221 value: struct {
1222 A int
1223 M map[string]interface{} `yaml:",inline"`
1224 }{
1225 A: 1,
1226 M: map[string]interface{}{
1227 "b": 2,
1228 "c": 3,
1229 },
1230 },
1231 error: `yaml: unmarshal errors:\n line 4: key "c" already set in map`,
1232 }, {
1233 data: "a: 1\n9: 2\nnull: 3\n9: 4",
1234 value: map[interface{}]interface{}{
1235 "a": 1,
1236 nil: 3,
1237 9: 4,
1238 },
1239 error: `yaml: unmarshal errors:\n line 4: key 9 already set in map`,
1240 }}
1241
1242 func (s *S) TestUnmarshalStrict(c *C) {
1243 for i, item := range unmarshalStrictTests {
1244 c.Logf("test %d: %q", i, item.data)
1245 // First test that normal Unmarshal unmarshals to the expected value.
1246 t := reflect.ValueOf(item.value).Type()
1247 value := reflect.New(t)
1248 err := yaml.Unmarshal([]byte(item.data), value.Interface())
1249 c.Assert(err, Equals, nil)
1250 c.Assert(value.Elem().Interface(), DeepEquals, item.value)
1251
1252 // Then test that UnmarshalStrict fails on the same thing.
1253 t = reflect.ValueOf(item.value).Type()
1254 value = reflect.New(t)
1255 err = yaml.UnmarshalStrict([]byte(item.data), value.Interface())
1256 c.Assert(err, ErrorMatches, item.error)
1257 }
1258 }
1259
1260 type textUnmarshaler struct {
1261 S string
1262 }
1263
1264 func (t *textUnmarshaler) UnmarshalText(s []byte) error {
1265 t.S = string(s)
1266 return nil
1267 }
1268
1269 func (s *S) TestFuzzCrashers(c *C) {
1270 cases := []string{
1271 // runtime error: index out of range
1272 "\"\\0\\\r\n",
1273
1274 // should not happen
1275 " 0: [\n] 0",
1276 "? ? \"\n\" 0",
1277 " - {\n000}0",
1278 "0:\n 0: [0\n] 0",
1279 " - \"\n000\"0",
1280 " - \"\n000\"\"",
1281 "0:\n - {\n000}0",
1282 "0:\n - \"\n000\"0",
1283 "0:\n - \"\n000\"\"",
1284
1285 // runtime error: index out of range
1286 " \ufeff\n",
1287 "? \ufeff\n",
1288 "? \ufeff:\n",
1289 "0: \ufeff\n",
1290 "? \ufeff: \ufeff\n",
1291 }
1292 for _, data := range cases {
1293 var v interface{}
1294 _ = yaml.Unmarshal([]byte(data), &v)
1295 }
9681296 }
9691297
9701298 //var data []byte
11
22 import (
33 "bytes"
4 "fmt"
45 )
56
67 // Flush the buffer if needed.
663664 return yaml_emitter_emit_mapping_start(emitter, event)
664665 default:
665666 return yaml_emitter_set_emitter_error(emitter,
666 "expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS")
667 fmt.Sprintf("expected SCALAR, SEQUENCE-START, MAPPING-START, or ALIAS, but got %v", event.typ))
667668 }
668669 }
669670
841842 return true
842843 }
843844
844 // Write an achor.
845 // Write an anchor.
845846 func yaml_emitter_process_anchor(emitter *yaml_emitter_t) bool {
846847 if emitter.anchor_data.anchor == nil {
847848 return true
993994 break_space = false
994995 space_break = false
995996
996 preceeded_by_whitespace = false
997 followed_by_whitespace = false
998 previous_space = false
999 previous_break = false
997 preceded_by_whitespace = false
998 followed_by_whitespace = false
999 previous_space = false
1000 previous_break = false
10001001 )
10011002
10021003 emitter.scalar_data.value = value
10151016 flow_indicators = true
10161017 }
10171018
1018 preceeded_by_whitespace = true
1019 preceded_by_whitespace = true
10191020 for i, w := 0, 0; i < len(value); i += w {
10201021 w = width(value[i])
10211022 followed_by_whitespace = i+w >= len(value) || is_blank(value, i+w)
10461047 block_indicators = true
10471048 }
10481049 case '#':
1049 if preceeded_by_whitespace {
1050 if preceded_by_whitespace {
10501051 flow_indicators = true
10511052 block_indicators = true
10521053 }
10871088 }
10881089
10891090 // [Go]: Why 'z'? Couldn't be the end of the string as that's the loop condition.
1090 preceeded_by_whitespace = is_blankz(value, i)
1091 preceded_by_whitespace = is_blankz(value, i)
10911092 }
10921093
10931094 emitter.scalar_data.multiline = line_breaks
22 import (
33 "encoding"
44 "fmt"
5 "io"
56 "reflect"
67 "regexp"
78 "sort"
89 "strconv"
910 "strings"
1011 "time"
12 "unicode/utf8"
1113 )
1214
1315 type encoder struct {
1517 event yaml_event_t
1618 out []byte
1719 flow bool
18 }
19
20 func newEncoder() (e *encoder) {
21 e = &encoder{}
22 e.must(yaml_emitter_initialize(&e.emitter))
20 // doneInit holds whether the initial stream_start_event has been
21 // emitted.
22 doneInit bool
23 }
24
25 func newEncoder() *encoder {
26 e := &encoder{}
27 yaml_emitter_initialize(&e.emitter)
2328 yaml_emitter_set_output_string(&e.emitter, &e.out)
2429 yaml_emitter_set_unicode(&e.emitter, true)
25 e.must(yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING))
26 e.emit()
27 e.must(yaml_document_start_event_initialize(&e.event, nil, nil, true))
28 e.emit()
2930 return e
3031 }
3132
33 func newEncoderWithWriter(w io.Writer) *encoder {
34 e := &encoder{}
35 yaml_emitter_initialize(&e.emitter)
36 yaml_emitter_set_output_writer(&e.emitter, w)
37 yaml_emitter_set_unicode(&e.emitter, true)
38 return e
39 }
40
41 func (e *encoder) init() {
42 if e.doneInit {
43 return
44 }
45 yaml_stream_start_event_initialize(&e.event, yaml_UTF8_ENCODING)
46 e.emit()
47 e.doneInit = true
48 }
49
3250 func (e *encoder) finish() {
33 e.must(yaml_document_end_event_initialize(&e.event, true))
34 e.emit()
3551 e.emitter.open_ended = false
36 e.must(yaml_stream_end_event_initialize(&e.event))
52 yaml_stream_end_event_initialize(&e.event)
3753 e.emit()
3854 }
3955
4359
4460 func (e *encoder) emit() {
4561 // This will internally delete the e.event value.
46 if !yaml_emitter_emit(&e.emitter, &e.event) && e.event.typ != yaml_DOCUMENT_END_EVENT && e.event.typ != yaml_STREAM_END_EVENT {
47 e.must(false)
48 }
62 e.must(yaml_emitter_emit(&e.emitter, &e.event))
4963 }
5064
5165 func (e *encoder) must(ok bool) {
5872 }
5973 }
6074
75 func (e *encoder) marshalDoc(tag string, in reflect.Value) {
76 e.init()
77 yaml_document_start_event_initialize(&e.event, nil, nil, true)
78 e.emit()
79 e.marshal(tag, in)
80 yaml_document_end_event_initialize(&e.event, true)
81 e.emit()
82 }
83
6184 func (e *encoder) marshal(tag string, in reflect.Value) {
62 if !in.IsValid() {
85 if !in.IsValid() || in.Kind() == reflect.Ptr && in.IsNil() {
6386 e.nilv()
6487 return
6588 }
6689 iface := in.Interface()
67 if m, ok := iface.(Marshaler); ok {
90 switch m := iface.(type) {
91 case time.Time, *time.Time:
92 // Although time.Time implements TextMarshaler,
93 // we don't want to treat it as a string for YAML
94 // purposes because YAML has special support for
95 // timestamps.
96 case Marshaler:
6897 v, err := m.MarshalYAML()
6998 if err != nil {
7099 fail(err)
74103 return
75104 }
76105 in = reflect.ValueOf(v)
77 } else if m, ok := iface.(encoding.TextMarshaler); ok {
106 case encoding.TextMarshaler:
78107 text, err := m.MarshalText()
79108 if err != nil {
80109 fail(err)
81110 }
82111 in = reflect.ValueOf(string(text))
112 case nil:
113 e.nilv()
114 return
83115 }
84116 switch in.Kind() {
85117 case reflect.Interface:
86 if in.IsNil() {
87 e.nilv()
88 } else {
89 e.marshal(tag, in.Elem())
90 }
118 e.marshal(tag, in.Elem())
91119 case reflect.Map:
92120 e.mapv(tag, in)
93121 case reflect.Ptr:
94 if in.IsNil() {
95 e.nilv()
122 if in.Type() == ptrTimeType {
123 e.timev(tag, in.Elem())
96124 } else {
97125 e.marshal(tag, in.Elem())
98126 }
99127 case reflect.Struct:
100 e.structv(tag, in)
101 case reflect.Slice:
128 if in.Type() == timeType {
129 e.timev(tag, in)
130 } else {
131 e.structv(tag, in)
132 }
133 case reflect.Slice, reflect.Array:
102134 if in.Type().Elem() == mapItemType {
103135 e.itemsv(tag, in)
104136 } else {
190222 e.flow = false
191223 style = yaml_FLOW_MAPPING_STYLE
192224 }
193 e.must(yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style))
225 yaml_mapping_start_event_initialize(&e.event, nil, []byte(tag), implicit, style)
194226 e.emit()
195227 f()
196 e.must(yaml_mapping_end_event_initialize(&e.event))
228 yaml_mapping_end_event_initialize(&e.event)
197229 e.emit()
198230 }
199231
239271 func (e *encoder) stringv(tag string, in reflect.Value) {
240272 var style yaml_scalar_style_t
241273 s := in.String()
242 rtag, rs := resolve("", s)
243 if rtag == yaml_BINARY_TAG {
244 if tag == "" || tag == yaml_STR_TAG {
245 tag = rtag
246 s = rs.(string)
247 } else if tag == yaml_BINARY_TAG {
274 canUsePlain := true
275 switch {
276 case !utf8.ValidString(s):
277 if tag == yaml_BINARY_TAG {
248278 failf("explicitly tagged !!binary data must be base64-encoded")
249 } else {
279 }
280 if tag != "" {
250281 failf("cannot marshal invalid UTF-8 data as %s", shortTag(tag))
251282 }
252 }
253 if tag == "" && (rtag != yaml_STR_TAG || isBase60Float(s)) {
283 // It can't be encoded directly as YAML so use a binary tag
284 // and encode it as base64.
285 tag = yaml_BINARY_TAG
286 s = encodeBase64(s)
287 case tag == "":
288 // Check to see if it would resolve to a specific
289 // tag when encoded unquoted. If it doesn't,
290 // there's no need to quote it.
291 rtag, _ := resolve("", s)
292 canUsePlain = rtag == yaml_STR_TAG && !isBase60Float(s)
293 }
294 // Note: it's possible for user code to emit invalid YAML
295 // if they explicitly specify a tag and a string containing
296 // text that's incompatible with that tag.
297 switch {
298 case strings.Contains(s, "\n"):
299 style = yaml_LITERAL_SCALAR_STYLE
300 case canUsePlain:
301 style = yaml_PLAIN_SCALAR_STYLE
302 default:
254303 style = yaml_DOUBLE_QUOTED_SCALAR_STYLE
255 } else if strings.Contains(s, "\n") {
256 style = yaml_LITERAL_SCALAR_STYLE
257 } else {
258 style = yaml_PLAIN_SCALAR_STYLE
259304 }
260305 e.emitScalar(s, "", tag, style)
261306 }
280325 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
281326 }
282327
328 func (e *encoder) timev(tag string, in reflect.Value) {
329 t := in.Interface().(time.Time)
330 s := t.Format(time.RFC3339Nano)
331 e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
332 }
333
283334 func (e *encoder) floatv(tag string, in reflect.Value) {
284 // FIXME: Handle 64 bits here.
285 s := strconv.FormatFloat(float64(in.Float()), 'g', -1, 32)
335 // Issue #352: When formatting, use the precision of the underlying value
336 precision := 64
337 if in.Kind() == reflect.Float32 {
338 precision = 32
339 }
340
341 s := strconv.FormatFloat(in.Float(), 'g', -1, precision)
286342 switch s {
287343 case "+Inf":
288344 s = ".inf"
00 package yaml_test
11
22 import (
3 "bytes"
34 "fmt"
45 "math"
56 "strconv"
67 "strings"
78 "time"
89
10 "net"
11 "os"
12
913 . "gopkg.in/check.v1"
1014 "gopkg.in/yaml.v2"
11 "net"
12 "os"
1315 )
1416
1517 var marshalIntTest = 123
2224 nil,
2325 "null\n",
2426 }, {
27 (*marshalerType)(nil),
28 "null\n",
29 }, {
2530 &struct{}{},
2631 "{}\n",
2732 }, {
6974 }, {
7075 map[string]interface{}{"v": float64(0.1)},
7176 "v: 0.1\n",
77 }, {
78 map[string]interface{}{"v": float32(0.99)},
79 "v: 0.99\n",
7280 }, {
7381 map[string]interface{}{"v": -0.1},
7482 "v: -0.1\n",
142150 &struct{ A []int }{[]int{1, 2}},
143151 "a:\n- 1\n- 2\n",
144152 }, {
153 &struct{ A [2]int }{[2]int{1, 2}},
154 "a:\n- 1\n- 2\n",
155 }, {
145156 &struct {
146157 B int "a"
147158 }{1},
195206 B float64 "b,omitempty"
196207 }{1, 0},
197208 "a: 1\n",
209 },
210 {
211 &struct {
212 T1 time.Time "t1,omitempty"
213 T2 time.Time "t2,omitempty"
214 T3 *time.Time "t3,omitempty"
215 T4 *time.Time "t4,omitempty"
216 }{
217 T2: time.Date(2018, 1, 9, 10, 40, 47, 0, time.UTC),
218 T4: newTime(time.Date(2098, 1, 9, 10, 40, 47, 0, time.UTC)),
219 },
220 "t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n",
221 },
222 // Nil interface that implements Marshaler.
223 {
224 map[string]yaml.Marshaler{
225 "a": nil,
226 },
227 "a: null\n",
198228 },
199229
200230 // Flow flag
301331 map[string]net.IP{"a": net.IPv4(1, 2, 3, 4)},
302332 "a: 1.2.3.4\n",
303333 },
304 {
305 map[string]time.Time{"a": time.Unix(1424801979, 0)},
334 // time.Time gets a timestamp tag.
335 {
336 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
306337 "a: 2015-02-24T18:19:39Z\n",
338 },
339 {
340 map[string]*time.Time{"a": newTime(time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC))},
341 "a: 2015-02-24T18:19:39Z\n",
342 },
343 {
344 // This is confirmed to be properly decoded in Python (libyaml) without a timestamp tag.
345 map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 123456789, time.FixedZone("FOO", -3*60*60))},
346 "a: 2015-02-24T18:19:39.123456789-03:00\n",
347 },
348 // Ensure timestamp-like strings are quoted.
349 {
350 map[string]string{"a": "2015-02-24T18:19:39Z"},
351 "a: \"2015-02-24T18:19:39Z\"\n",
307352 },
308353
309354 // Ensure strings containing ": " are quoted (reported as PR #43, but not reproducible).
326371 func (s *S) TestMarshal(c *C) {
327372 defer os.Setenv("TZ", os.Getenv("TZ"))
328373 os.Setenv("TZ", "UTC")
329 for _, item := range marshalTests {
374 for i, item := range marshalTests {
375 c.Logf("test %d: %q", i, item.data)
330376 data, err := yaml.Marshal(item.value)
331377 c.Assert(err, IsNil)
332378 c.Assert(string(data), Equals, item.data)
333379 }
380 }
381
382 func (s *S) TestEncoderSingleDocument(c *C) {
383 for i, item := range marshalTests {
384 c.Logf("test %d. %q", i, item.data)
385 var buf bytes.Buffer
386 enc := yaml.NewEncoder(&buf)
387 err := enc.Encode(item.value)
388 c.Assert(err, Equals, nil)
389 err = enc.Close()
390 c.Assert(err, Equals, nil)
391 c.Assert(buf.String(), Equals, item.data)
392 }
393 }
394
395 func (s *S) TestEncoderMultipleDocuments(c *C) {
396 var buf bytes.Buffer
397 enc := yaml.NewEncoder(&buf)
398 err := enc.Encode(map[string]string{"a": "b"})
399 c.Assert(err, Equals, nil)
400 err = enc.Encode(map[string]string{"c": "d"})
401 c.Assert(err, Equals, nil)
402 err = enc.Close()
403 c.Assert(err, Equals, nil)
404 c.Assert(buf.String(), Equals, "a: b\n---\nc: d\n")
405 }
406
407 func (s *S) TestEncoderWriteError(c *C) {
408 enc := yaml.NewEncoder(errorWriter{})
409 err := enc.Encode(map[string]string{"a": "b"})
410 c.Assert(err, ErrorMatches, `yaml: write error: some write error`) // Data not flushed yet
411 }
412
413 type errorWriter struct{}
414
415 func (errorWriter) Write([]byte) (int, error) {
416 return 0, fmt.Errorf("some write error")
334417 }
335418
336419 var marshalErrorTests = []struct {
454537 "1",
455538 "2",
456539 "a!10",
457 "a/2",
540 "a/0001",
541 "a/002",
542 "a/3",
458543 "a/10",
544 "a/11",
545 "a/0012",
546 "a/100",
459547 "a~10",
460548 "ab/1",
461549 "b/1",
470558 "c2.10",
471559 "c10.2",
472560 "d1",
561 "d7",
562 "d7abc",
473563 "d12",
474564 "d12a",
475565 }
498588 last = index
499589 }
500590 }
591
592 func newTime(t time.Time) *time.Time {
593 return &t
594 }
0 package yaml_test
1
2 import (
3 "fmt"
4 "log"
5
6 "gopkg.in/yaml.v2"
7 )
8
9 // An example showing how to unmarshal embedded
10 // structs from YAML.
11
12 type StructA struct {
13 A string `yaml:"a"`
14 }
15
16 type StructB struct {
17 // Embedded structs are not treated as embedded in YAML by default. To do that,
18 // add the ",inline" annotation below
19 StructA `yaml:",inline"`
20 B string `yaml:"b"`
21 }
22
23 var data = `
24 a: a string from struct A
25 b: a string from struct B
26 `
27
28 func ExampleUnmarshal_embedded() {
29 var b StructB
30
31 err := yaml.Unmarshal([]byte(data), &b)
32 if err != nil {
33 log.Fatalf("cannot unmarshal data: %v", err)
34 }
35 fmt.Println(b.A)
36 fmt.Println(b.B)
37 // Output:
38 // a string from struct A
39 // a string from struct B
40 }
0 module "gopkg.in/yaml.v2"
1
2 require (
3 "gopkg.in/check.v1" v0.0.0-20161208181325-20d25e280405
4 )
9292 panic("read handler must be set")
9393 }
9494
95 // [Go] This function was changed to guarantee the requested length size at EOF.
96 // The fact we need to do this is pretty awful, but the description above implies
97 // for that to be the case, and there are tests
98
9599 // If the EOF flag is set and the raw buffer is empty, do nothing.
96100 if parser.eof && parser.raw_buffer_pos == len(parser.raw_buffer) {
97 return true
101 // [Go] ACTUALLY! Read the documentation of this function above.
102 // This is just broken. To return true, we need to have the
103 // given length in the buffer. Not doing that means every single
104 // check that calls this function to make sure the buffer has a
105 // given length is Go) panicking; or C) accessing invalid memory.
106 //return true
98107 }
99108
100109 // Return if the buffer contains enough characters.
388397 break
389398 }
390399 }
400 // [Go] Read the documentation of this function above. To return true,
401 // we need to have the given length in the buffer. Not doing that means
402 // every single check that calls this function to make sure the buffer
403 // has a given length is Go) panicking; or C) accessing invalid memory.
404 // This happens here due to the EOF above breaking early.
405 for buffer_len < length {
406 parser.buffer[buffer_len] = 0
407 buffer_len++
408 }
391409 parser.buffer = parser.buffer[:buffer_len]
392410 return true
393411 }
55 "regexp"
66 "strconv"
77 "strings"
8 "unicode/utf8"
8 "time"
99 )
1010
1111 type resolveMapItem struct {
7474
7575 func resolvableTag(tag string) bool {
7676 switch tag {
77 case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG:
77 case "", yaml_STR_TAG, yaml_BOOL_TAG, yaml_INT_TAG, yaml_FLOAT_TAG, yaml_NULL_TAG, yaml_TIMESTAMP_TAG:
7878 return true
7979 }
8080 return false
9191 switch tag {
9292 case "", rtag, yaml_STR_TAG, yaml_BINARY_TAG:
9393 return
94 case yaml_FLOAT_TAG:
95 if rtag == yaml_INT_TAG {
96 switch v := out.(type) {
97 case int64:
98 rtag = yaml_FLOAT_TAG
99 out = float64(v)
100 return
101 case int:
102 rtag = yaml_FLOAT_TAG
103 out = float64(v)
104 return
105 }
106 }
94107 }
95108 failf("cannot decode %s `%s` as a %s", shortTag(rtag), in, shortTag(tag))
96109 }()
124137
125138 case 'D', 'S':
126139 // Int, float, or timestamp.
140 // Only try values as a timestamp if the value is unquoted or there's an explicit
141 // !!timestamp tag.
142 if tag == "" || tag == yaml_TIMESTAMP_TAG {
143 t, ok := parseTimestamp(in)
144 if ok {
145 return yaml_TIMESTAMP_TAG, t
146 }
147 }
148
127149 plain := strings.Replace(in, "_", "", -1)
128150 intv, err := strconv.ParseInt(plain, 0, 64)
129151 if err == nil {
157179 return yaml_INT_TAG, uintv
158180 }
159181 } else if strings.HasPrefix(plain, "-0b") {
160 intv, err := strconv.ParseInt(plain[3:], 2, 64)
161 if err == nil {
162 if intv == int64(int(intv)) {
163 return yaml_INT_TAG, -int(intv)
182 intv, err := strconv.ParseInt("-" + plain[3:], 2, 64)
183 if err == nil {
184 if true || intv == int64(int(intv)) {
185 return yaml_INT_TAG, int(intv)
164186 } else {
165 return yaml_INT_TAG, -intv
187 return yaml_INT_TAG, intv
166188 }
167189 }
168190 }
169 // XXX Handle timestamps here.
170
171191 default:
172192 panic("resolveTable item not yet handled: " + string(rune(hint)) + " (with " + in + ")")
173193 }
174194 }
175 if tag == yaml_BINARY_TAG {
176 return yaml_BINARY_TAG, in
177 }
178 if utf8.ValidString(in) {
179 return yaml_STR_TAG, in
180 }
181 return yaml_BINARY_TAG, encodeBase64(in)
195 return yaml_STR_TAG, in
182196 }
183197
184198 // encodeBase64 encodes s as base64 that is broken up into multiple lines
205219 }
206220 return string(out[:k])
207221 }
222
223 // This is a subset of the formats allowed by the regular expression
224 // defined at http://yaml.org/type/timestamp.html.
225 var allowedTimestampFormats = []string{
226 "2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
227 "2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
228 "2006-1-2 15:4:5.999999999", // space separated with no time zone
229 "2006-1-2", // date only
230 // Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
231 // from the set of examples.
232 }
233
234 // parseTimestamp parses s as a timestamp string and
235 // returns the timestamp and reports whether it succeeded.
236 // Timestamp formats are defined at http://yaml.org/type/timestamp.html
237 func parseTimestamp(s string) (time.Time, bool) {
238 // TODO write code to check all the formats supported by
239 // http://yaml.org/type/timestamp.html instead of using time.Parse.
240
241 // Quick check: all date formats start with YYYY-.
242 i := 0
243 for ; i < len(s); i++ {
244 if c := s[i]; c < '0' || c > '9' {
245 break
246 }
247 }
248 if i != 4 || i == len(s) || s[i] != '-' {
249 return time.Time{}, false
250 }
251 for _, format := range allowedTimestampFormats {
252 if t, err := time.Parse(format, s); err == nil {
253 return t, true
254 }
255 }
256 return time.Time{}, false
257 }
610610 if directive {
611611 context = "while parsing a %TAG directive"
612612 }
613 return yaml_parser_set_scanner_error(parser, context, context_mark, "did not find URI escaped octet")
613 return yaml_parser_set_scanner_error(parser, context, context_mark, problem)
614614 }
615615
616616 func trace(args ...interface{}) func() {
870870
871871 required := parser.flow_level == 0 && parser.indent == parser.mark.column
872872
873 // A simple key is required only when it is the first token in the current
874 // line. Therefore it is always allowed. But we add a check anyway.
875 if required && !parser.simple_key_allowed {
876 panic("should not happen")
877 }
878
879873 //
880874 // If the current position may start a simple key, save it.
881875 //
19431937 } else {
19441938 // It's either the '!' tag or not really a tag handle. If it's a %TAG
19451939 // directive, it's an error. If it's a tag token, it must be a part of URI.
1946 if directive && !(s[0] == '!' && s[1] == 0) {
1940 if directive && string(s) != "!" {
19471941 yaml_parser_set_scanner_tag_error(parser, directive,
19481942 start_mark, "did not find expected '!'")
19491943 return false
19581952 func yaml_parser_scan_tag_uri(parser *yaml_parser_t, directive bool, head []byte, start_mark yaml_mark_t, uri *[]byte) bool {
19591953 //size_t length = head ? strlen((char *)head) : 0
19601954 var s []byte
1955 hasTag := len(head) > 0
19611956
19621957 // Copy the head if needed.
19631958 //
19991994 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
20001995 return false
20011996 }
2002 }
2003
2004 // Check if the tag is non-empty.
2005 if len(s) == 0 {
1997 hasTag = true
1998 }
1999
2000 if !hasTag {
20062001 yaml_parser_set_scanner_tag_error(parser, directive,
20072002 start_mark, "did not find expected tag URI")
20082003 return false
24732468 }
24742469 }
24752470
2471 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2472 return false
2473 }
2474
24762475 // Check if we are at the end of the scalar.
24772476 if single {
24782477 if parser.buffer[parser.buffer_pos] == '\'' {
24852484 }
24862485
24872486 // Consume blank characters.
2488 if parser.unread < 1 && !yaml_parser_update_buffer(parser, 1) {
2489 return false
2490 }
2491
24922487 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
24932488 if is_blank(parser.buffer, parser.buffer_pos) {
24942489 // Consume a space or a tab character.
25902585 // Consume non-blank characters.
25912586 for !is_blankz(parser.buffer, parser.buffer_pos) {
25922587
2593 // Check for 'x:x' in the flow context. TODO: Fix the test "spec-08-13".
2594 if parser.flow_level > 0 &&
2595 parser.buffer[parser.buffer_pos] == ':' &&
2596 !is_blankz(parser.buffer, parser.buffer_pos+1) {
2597 yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
2598 start_mark, "found unexpected ':'")
2599 return false
2600 }
2601
26022588 // Check for indicators that may end a plain scalar.
26032589 if (parser.buffer[parser.buffer_pos] == ':' && is_blankz(parser.buffer, parser.buffer_pos+1)) ||
26042590 (parser.flow_level > 0 &&
2605 (parser.buffer[parser.buffer_pos] == ',' || parser.buffer[parser.buffer_pos] == ':' ||
2591 (parser.buffer[parser.buffer_pos] == ',' ||
26062592 parser.buffer[parser.buffer_pos] == '?' || parser.buffer[parser.buffer_pos] == '[' ||
26072593 parser.buffer[parser.buffer_pos] == ']' || parser.buffer[parser.buffer_pos] == '{' ||
26082594 parser.buffer[parser.buffer_pos] == '}')) {
26542640 for is_blank(parser.buffer, parser.buffer_pos) || is_break(parser.buffer, parser.buffer_pos) {
26552641 if is_blank(parser.buffer, parser.buffer_pos) {
26562642
2657 // Check for tab character that abuse indentation.
2643 // Check for tab characters that abuse indentation.
26582644 if leading_blanks && parser.mark.column < indent && is_tab(parser.buffer, parser.buffer_pos) {
26592645 yaml_parser_set_scanner_error(parser, "while scanning a plain scalar",
2660 start_mark, "found a tab character that violate indentation")
2646 start_mark, "found a tab character that violates indentation")
26612647 return false
26622648 }
26632649
5050 }
5151 var ai, bi int
5252 var an, bn int64
53 if ar[i] == '0' || br[i] == '0' {
54 for j := i-1; j >= 0 && unicode.IsDigit(ar[j]); j-- {
55 if ar[j] != '0' {
56 an = 1
57 bn = 1
58 break
59 }
60 }
61 }
5362 for ai = i; ai < len(ar) && unicode.IsDigit(ar[ai]); ai++ {
5463 an = an*10 + int64(ar[ai]-'0')
5564 }
1717 return true
1818 }
1919
20 // If the output encoding is UTF-8, we don't need to recode the buffer.
21 if emitter.encoding == yaml_UTF8_ENCODING {
22 if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
23 return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
24 }
25 emitter.buffer_pos = 0
26 return true
27 }
28
29 // Recode the buffer into the raw buffer.
30 var low, high int
31 if emitter.encoding == yaml_UTF16LE_ENCODING {
32 low, high = 0, 1
33 } else {
34 high, low = 1, 0
35 }
36
37 pos := 0
38 for pos < emitter.buffer_pos {
39 // See the "reader.c" code for more details on UTF-8 encoding. Note
40 // that we assume that the buffer contains a valid UTF-8 sequence.
41
42 // Read the next UTF-8 character.
43 octet := emitter.buffer[pos]
44
45 var w int
46 var value rune
47 switch {
48 case octet&0x80 == 0x00:
49 w, value = 1, rune(octet&0x7F)
50 case octet&0xE0 == 0xC0:
51 w, value = 2, rune(octet&0x1F)
52 case octet&0xF0 == 0xE0:
53 w, value = 3, rune(octet&0x0F)
54 case octet&0xF8 == 0xF0:
55 w, value = 4, rune(octet&0x07)
56 }
57 for k := 1; k < w; k++ {
58 octet = emitter.buffer[pos+k]
59 value = (value << 6) + (rune(octet) & 0x3F)
60 }
61 pos += w
62
63 // Write the character.
64 if value < 0x10000 {
65 var b [2]byte
66 b[high] = byte(value >> 8)
67 b[low] = byte(value & 0xFF)
68 emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1])
69 } else {
70 // Write the character using a surrogate pair (check "reader.c").
71 var b [4]byte
72 value -= 0x10000
73 b[high] = byte(0xD8 + (value >> 18))
74 b[low] = byte((value >> 10) & 0xFF)
75 b[high+2] = byte(0xDC + ((value >> 8) & 0xFF))
76 b[low+2] = byte(value & 0xFF)
77 emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3])
78 }
79 }
80
81 // Write the raw buffer.
82 if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil {
20 if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil {
8321 return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error())
8422 }
8523 emitter.buffer_pos = 0
86 emitter.raw_buffer = emitter.raw_buffer[:0]
8724 return true
8825 }
88 import (
99 "errors"
1010 "fmt"
11 "io"
1112 "reflect"
1213 "strings"
1314 "sync"
7677 // supported tag options.
7778 //
7879 func Unmarshal(in []byte, out interface{}) (err error) {
80 return unmarshal(in, out, false)
81 }
82
83 // UnmarshalStrict is like Unmarshal except that any fields that are found
84 // in the data that do not have corresponding struct members, or mapping
85 // keys that are duplicates, will result in
86 // an error.
87 func UnmarshalStrict(in []byte, out interface{}) (err error) {
88 return unmarshal(in, out, true)
89 }
90
91 // A Decorder reads and decodes YAML values from an input stream.
92 type Decoder struct {
93 strict bool
94 parser *parser
95 }
96
97 // NewDecoder returns a new decoder that reads from r.
98 //
99 // The decoder introduces its own buffering and may read
100 // data from r beyond the YAML values requested.
101 func NewDecoder(r io.Reader) *Decoder {
102 return &Decoder{
103 parser: newParserFromReader(r),
104 }
105 }
106
107 // SetStrict sets whether strict decoding behaviour is enabled when
108 // decoding items in the data (see UnmarshalStrict). By default, decoding is not strict.
109 func (dec *Decoder) SetStrict(strict bool) {
110 dec.strict = strict
111 }
112
113 // Decode reads the next YAML-encoded value from its input
114 // and stores it in the value pointed to by v.
115 //
116 // See the documentation for Unmarshal for details about the
117 // conversion of YAML into a Go value.
118 func (dec *Decoder) Decode(v interface{}) (err error) {
119 d := newDecoder(dec.strict)
79120 defer handleErr(&err)
80 d := newDecoder()
121 node := dec.parser.parse()
122 if node == nil {
123 return io.EOF
124 }
125 out := reflect.ValueOf(v)
126 if out.Kind() == reflect.Ptr && !out.IsNil() {
127 out = out.Elem()
128 }
129 d.unmarshal(node, out)
130 if len(d.terrors) > 0 {
131 return &TypeError{d.terrors}
132 }
133 return nil
134 }
135
136 func unmarshal(in []byte, out interface{}, strict bool) (err error) {
137 defer handleErr(&err)
138 d := newDecoder(strict)
81139 p := newParser(in)
82140 defer p.destroy()
83141 node := p.parse()
98156 // of the generated document will reflect the structure of the value itself.
99157 // Maps and pointers (to struct, string, int, etc) are accepted as the in value.
100158 //
101 // Struct fields are only unmarshalled if they are exported (have an upper case
102 // first letter), and are unmarshalled using the field name lowercased as the
159 // Struct fields are only marshalled if they are exported (have an upper case
160 // first letter), and are marshalled using the field name lowercased as the
103161 // default key. Custom keys may be defined via the "yaml" name in the field
104162 // tag: the content preceding the first comma is used as the key, and the
105163 // following comma-separated options are used to tweak the marshalling process.
113171 //
114172 // omitempty Only include the field if it's not set to the zero
115173 // value for the type or to empty slices or maps.
116 // Does not apply to zero valued structs.
174 // Zero valued structs will be omitted if all their public
175 // fields are zero, unless they implement an IsZero
176 // method (see the IsZeroer interface type), in which
177 // case the field will be included if that method returns true.
117178 //
118179 // flow Marshal using a flow style (useful for structs,
119180 // sequences and maps).
128189 // For example:
129190 //
130191 // type T struct {
131 // F int "a,omitempty"
192 // F int `yaml:"a,omitempty"`
132193 // B int
133194 // }
134195 // yaml.Marshal(&T{B: 2}) // Returns "b: 2\n"
138199 defer handleErr(&err)
139200 e := newEncoder()
140201 defer e.destroy()
141 e.marshal("", reflect.ValueOf(in))
202 e.marshalDoc("", reflect.ValueOf(in))
142203 e.finish()
143204 out = e.out
144205 return
206 }
207
208 // An Encoder writes YAML values to an output stream.
209 type Encoder struct {
210 encoder *encoder
211 }
212
213 // NewEncoder returns a new encoder that writes to w.
214 // The Encoder should be closed after use to flush all data
215 // to w.
216 func NewEncoder(w io.Writer) *Encoder {
217 return &Encoder{
218 encoder: newEncoderWithWriter(w),
219 }
220 }
221
222 // Encode writes the YAML encoding of v to the stream.
223 // If multiple items are encoded to the stream, the
224 // second and subsequent document will be preceded
225 // with a "---" document separator, but the first will not.
226 //
227 // See the documentation for Marshal for details about the conversion of Go
228 // values to YAML.
229 func (e *Encoder) Encode(v interface{}) (err error) {
230 defer handleErr(&err)
231 e.encoder.marshalDoc("", reflect.ValueOf(v))
232 return nil
233 }
234
235 // Close closes the encoder by writing any remaining data.
236 // It does not write a stream terminating string "...".
237 func (e *Encoder) Close() (err error) {
238 defer handleErr(&err)
239 e.encoder.finish()
240 return nil
145241 }
146242
147243 func handleErr(err *error) {
199295 Num int
200296 OmitEmpty bool
201297 Flow bool
298 // Id holds the unique field identifier, so we can cheaply
299 // check for field duplicates without maintaining an extra map.
300 Id int
202301
203302 // Inline holds the field index if the field is part of an inlined struct.
204303 Inline []int
278377 } else {
279378 finfo.Inline = append([]int{i}, finfo.Inline...)
280379 }
380 finfo.Id = len(fieldsList)
281381 fieldsMap[finfo.Key] = finfo
282382 fieldsList = append(fieldsList, finfo)
283383 }
299399 return nil, errors.New(msg)
300400 }
301401
402 info.Id = len(fieldsList)
302403 fieldsList = append(fieldsList, info)
303404 fieldsMap[info.Key] = info
304405 }
305406
306 sinfo = &structInfo{fieldsMap, fieldsList, inlineMap}
407 sinfo = &structInfo{
408 FieldsMap: fieldsMap,
409 FieldsList: fieldsList,
410 InlineMap: inlineMap,
411 }
307412
308413 fieldMapMutex.Lock()
309414 structMap[st] = sinfo
311416 return sinfo, nil
312417 }
313418
419 // IsZeroer is used to check whether an object is zero to
420 // determine whether it should be omitted when marshaling
421 // with the omitempty flag. One notable implementation
422 // is time.Time.
423 type IsZeroer interface {
424 IsZero() bool
425 }
426
314427 func isZero(v reflect.Value) bool {
315 switch v.Kind() {
428 kind := v.Kind()
429 if z, ok := v.Interface().(IsZeroer); ok {
430 if (kind == reflect.Ptr || kind == reflect.Interface) && v.IsNil() {
431 return true
432 }
433 return z.IsZero()
434 }
435 switch kind {
316436 case reflect.String:
317437 return len(v.String()) == 0
318438 case reflect.Interface, reflect.Ptr:
00 package yaml
11
22 import (
3 "fmt"
34 "io"
45 )
56
237238 yaml_MAPPING_START_EVENT // A MAPPING-START event.
238239 yaml_MAPPING_END_EVENT // A MAPPING-END event.
239240 )
241
242 var eventStrings = []string{
243 yaml_NO_EVENT: "none",
244 yaml_STREAM_START_EVENT: "stream start",
245 yaml_STREAM_END_EVENT: "stream end",
246 yaml_DOCUMENT_START_EVENT: "document start",
247 yaml_DOCUMENT_END_EVENT: "document end",
248 yaml_ALIAS_EVENT: "alias",
249 yaml_SCALAR_EVENT: "scalar",
250 yaml_SEQUENCE_START_EVENT: "sequence start",
251 yaml_SEQUENCE_END_EVENT: "sequence end",
252 yaml_MAPPING_START_EVENT: "mapping start",
253 yaml_MAPPING_END_EVENT: "mapping end",
254 }
255
256 func (e yaml_event_type_t) String() string {
257 if e < 0 || int(e) >= len(eventStrings) {
258 return fmt.Sprintf("unknown event %d", e)
259 }
260 return eventStrings[e]
261 }
240262
241263 // The event structure.
242264 type yaml_event_t struct {
507529
508530 problem string // Error description.
509531
510 // The byte about which the problem occured.
532 // The byte about which the problem occurred.
511533 problem_offset int
512534 problem_value int
513535 problem_mark yaml_mark_t
520542
521543 read_handler yaml_read_handler_t // Read handler.
522544
523 input_file io.Reader // File input data.
524 input []byte // String input data.
525 input_pos int
545 input_reader io.Reader // File input data.
546 input []byte // String input data.
547 input_pos int
526548
527549 eof bool // EOF flag
528550
631653 write_handler yaml_write_handler_t // Write handler.
632654
633655 output_buffer *[]byte // String output data.
634 output_file io.Writer // File output data.
656 output_writer io.Writer // File output data.
635657
636658 buffer []byte // The working buffer.
637659 buffer_pos int // The current position of the buffer.