1 /*******************************************************************************
2 * Copyright (c) 2017 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Semantum Oy - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.history.csv;
15 * @author Tuukka Lehtonen
16 * @since 1.30.0, 1.28.1
20 public static String safeUnescape(String uri) {
23 } catch (IllegalArgumentException e) {
28 public static String unescape(String uri) {
30 if (!needsUnescaping(uri))
33 int len = uri.length();
35 char result[] = new char[len];
39 char inCh = unicode.charAt(in++);
40 if (inCh == '%' && in+1 < len) {
41 char d1 = unicode.charAt(in);
42 char d2 = unicode.charAt(in+1);
43 if (d1 > 127 || d2 > 127)
44 throw new IllegalArgumentException("Invalid hex digit escape sequence in " + uri + " at " + in);
45 result[out++] = (char) (hexDecode(d1) * 16 | hexDecode(d2));
51 return new String(result, 0, out);
52 } catch (IllegalArgumentException e) {
53 throw new IllegalArgumentException("Problem while unescaping string: " + uri, e);
54 } catch (IndexOutOfBoundsException ee) {
55 throw new IllegalArgumentException("Incomplete hex digit escape sequence in " + uri);
59 private static boolean needsUnescaping(String s) {
61 for (int i = -1; i < l;) {
62 i = s.indexOf('%', i+1);
66 && isHexDigit(s.charAt(i+1))
67 && isHexDigit(s.charAt(i+2)))
73 private static int hexDecode(char c) {
75 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
76 return ((c) & 255) - 'a' + 10;
77 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
79 case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
82 throw new IllegalArgumentException("Bad Hex escape character: " + ((c)&255) );
86 private static boolean isHexDigit(char c) {
87 return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
90 // public static void main(String[] args) {
91 // System.out.println(unescape("%"));
92 // System.out.println(unescape("%.AI"));
93 // System.out.println(unescape("%6B"));
94 // System.out.println(unescape("%6g"));
95 // System.out.println(unescape("%g5"));
96 // System.out.println(unescape("%f5"));
97 // System.out.println(unescape("%A1"));
98 // System.out.println(unescape("%A"));
99 // System.out.println(unescape("%A."));
100 // System.out.println(unescape("%AI"));