Created
September 27, 2012 20:44
-
-
Save headius/3796362 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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