]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / markdown / internal / HtmlEscape.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/markdown/internal/HtmlEscape.java
new file mode 100644 (file)
index 0000000..a31c706
--- /dev/null
@@ -0,0 +1,83 @@
+package org.simantics.scl.compiler.markdown.internal;
+
+import gnu.trove.map.hash.TCharObjectHashMap;
+
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+
+public class HtmlEscape {
+
+    private static final Charset UTF8 = Charset.forName("UTF-8");
+    
+    private static final TCharObjectHashMap<String> ESCAPED_CHARS = new TCharObjectHashMap<String>();
+    static {
+        ESCAPED_CHARS.put('<', "&lt;");
+        ESCAPED_CHARS.put('>', "&gt;");
+        ESCAPED_CHARS.put('"', "&quot;");
+        ESCAPED_CHARS.put('&', "&amp;");
+    }
+    
+    public static CharSequence escape(CharSequence text) {
+        int length = text.length();
+        for(int i=0;i<length;++i) {
+            char c = text.charAt(i);
+            String esc = ESCAPED_CHARS.get(c);
+            if(esc != null) {
+                StringBuilder b = new StringBuilder(length+16);
+                b.append(text, 0, i);
+                b.append(esc);
+                for(++i;i<length;++i) {
+                    c = text.charAt(i);
+                    esc = ESCAPED_CHARS.get(c);
+                    if(esc != null)
+                        b.append(esc);
+                    else
+                        b.append(c);
+                }
+                return b.toString();
+            }
+        }
+        return text;
+    }       
+    
+    public static StringBuilder escapeURL(CharSequence str) {
+        StringBuilder result = new StringBuilder();
+        for(int i=0;i<str.length();++i) {
+            char c = str.charAt(i);
+            if(c < 0 || c >= 128) {
+                ByteBuffer bs = UTF8.encode(CharBuffer.wrap(new char[] {c}));
+                for(int j=0;j<bs.limit();++j)
+                    result.append(percentEncode(bs.get()));
+            }
+            else if(URL_CAN_CONTAIN[(int)c])
+                result.append(c);
+            else if(c == '&')
+                result.append("&amp;");
+            else
+                result.append(percentEncode(c));
+        }
+        return result;
+    }
+    
+    private static String percentEncode(int c) {
+        if(c < 0)
+            c += 256;
+        String hex = Integer.toHexString(c).toUpperCase();
+        if(hex.length() == 1)
+            return "%0" + hex;
+        else
+            return "%" + hex;
+    }
+    
+    private static final boolean[] URL_CAN_CONTAIN = new boolean[] {
+        false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false,
+        false, true, false, true, true, true, false, false, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, true,
+        true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, true,
+        false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true,
+        true, true, true, true, true, true, true, true, true, true, true, false, false, false, false, false,
+    };
+}