psych
psych copied to clipboard
Need port to Java of fix for excessive quoting fix for line width -1
See #254. This code was not ported to the Java stuff.
Here's my attempt at a patch, but it causes out-of-memory errors for some reason (i.e. it's broken in a non-obvious way I can't fix right now):
diff --git a/ext/java/PsychEmitter.java b/ext/java/PsychEmitter.java
index d9f3231..c0be111 100644
--- a/ext/java/PsychEmitter.java
+++ b/ext/java/PsychEmitter.java
@@ -29,23 +29,36 @@ package org.jruby.ext.psych;
import java.io.IOException;
import java.io.OutputStreamWriter;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channel;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import org.jcodings.Encoding;
+import org.jcodings.specific.UTF8Encoding;
import org.jruby.Ruby;
import org.jruby.RubyArray;
import org.jruby.RubyClass;
+import org.jruby.RubyEncoding;
import org.jruby.RubyFixnum;
+import org.jruby.RubyIO;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.RubyString;
import org.jruby.anno.JRubyMethod;
+import org.jruby.exceptions.RaiseException;
+import org.jruby.java.addons.IOJavaAddons;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.callsite.NormalCachingCallSite;
+import org.jruby.util.ByteList;
import org.jruby.util.IOOutputStream;
+import org.jruby.util.StringSupport;
+import org.jruby.util.io.ChannelHelper;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.emitter.Emitter;
import org.yaml.snakeyaml.emitter.EmitterException;
@@ -317,13 +330,45 @@ public class PsychEmitter extends RubyObject {
}
}
- private void initEmitter(ThreadContext context, IRubyObject _encoding) {
+ private void initEmitter(final ThreadContext context, IRubyObject _encoding) {
if (emitter != null) throw context.runtime.newRuntimeError("already initialized emitter");
- Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding;
- Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding);
+ WritableByteChannel out = new WritableByteChannel() {
+ NormalCachingCallSite adapter = new NormalCachingCallSite("write");
+ RubyString tmpStr;
+ ByteList tmpBL;
+ @Override
+ public synchronized int write(ByteBuffer src) throws IOException {
+ if (tmpStr == null) {
+ tmpBL = new ByteList(src.array(), src.position(), src.remaining(), UTF8Encoding.INSTANCE, false);
+ tmpStr = RubyString.newString(context.runtime, tmpBL, StringSupport.CR_UNKNOWN);
+ } else {
+ tmpBL.setUnsafeBytes(src.array());
+ tmpBL.setBegin(src.position());
+ tmpBL.setRealSize(src.remaining());
+ }
+ try {
+ return adapter.call(context, PsychEmitter.this, io, tmpStr).convertToInteger().getIntValue();
+ } catch (RaiseException re) {
+ throw new IOException("error in dynamic write: " + re.getMessage(), re);
+ }
+ }
- emitter = new Emitter(new OutputStreamWriter(new IOOutputStream(io, encoding), charset), options);
+ @Override
+ public boolean isOpen() {
+ return !io.callMethod(context, "closed?").isTrue();
+ }
+
+ @Override
+ public void close() throws IOException {
+ try {
+ io.callMethod(context, "close");
+ } catch (RaiseException re) {
+ throw new IOException("error in dynamic close: " + re.getMessage(), re);
+ }
+ }
+ };
+ emitter = new Emitter(new OutputStreamWriter(Channels.newOutputStream(out), RubyEncoding.UTF8), options);
}
Emitter emitter;