private Node composeSequenceNode(String anchor) { SequenceStartEvent startEvent = (SequenceStartEvent) this.parser.getEvent(); String tag = startEvent.getTag(); boolean resolved = false; Tag nodeTag; if ((tag == null) || (tag.equals("!"))) { Tag nodeTag = this.resolver.resolve(NodeId.sequence, null, startEvent.getImplicit()); resolved = true; } else { nodeTag = new Tag(tag); } ArrayList<Node> children = new ArrayList(); SequenceNode node = new SequenceNode( nodeTag, resolved, children, startEvent.getStartMark(), null, startEvent.getFlowStyle()); if (anchor != null) { this.anchors.put(anchor, node); } while (!this.parser.checkEvent(Event.ID.SequenceEnd)) { children.add(composeNode(node)); } Event endEvent = this.parser.getEvent(); node.setEndMark(endEvent.getEndMark()); return node; }
@JRubyMethod public IRubyObject parse(ThreadContext context, IRubyObject target) { Ruby runtime = context.runtime; // FIXME? only supports Unicode, since we have to produces strings... StreamReader reader; if (target.respondsTo("read")) { reader = new StreamReader(new InputStreamReader(new IOInputStream(target))); } else { reader = new StreamReader(new StringReader(target.convertToString().asJavaString())); } Parser parser = new ParserImpl(reader); IRubyObject handler = getInstanceVariable("@handler"); Event event; while (true) { try { event = parser.getEvent(); // FIXME: Event should expose a getID, so it can be switched if (event.is(ID.StreamStart)) { invoke(context, handler, "start_stream", runtime.newFixnum(YAML_ANY_ENCODING)); } else if (event.is(ID.DocumentStart)) { DocumentStartEvent dse = (DocumentStartEvent) event; Integer[] versionInts = dse.getVersion(); IRubyObject version = versionInts == null ? runtime.getNil() : RubyArray.newArray( runtime, runtime.newFixnum(versionInts[0]), runtime.newFixnum(versionInts[1])); Map<String, String> tagsMap = dse.getTags(); RubyArray tags = RubyArray.newArray(runtime); if (tags.size() > 0) { for (Map.Entry<String, String> tag : tagsMap.entrySet()) { tags.append( RubyArray.newArray( runtime, RubyString.newString(runtime, tag.getKey()), RubyString.newString(runtime, tag.getValue()))); } } invoke( context, handler, "start_document", version, tags, runtime.newBoolean(dse.getExplicit())); } else if (event.is(ID.DocumentEnd)) { DocumentEndEvent dee = (DocumentEndEvent) event; invoke(context, handler, "end_document", runtime.newBoolean(dee.getExplicit())); } else if (event.is(ID.Alias)) { AliasEvent ae = (AliasEvent) event; IRubyObject alias = runtime.getNil(); if (ae.getAnchor() != null) { alias = RubyString.newString(runtime, ae.getAnchor()); } invoke(context, handler, "alias", alias); } else if (event.is(ID.Scalar)) { ScalarEvent se = (ScalarEvent) event; IRubyObject anchor = se.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, se.getAnchor()); IRubyObject tag = se.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, se.getTag()); IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().isFirst()); IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().isSecond()); IRubyObject style = runtime.newFixnum(se.getStyle()); IRubyObject val = RubyString.newString(runtime, se.getValue()); invoke( context, handler, "scalar", val, anchor, tag, plain_implicit, quoted_implicit, style); } else if (event.is(ID.SequenceStart)) { SequenceStartEvent sse = (SequenceStartEvent) event; IRubyObject anchor = sse.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, sse.getAnchor()); IRubyObject tag = sse.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, sse.getTag()); IRubyObject implicit = runtime.newBoolean(sse.getImplicit()); IRubyObject style = runtime.newFixnum(sse.getFlowStyle() ? 1 : 0); invoke(context, handler, "start_sequence", anchor, tag, implicit, style); } else if (event.is(ID.SequenceEnd)) { invoke(context, handler, "end_sequence"); } else if (event.is(ID.MappingStart)) { MappingStartEvent mse = (MappingStartEvent) event; IRubyObject anchor = mse.getAnchor() == null ? runtime.getNil() : RubyString.newString(runtime, mse.getAnchor()); IRubyObject tag = mse.getTag() == null ? runtime.getNil() : RubyString.newString(runtime, mse.getTag()); IRubyObject implicit = runtime.newBoolean(mse.getImplicit()); IRubyObject style = runtime.newFixnum(mse.getFlowStyle() ? 1 : 0); invoke(context, handler, "start_mapping", anchor, tag, implicit, style); } else if (event.is(ID.MappingEnd)) { invoke(context, handler, "end_mapping"); } else if (event.is(ID.StreamEnd)) { invoke(context, handler, "end_stream"); break; } } catch (ParserException pe) { parser = null; RubyKernel.raise( context, runtime.getModule("Psych").getConstant("SyntaxError"), new IRubyObject[] {runtime.newString(pe.getLocalizedMessage())}, Block.NULL_BLOCK); } } return this; }