psych 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,93 +0,0 @@
1
- /***** BEGIN LICENSE BLOCK *****
2
- * Version: EPL 1.0/GPL 2.0/LGPL 2.1
3
- *
4
- * The contents of this file are subject to the Eclipse Public
5
- * License Version 1.0 (the "License"); you may not use this file
6
- * except in compliance with the License. You may obtain a copy of
7
- * the License at http://www.eclipse.org/legal/epl-v10.html
8
- *
9
- * Software distributed under the License is distributed on an "AS
10
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11
- * implied. See the License for the specific language governing
12
- * rights and limitations under the License.
13
- *
14
- * Copyright (C) 2010 Charles O Nutter <headius@headius.com>
15
- *
16
- * Alternatively, the contents of this file may be used under the terms of
17
- * either of the GNU General Public License Version 2 or later (the "GPL"),
18
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19
- * in which case the provisions of the GPL or the LGPL are applicable instead
20
- * of those above. If you wish to allow use of your version of this file only
21
- * under the terms of either the GPL or the LGPL, and not to allow others to
22
- * use your version of this file under the terms of the EPL, indicate your
23
- * decision by deleting the provisions above and replace them with the notice
24
- * and other provisions required by the GPL or the LGPL. If you do not delete
25
- * the provisions above, a recipient may use your version of this file under
26
- * the terms of any one of the EPL, the GPL or the LGPL.
27
- ***** END LICENSE BLOCK *****/
28
- package org.jruby.ext.psych;
29
-
30
- import java.io.InputStream;
31
- import java.io.IOException;
32
- import java.util.Properties;
33
-
34
- import org.jcodings.Encoding;
35
- import org.jcodings.specific.UTF16BEEncoding;
36
- import org.jcodings.specific.UTF16LEEncoding;
37
- import org.jcodings.specific.UTF8Encoding;
38
- import org.jruby.Ruby;
39
- import org.jruby.RubyArray;
40
- import org.jruby.RubyModule;
41
- import org.jruby.RubyString;
42
- import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodZero;
43
- import org.jruby.runtime.ThreadContext;
44
- import org.jruby.runtime.Visibility;
45
- import org.jruby.runtime.builtin.IRubyObject;
46
- import org.jruby.runtime.load.Library;
47
-
48
- public class PsychLibrary implements Library {
49
- public void load(final Ruby runtime, boolean wrap) {
50
- RubyModule psych = runtime.defineModule("Psych");
51
-
52
- // load version from properties packed with the jar
53
- Properties props = new Properties();
54
- try( InputStream is = runtime.getJRubyClassLoader().getResourceAsStream("META-INF/maven/org.yaml/snakeyaml/pom.properties") ) {
55
- props.load(is);
56
- }
57
- catch( IOException e ) {
58
- // ignored
59
- }
60
- RubyString version = runtime.newString(props.getProperty("version", "0.0") + ".0");
61
- version.setFrozen(true);
62
- psych.setConstant("SNAKEYAML_VERSION", version);
63
-
64
- String[] versionParts = version.toString().split("\\.");
65
- final RubyArray versionElements = runtime.newArray(runtime.newFixnum(Integer.parseInt(versionParts[0])), runtime.newFixnum(Integer.parseInt(versionParts[1])), runtime.newFixnum(Integer.parseInt(versionParts[2])));
66
- versionElements.setFrozen(true);
67
-
68
- psych.getSingletonClass().addMethod("libyaml_version", new JavaMethodZero(psych, Visibility.PUBLIC) {
69
- @Override
70
- public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
71
- return versionElements;
72
- }
73
- });
74
-
75
- PsychParser.initPsychParser(runtime, psych);
76
- PsychEmitter.initPsychEmitter(runtime, psych);
77
- PsychToRuby.initPsychToRuby(runtime, psych);
78
- PsychYamlTree.initPsychYamlTree(runtime, psych);
79
- }
80
-
81
- public enum YAMLEncoding {
82
- YAML_ANY_ENCODING(UTF8Encoding.INSTANCE),
83
- YAML_UTF8_ENCODING(UTF8Encoding.INSTANCE),
84
- YAML_UTF16LE_ENCODING(UTF16LEEncoding.INSTANCE),
85
- YAML_UTF16BE_ENCODING(UTF16BEEncoding.INSTANCE);
86
-
87
- YAMLEncoding(Encoding encoding) {
88
- this.encoding = encoding;
89
- }
90
-
91
- public final Encoding encoding;
92
- }
93
- }
@@ -1,399 +0,0 @@
1
- /***** BEGIN LICENSE BLOCK *****
2
- * Version: EPL 1.0/GPL 2.0/LGPL 2.1
3
- *
4
- * The contents of this file are subject to the Eclipse Public
5
- * License Version 1.0 (the "License"); you may not use this file
6
- * except in compliance with the License. You may obtain a copy of
7
- * the License at http://www.eclipse.org/legal/epl-v10.html
8
- *
9
- * Software distributed under the License is distributed on an "AS
10
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11
- * implied. See the License for the specific language governing
12
- * rights and limitations under the License.
13
- *
14
- * Copyright (C) 2010 Charles O Nutter <headius@headius.com>
15
- *
16
- * Alternatively, the contents of this file may be used under the terms of
17
- * either of the GNU General Public License Version 2 or later (the "GPL"),
18
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
19
- * in which case the provisions of the GPL or the LGPL are applicable instead
20
- * of those above. If you wish to allow use of your version of this file only
21
- * under the terms of either the GPL or the LGPL, and not to allow others to
22
- * use your version of this file under the terms of the EPL, indicate your
23
- * decision by deleting the provisions above and replace them with the notice
24
- * and other provisions required by the GPL or the LGPL. If you do not delete
25
- * the provisions above, a recipient may use your version of this file under
26
- * the terms of any one of the EPL, the GPL or the LGPL.
27
- ***** END LICENSE BLOCK *****/
28
- package org.jruby.ext.psych;
29
-
30
- import java.io.ByteArrayInputStream;
31
- import java.io.InputStreamReader;
32
- import java.nio.charset.Charset;
33
- import java.util.Map;
34
-
35
- import org.jcodings.Encoding;
36
- import org.jcodings.specific.UTF8Encoding;
37
- import org.jcodings.unicode.UnicodeEncoding;
38
- import org.jruby.Ruby;
39
- import org.jruby.RubyArray;
40
- import org.jruby.RubyClass;
41
- import org.jruby.RubyEncoding;
42
- import org.jruby.RubyIO;
43
- import org.jruby.RubyKernel;
44
- import org.jruby.RubyModule;
45
- import org.jruby.RubyObject;
46
- import org.jruby.RubyString;
47
- import org.jruby.anno.JRubyMethod;
48
- import static org.jruby.ext.psych.PsychLibrary.YAMLEncoding.*;
49
- import org.jruby.runtime.Block;
50
- import org.jruby.runtime.Helpers;
51
- import org.jruby.runtime.ObjectAllocator;
52
- import org.jruby.runtime.ThreadContext;
53
- import org.jruby.runtime.builtin.IRubyObject;
54
- import org.jruby.util.IOInputStream;
55
- import org.jruby.util.io.EncodingUtils;
56
- import org.jruby.util.log.Logger;
57
- import org.jruby.util.log.LoggerFactory;
58
- import org.yaml.snakeyaml.DumperOptions;
59
- import org.yaml.snakeyaml.error.Mark;
60
- import org.yaml.snakeyaml.error.MarkedYAMLException;
61
- import org.yaml.snakeyaml.events.AliasEvent;
62
- import org.yaml.snakeyaml.events.DocumentEndEvent;
63
- import org.yaml.snakeyaml.events.DocumentStartEvent;
64
- import org.yaml.snakeyaml.events.Event;
65
- import org.yaml.snakeyaml.events.Event.ID;
66
- import org.yaml.snakeyaml.events.MappingStartEvent;
67
- import org.yaml.snakeyaml.events.ScalarEvent;
68
- import org.yaml.snakeyaml.events.SequenceStartEvent;
69
- import org.yaml.snakeyaml.parser.Parser;
70
- import org.yaml.snakeyaml.parser.ParserException;
71
- import org.yaml.snakeyaml.parser.ParserImpl;
72
- import org.yaml.snakeyaml.reader.ReaderException;
73
- import org.yaml.snakeyaml.reader.StreamReader;
74
- import org.yaml.snakeyaml.scanner.ScannerException;
75
- import static org.jruby.runtime.Helpers.invoke;
76
- import org.jruby.util.ByteList;
77
-
78
- public class PsychParser extends RubyObject {
79
-
80
- private static final Logger LOG = LoggerFactory.getLogger(PsychParser.class);
81
-
82
- public static void initPsychParser(Ruby runtime, RubyModule psych) {
83
- RubyClass psychParser = runtime.defineClassUnder("Parser", runtime.getObject(), new ObjectAllocator() {
84
- public IRubyObject allocate(Ruby runtime, RubyClass klazz) {
85
- return new PsychParser(runtime, klazz);
86
- }
87
- }, psych);
88
-
89
- RubyKernel.require(runtime.getNil(),
90
- runtime.newString("psych/syntax_error"), Block.NULL_BLOCK);
91
- psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
92
- psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal()));
93
- psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal()));
94
- psychParser.defineConstant("UTF16BE", runtime.newFixnum(YAML_UTF16BE_ENCODING.ordinal()));
95
-
96
- psychParser.defineAnnotatedMethods(PsychParser.class);
97
- }
98
-
99
- public PsychParser(Ruby runtime, RubyClass klass) {
100
- super(runtime, klass);
101
- }
102
-
103
- @JRubyMethod
104
- public IRubyObject parse(ThreadContext context, IRubyObject yaml) {
105
- Ruby runtime = context.runtime;
106
-
107
- return parse(context, yaml, runtime.getNil());
108
- }
109
-
110
- private IRubyObject stringOrNilFor(Ruby runtime, String value, boolean tainted) {
111
- if (value == null) return runtime.getNil(); // No need to taint nil
112
-
113
- return stringFor(runtime, value, tainted);
114
- }
115
-
116
- private RubyString stringFor(Ruby runtime, String value, boolean tainted) {
117
- Encoding encoding = runtime.getDefaultInternalEncoding();
118
- if (encoding == null) {
119
- encoding = UTF8Encoding.INSTANCE;
120
- }
121
-
122
- Charset charset = RubyEncoding.UTF8;
123
- if (encoding.getCharset() != null) {
124
- charset = encoding.getCharset();
125
- }
126
-
127
- ByteList bytes = new ByteList(value.getBytes(charset), encoding);
128
- RubyString string = RubyString.newString(runtime, bytes);
129
-
130
- string.setTaint(tainted);
131
-
132
- return string;
133
- }
134
-
135
- private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
136
- Ruby runtime = context.runtime;
137
-
138
- if (yaml instanceof RubyString) {
139
- ByteList byteList = ((RubyString)yaml).getByteList();
140
- Encoding enc = byteList.getEncoding();
141
-
142
- // if not unicode, transcode to UTF8
143
- if (!(enc instanceof UnicodeEncoding)) {
144
- byteList = EncodingUtils.strConvEnc(context, byteList, enc, UTF8Encoding.INSTANCE);
145
- enc = UTF8Encoding.INSTANCE;
146
- }
147
-
148
- ByteArrayInputStream bais = new ByteArrayInputStream(byteList.getUnsafeBytes(), byteList.getBegin(), byteList.getRealSize());
149
-
150
- Charset charset = enc.getCharset();
151
-
152
- assert charset != null : "charset for encoding " + enc + " should not be null";
153
-
154
- InputStreamReader isr = new InputStreamReader(bais, charset);
155
-
156
- return new StreamReader(isr);
157
- }
158
-
159
- // fall back on IOInputStream, using default charset
160
- if (yaml.respondsTo("read")) {
161
- Encoding enc = (yaml instanceof RubyIO)
162
- ? ((RubyIO)yaml).getReadEncoding()
163
- : UTF8Encoding.INSTANCE;
164
- Charset charset = enc.getCharset();
165
- return new StreamReader(new InputStreamReader(new IOInputStream(yaml), charset));
166
- } else {
167
- throw runtime.newTypeError(yaml, runtime.getIO());
168
- }
169
- }
170
-
171
- @JRubyMethod
172
- public IRubyObject parse(ThreadContext context, IRubyObject yaml, IRubyObject path) {
173
- Ruby runtime = context.runtime;
174
- boolean tainted = yaml.isTaint() || yaml instanceof RubyIO;
175
-
176
- try {
177
- parser = new ParserImpl(readerFor(context, yaml));
178
-
179
- if (path.isNil() && yaml.respondsTo("path")) {
180
- path = yaml.callMethod(context, "path");
181
- }
182
-
183
- IRubyObject handler = getInstanceVariable("@handler");
184
-
185
- while (true) {
186
- event = parser.getEvent();
187
-
188
- // FIXME: Event should expose a getID, so it can be switched
189
- if (event.is(ID.StreamStart)) {
190
- invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
191
- } else if (event.is(ID.DocumentStart)) {
192
- handleDocumentStart(context, (DocumentStartEvent) event, tainted, handler);
193
- } else if (event.is(ID.DocumentEnd)) {
194
- IRubyObject notExplicit = runtime.newBoolean(!((DocumentEndEvent) event).getExplicit());
195
-
196
- invoke(context, handler, "end_document", notExplicit);
197
- } else if (event.is(ID.Alias)) {
198
- IRubyObject alias = stringOrNilFor(runtime, ((AliasEvent)event).getAnchor(), tainted);
199
-
200
- invoke(context, handler, "alias", alias);
201
- } else if (event.is(ID.Scalar)) {
202
- handleScalar(context, (ScalarEvent) event, tainted, handler);
203
- } else if (event.is(ID.SequenceStart)) {
204
- handleSequenceStart(context,(SequenceStartEvent) event, tainted, handler);
205
- } else if (event.is(ID.SequenceEnd)) {
206
- invoke(context, handler, "end_sequence");
207
- } else if (event.is(ID.MappingStart)) {
208
- handleMappingStart(context, (MappingStartEvent) event, tainted, handler);
209
- } else if (event.is(ID.MappingEnd)) {
210
- invoke(context, handler, "end_mapping");
211
- } else if (event.is(ID.StreamEnd)) {
212
- invoke(context, handler, "end_stream");
213
-
214
- break;
215
- }
216
- }
217
- } catch (ParserException pe) {
218
- parser = null;
219
- raiseParserException(context, yaml, pe, path);
220
-
221
- } catch (ScannerException se) {
222
- parser = null;
223
- StringBuilder message = new StringBuilder("syntax error");
224
- if (se.getProblemMark() != null) {
225
- message.append(se.getProblemMark().toString());
226
- }
227
- raiseParserException(context, yaml, se, path);
228
-
229
- } catch (ReaderException re) {
230
- parser = null;
231
- raiseParserException(context, yaml, re, path);
232
-
233
- } catch (Throwable t) {
234
- Helpers.throwException(t);
235
- return this;
236
- }
237
-
238
- return this;
239
- }
240
-
241
- private void handleDocumentStart(ThreadContext context, DocumentStartEvent dse, boolean tainted, IRubyObject handler) {
242
- Ruby runtime = context.runtime;
243
- DumperOptions.Version _version = dse.getVersion();
244
- Integer[] versionInts = _version == null ? null : _version.getArray();
245
- IRubyObject version = versionInts == null ?
246
- RubyArray.newArray(runtime) :
247
- RubyArray.newArray(runtime, runtime.newFixnum(versionInts[0]), runtime.newFixnum(versionInts[1]));
248
-
249
- Map<String, String> tagsMap = dse.getTags();
250
- RubyArray tags = RubyArray.newArray(runtime);
251
- if (tagsMap != null && tagsMap.size() > 0) {
252
- for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
253
- IRubyObject key = stringFor(runtime, tag.getKey(), tainted);
254
- IRubyObject value = stringFor(runtime, tag.getValue(), tainted);
255
-
256
- tags.append(RubyArray.newArray(runtime, key, value));
257
- }
258
- }
259
- IRubyObject notExplicit = runtime.newBoolean(!dse.getExplicit());
260
-
261
- invoke(context, handler, "start_document", version, tags, notExplicit);
262
- }
263
-
264
- private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) {
265
- Ruby runtime = context.runtime;
266
- IRubyObject anchor = stringOrNilFor(runtime, mse.getAnchor(), tainted);
267
- IRubyObject tag = stringOrNilFor(runtime, mse.getTag(), tainted);
268
- IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
269
- IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
270
-
271
- invoke(context, handler, "start_mapping", anchor, tag, implicit, style);
272
- }
273
-
274
- private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) {
275
- Ruby runtime = context.runtime;
276
- IRubyObject anchor = stringOrNilFor(runtime, se.getAnchor(), tainted);
277
- IRubyObject tag = stringOrNilFor(runtime, se.getTag(), tainted);
278
- IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
279
- IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
280
- IRubyObject style = runtime.newFixnum(translateStyle(se.getStyle()));
281
- IRubyObject val = stringFor(runtime, se.getValue(), tainted);
282
-
283
- invoke(context, handler, "scalar", val, anchor, tag, plain_implicit,
284
- quoted_implicit, style);
285
- }
286
-
287
- private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) {
288
- Ruby runtime = context.runtime;
289
- IRubyObject anchor = stringOrNilFor(runtime, sse.getAnchor(), tainted);
290
- IRubyObject tag = stringOrNilFor(runtime, sse.getTag(), tainted);
291
- IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
292
- IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
293
-
294
- invoke(context, handler, "start_sequence", anchor, tag, implicit, style);
295
- }
296
-
297
- private static void raiseParserException(ThreadContext context, IRubyObject yaml, ReaderException re, IRubyObject rbPath) {
298
- Ruby runtime;
299
- RubyClass se;
300
- IRubyObject exception;
301
-
302
- runtime = context.runtime;
303
- se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
304
-
305
- exception = se.newInstance(context,
306
- new IRubyObject[] {
307
- rbPath,
308
- runtime.newFixnum(0),
309
- runtime.newFixnum(0),
310
- runtime.newFixnum(re.getPosition()),
311
- (null == re.getName() ? runtime.getNil() : runtime.newString(re.getName())),
312
- (null == re.toString() ? runtime.getNil() : runtime.newString(re.toString()))
313
- },
314
- Block.NULL_BLOCK);
315
-
316
- RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
317
- }
318
-
319
- private static void raiseParserException(ThreadContext context, IRubyObject yaml, MarkedYAMLException mye, IRubyObject rbPath) {
320
- Ruby runtime;
321
- Mark mark;
322
- RubyClass se;
323
- IRubyObject exception;
324
-
325
- runtime = context.runtime;
326
- se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
327
-
328
- mark = mye.getProblemMark();
329
-
330
- exception = se.newInstance(context,
331
- new IRubyObject[] {
332
- rbPath,
333
- runtime.newFixnum(mark.getLine() + 1),
334
- runtime.newFixnum(mark.getColumn() + 1),
335
- runtime.newFixnum(mark.getIndex()),
336
- (null == mye.getProblem() ? runtime.getNil() : runtime.newString(mye.getProblem())),
337
- (null == mye.getContext() ? runtime.getNil() : runtime.newString(mye.getContext()))
338
- },
339
- Block.NULL_BLOCK);
340
-
341
- RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
342
- }
343
-
344
- private static int translateStyle(Character style) {
345
- if (style == null) return 0; // any
346
-
347
- switch (style) {
348
- case 0: return 1; // plain
349
- case '\'': return 2; // single-quoted
350
- case '"': return 3; // double-quoted
351
- case '|': return 4; // literal
352
- case '>': return 5; // folded
353
- default: return 0; // any
354
- }
355
- }
356
-
357
- private static int translateFlowStyle(Boolean flowStyle) {
358
- if (flowStyle == null) return 0; // any
359
-
360
- if (flowStyle) return 2;
361
- return 1;
362
- }
363
-
364
- @JRubyMethod
365
- public IRubyObject mark(ThreadContext context) {
366
- Ruby runtime = context.runtime;
367
-
368
- Event event = null;
369
-
370
- if (parser != null) {
371
- event = parser.peekEvent();
372
-
373
- if (event == null) event = this.event;
374
- }
375
-
376
- if (event == null) {
377
- return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
378
- context,
379
- runtime.newFixnum(0),
380
- runtime.newFixnum(0),
381
- runtime.newFixnum(0),
382
- Block.NULL_BLOCK
383
- );
384
- }
385
-
386
- Mark mark = event.getStartMark();
387
-
388
- return ((RubyClass)context.runtime.getClassFromPath("Psych::Parser::Mark")).newInstance(
389
- context,
390
- runtime.newFixnum(mark.getIndex()),
391
- runtime.newFixnum(mark.getLine()),
392
- runtime.newFixnum(mark.getColumn()),
393
- Block.NULL_BLOCK
394
- );
395
- }
396
-
397
- private Parser parser;
398
- private Event event;
399
- }