Skip to content

Instantly share code, notes, and snippets.

@headius
Created September 27, 2012 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/3796362 to your computer and use it in GitHub Desktop.
Save headius/3796362 to your computer and use it in GitHub Desktop.
diff -r 9126dde66e63 src/main/java/org/yaml/snakeyaml/emitter/Emitter.java
--- a/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java Wed Sep 05 20:14:52 2012 +0200
+++ b/src/main/java/org/yaml/snakeyaml/emitter/Emitter.java Sat Sep 29 10:19:20 2012 -0500
@@ -46,6 +46,7 @@
import org.yaml.snakeyaml.events.StreamEndEvent;
import org.yaml.snakeyaml.events.StreamStartEvent;
import org.yaml.snakeyaml.nodes.Tag;
+import org.yaml.snakeyaml.reader.StreamReader;
import org.yaml.snakeyaml.scanner.Constant;
import org.yaml.snakeyaml.util.ArrayStack;
@@ -1225,12 +1226,20 @@
String data;
if (ESCAPE_REPLACEMENTS.containsKey(ch)) {
data = "\\" + ESCAPE_REPLACEMENTS.get(ch);
- } else if (!this.allowUnicode) {
- // this is different from PyYAML which escapes all
- // non-ASCII characters
+ } else if (!this.allowUnicode || !StreamReader.isPrintable(ch)) {
+ // if !allowUnicode or the character is not printable, we must encode it
if (ch <= '\u00FF') {
String s = "0" + Integer.toString(ch, 16);
data = "\\x" + s.substring(s.length() - 2);
+ } else if (ch >= '\uD800' && ch <= '\uDBFF') {
+ if (end + 1 < text.length()) {
+ Character ch2 = text.charAt(++end);
+ String s = "000" + Long.toHexString(Character.toCodePoint(ch, ch2));
+ data = "\\U" + s.substring(s.length() - 8) ;
+ } else {
+ String s = "000" + Integer.toString(ch, 16);
+ data = "\\u" + s.substring(s.length() - 4);
+ }
} else {
String s = "000" + Integer.toString(ch, 16);
data = "\\u" + s.substring(s.length() - 4);
diff -r 9126dde66e63 src/main/java/org/yaml/snakeyaml/reader/StreamReader.java
--- a/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java Wed Sep 05 20:14:52 2012 +0200
+++ b/src/main/java/org/yaml/snakeyaml/reader/StreamReader.java Sat Sep 29 10:19:20 2012 -0500
@@ -85,9 +85,7 @@
for (int i = begin; i < end; i++) {
final char c = chars[i];
- if ((c >= '\u0020' && c <= '\u007E') || c == '\n' || c == '\r' || c == '\t'
- || c == '\u0085' || (c >= '\u00A0' && c <= '\uD7FF')
- || (c >= '\uE000' && c <= '\uFFFD')) {
+ if (isPrintable(c)) {
continue;
}
@@ -96,6 +94,12 @@
}
}
+ public static boolean isPrintable(final char c) {
+ return (c >= '\u0020' && c <= '\u007E') || c == '\n' || c == '\r' || c == '\t'
+ || c == '\u0085' || (c >= '\u00A0' && c <= '\uD7FF')
+ || (c >= '\uE000' && c <= '\uFFFD');
+ }
+
public Mark getMark() {
return new Mark(name, this.index, this.line, this.column, this.buffer, this.pointer);
}
diff -r 9126dde66e63 src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java
--- a/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java Wed Sep 05 20:14:52 2012 +0200
+++ b/src/test/java/org/yaml/snakeyaml/emitter/EmitterTest.java Sat Sep 29 10:19:20 2012 -0500
@@ -15,6 +15,8 @@
*/
package org.yaml.snakeyaml.emitter;
+import java.io.IOException;
+import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -23,6 +25,10 @@
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.DumperOptions.ScalarStyle;
import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.events.DocumentStartEvent;
+import org.yaml.snakeyaml.events.ImplicitTuple;
+import org.yaml.snakeyaml.events.ScalarEvent;
+import org.yaml.snakeyaml.events.StreamStartEvent;
public class EmitterTest extends TestCase {
@@ -106,4 +112,19 @@
String etalon = "\"aaa\": \"0123456789 0123456789\\n0123456789 0123456789\"\n\"bbb\": \"\\nbla-bla\"\n";
assertEquals(etalon, output);
}
+
+ // Issue #158
+ public void testWriteSupplementaryUnicode() throws IOException {
+ DumperOptions options = new DumperOptions();
+ String burger = new String(Character.toChars(0x1f354));
+ String halfBurger = "\uD83C";
+ StringWriter output = new StringWriter();
+ Emitter emitter = new Emitter(output, options);
+
+ emitter.emit(new StreamStartEvent(null, null));
+ emitter.emit(new DocumentStartEvent(null, null, false, null, null));
+ emitter.emit(new ScalarEvent(null, null, new ImplicitTuple(true, false), burger + halfBurger, null, null, '"'));
+ String expected = "! \"\\U0001f354\\ud83c\"";
+ assertEquals(expected, output.toString());
+ }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment