]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils/src/org/simantics/utils/strings/EString.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.utils / src / org / simantics / utils / strings / EString.java
diff --git a/bundles/org.simantics.utils/src/org/simantics/utils/strings/EString.java b/bundles/org.simantics.utils/src/org/simantics/utils/strings/EString.java
new file mode 100644 (file)
index 0000000..28f49df
--- /dev/null
@@ -0,0 +1,521 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+/*\r
+ * Created on Jan 21, 2005\r
+ * \r
+ * Copyright Toni Kalajainen\r
+ * \r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *     http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package org.simantics.utils.strings;\r
+\r
+import java.io.IOException;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.List;\r
+import java.util.regex.Matcher;\r
+import java.util.regex.Pattern;\r
+import java.util.regex.PatternSyntaxException;\r
+\r
+import org.simantics.databoard.parser.StringEscapeUtils;\r
+import org.simantics.utils.bytes.ByteArrays;\r
+\r
+\r
+/**\r
+ * Extended string functions\r
+ * Byte array <-> string conversions\r
+ *\r
+ *  Length is not included\r
+ *\r
+ *\r
+ * See also {@link StringEscapeUtils}\r
+ * @author Toni Kalajainen\r
+ */\r
+public class EString {\r
+\r
+    public static final char[] HEX_VALUES =\r
+    {'0', '1', '2', '3' ,'4' ,'5', '6', '7', '8', '9' ,'A', 'B', 'C',\r
+        'D', 'E', 'F'};\r
+\r
+\r
+    /**\r
+     * convert string to byte array\r
+     * @param s\r
+     * @return\r
+     */\r
+    public static byte[] toBytes(String s) {\r
+        int size = s.length();\r
+        byte array[] = new byte[size];\r
+        // write chars\r
+        for (int i=0; i<size; i++)\r
+            array[i] = (byte) (s.charAt(i) );\r
+        return array;\r
+    }\r
+\r
+    /**\r
+     * convert bytearray to string\r
+     * @param array\r
+     * @return\r
+     */\r
+    public static String toString(byte array[]) {\r
+        if (array==null) return null;\r
+        int size = array.length;\r
+        if (size==0) return null;\r
+        // read chars\r
+        //return new String(array, 4, size);\r
+        char chars[] = new char[size];\r
+        for (int i=0; i<size; i++)\r
+            chars[i] = (char) (array[i] & 0xff);\r
+        return new String(chars);\r
+    }\r
+\r
+    /**\r
+     * read null terminated string\r
+     * @param array\r
+     * @param offset start offset\r
+     * @return\r
+     */\r
+    public static String PChar(byte array[], int offset) {\r
+        if (array==null) return null;\r
+        int size = array.length;\r
+        int zero = offset;\r
+        while (zero<size && array[zero]!=0) zero++;\r
+        if (zero>=size) throw new IndexOutOfBoundsException();\r
+        char chars[] = new char[zero-offset];\r
+        for (int i=0; i<chars.length; i++)\r
+            chars[i] = (char) (array[i+offset] & 0xff);\r
+        return new String(chars);\r
+    }\r
+\r
+    /**\r
+     * read null terminated string\r
+     * @param array\r
+     * @param offset start offset\r
+     * @param maxLen maximum bytes to read\r
+     * @return\r
+     */\r
+    public static String PChar(byte array[], int offset, int maxLen) {\r
+        if (array==null) return null;\r
+        int size = array.length;\r
+        if (offset+maxLen<size) size = offset+maxLen;\r
+        int zero = offset;\r
+        while (zero<size && array[zero]!=0) zero++;\r
+        if (zero>=size) throw new IndexOutOfBoundsException();\r
+        char chars[] = new char[zero-offset];\r
+        for (int i=0; i<chars.length; i++)\r
+            chars[i] = (char) (array[i+offset] & 0xff);\r
+        return new String(chars);\r
+    }\r
+\r
+    /**\r
+     * Explode words into array\r
+     * @param str\r
+     * @param breaker\r
+     * @return\r
+     */\r
+    public static String[] explode(String str, String breaker) {\r
+        return str.split(breaker);\r
+    }\r
+    /**\r
+     * Explode string into lines\r
+     * @param str\r
+     * @return\r
+     */\r
+    public static String[] explode(String str) {\r
+        return str.split("\n");\r
+    }\r
+    /**\r
+     * implode array into string\r
+     * @param strings\r
+     * @param glue\r
+     * @return\r
+     */\r
+    public static String implode(Object strings[], String glue) {\r
+        if (strings.length==0) return null;\r
+        if (strings.length == 1)\r
+            return strings[0].toString();\r
+        StringBuilder sb = new StringBuilder();\r
+        sb.append(strings[0].toString());\r
+        for (int i=1; i<strings.length; i++) {\r
+            sb.append(glue);\r
+            sb.append(strings[i]);\r
+        }\r
+        return sb.toString();\r
+    }\r
+    public static String implode(Collection<?> strings) {\r
+        return implode(strings.toArray(new Object[strings.size()]));\r
+    }\r
+    public static String implode(Collection<?> strings, String glue) {\r
+        return implode(strings.toArray(new Object[strings.size()]), glue);\r
+    }\r
+    /**\r
+     * implode lines into array\r
+     * @param strings\r
+     * @return\r
+     */\r
+    public static String implode(Object strings[]) {\r
+        if (strings.length==0) return "";\r
+\r
+        String s0 = strings[0].toString();\r
+        int s0len = s0.length();\r
+        int len = s0len;\r
+        for (int i=1; i<strings.length; i++)\r
+            len += 1+strings[i].toString().length();\r
+\r
+        char data[] = new char[len];\r
+        s0.getChars(0, s0.length(), data, 0);\r
+        int pos = s0len;\r
+\r
+        for (int i=1; i<strings.length; i++) {\r
+            data[pos] = '\n';\r
+            String si = strings[i].toString();\r
+            int silen = si.length();\r
+            si.getChars(0, silen, data, pos+1);\r
+            pos += 1+silen;\r
+        }\r
+\r
+        return new String(data);\r
+    }\r
+\r
+    /**\r
+     * Add prefix to stings in array\r
+     * @param strings\r
+     * @param prefix\r
+     * @return\r
+     */\r
+    public static String[] addPrefix(String strings[], String prefix) {\r
+        String result[] = new String[strings.length];\r
+        for (int i=0; i<result.length; i++)\r
+            result[i] = prefix + strings[i];\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * add prefix to lines\r
+     * @param strings\r
+     * @param prefix\r
+     * @return\r
+     */\r
+    public static String addPrefix(String strings, String prefix) {\r
+        String result[] = explode(strings);\r
+        for (int i=0; i<result.length; i++)\r
+            result[i] = prefix + result[i];\r
+        return implode(result);\r
+    }\r
+\r
+    /**\r
+     * add prefix and suffix to lines\r
+     * @param strings\r
+     * @param prefix\r
+     * @param suffixfix\r
+     * @return\r
+     */\r
+    public static String addFix(String strings, String prefix, String suffix) {\r
+        String result[] = explode(strings);\r
+        for (int i=0; i<result.length; i++)\r
+            result[i] = prefix + result[i] + suffix;\r
+        return implode(result);\r
+    }\r
+\r
+    /**\r
+     * Big Endian hex\r
+     * @param value\r
+     * @param decimals\r
+     * @return\r
+     */\r
+    public static String intToBEHex(int value, int decimals) {\r
+       // TODO Replace with String.format("%0"+decimals+"X", value)\r
+        String result="";\r
+        for (int i=0; i<decimals; i++) {\r
+            result += EString.HEX_VALUES[(value>>4) & 0xF];\r
+            result += EString.HEX_VALUES[value & 0xF];\r
+            value = value >> 8;\r
+        }\r
+        return result;\r
+    }\r
+\r
+    /**\r
+     * splits line in a manner that is done to word wrap\r
+     * Lines are broken between spaces if possible\r
+     */\r
+    public static String wordWrap(String text, int minWidth, int maxWidth)\r
+    {\r
+        // init values\r
+        char cr = 0x0D;\r
+        String lines[] = text.replaceAll(""+cr, "").split("\n");\r
+        List<String> result = new ArrayList<String>();\r
+\r
+        // iterate lines\r
+        for (int i=0; i<lines.length; i++) {\r
+            String line = lines[i];\r
+\r
+            if (line.length() < maxWidth) {\r
+                result.add(line);\r
+                continue;\r
+            }\r
+\r
+            // Line is longer than maxwidth, split it\r
+            String words[] = lines[i].split(" ");\r
+            line = "";\r
+            for (int j=0; j<words.length; j++) {\r
+                // Nothing on the buffer\r
+                if (line.equals("")) {\r
+                    line = words[j];\r
+                    while (line.length() > maxWidth) {\r
+                        result.add(line.substring(0, maxWidth));\r
+                        line = line.substring(maxWidth);\r
+                    }\r
+                    continue;\r
+                }\r
+\r
+                // Add to previous line buffer\r
+                String word = words[j];\r
+\r
+                // Check if adding this word fits maxwidth\r
+                if (line.length()+1+word.length()<maxWidth) {\r
+                    line = line + " " + word;\r
+                    continue;\r
+                }\r
+                // Adding this word would make the line too long\r
+\r
+                // Check if this line is long enough\r
+                if (line.length()>=minWidth) {\r
+                    result.add(line);\r
+                    line = word;\r
+                    continue;\r
+                }\r
+                // Line is not long enough with out AWord and with it\r
+                // the line is too long.\r
+\r
+                // So we need to split the line\r
+                line = line + " " + word;\r
+                while (line.length()>maxWidth) {\r
+                    result.add(line.substring(0, maxWidth));\r
+                    line = line.substring(maxWidth);\r
+                }\r
+            }\r
+            if (!line.equals(""))\r
+                result.add(line);\r
+        }\r
+\r
+        // Change string lines into single string\r
+        StringBuilder sb = new StringBuilder();\r
+        int rs = result.size();\r
+        if (rs > 0) {\r
+            sb.append(result.get(0));\r
+            for (int i=1; i<rs; i++)\r
+                sb.append("\n").append(result.get(i));\r
+        }\r
+        return sb.length() == 0 ? "" : sb.toString();\r
+    }\r
+\r
+\r
+    public static void printByteArray(byte array[]) {\r
+        for (int i=0; i<array.length; i++) {\r
+            System.out.print(array[i] & 0xff);\r
+            if (i<array.length-1)\r
+                System.out.print(",");\r
+        }\r
+    }\r
+\r
+    public static void saveToFile(String text, String filename)\r
+    throws IOException\r
+    {\r
+        ByteArrays.saveToFile(toBytes(text), filename);\r
+    }\r
+\r
+    /**\r
+     * Escape characters in a string.\r
+     * <p>\r
+     * eg. value=5,5 will be escaped to value\=5\,5\r
+     * with escape set =, and escape char \\r
+     * \r
+     * @param str string to escape\r
+     * @param escapeSet set of chars\r
+     * @param escapeChar escape character\r
+     * @return escaped string\r
+     */\r
+    public static String escapeString(String str, String escapeSet, char escapeChar)\r
+    {\r
+        escapeSet += escapeChar;\r
+        StringBuilder sb = new StringBuilder(str.length()*2);\r
+        for (int i=0; i<str.length(); i++)\r
+        {\r
+            char c = str.charAt(i);\r
+\r
+            for (int j=0; j<escapeSet.length(); j++)\r
+            {\r
+                char ec = escapeSet.charAt(j);\r
+                if (ec==c) {\r
+                    sb.append(escapeChar);\r
+                    break;\r
+                }\r
+            }\r
+\r
+            sb.append(c);\r
+        }\r
+\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Unescape charaters in a string\r
+     * <p>\r
+     * eg. value\=5\,5 will be unescaped to value=5,5 with\r
+     * escape set =, and escape char \\r
+     * \r
+     * @param str string to unescape\r
+     * @param escapeChar\r
+     * @return unescaped string\r
+     */\r
+    public static String unescapeString(String str, char escapeChar)\r
+    {\r
+        StringBuilder sb = new StringBuilder(str.length());\r
+        boolean prevWasEscapeChar = false;\r
+        for (int i=0; i<str.length(); i++)\r
+        {\r
+            char c = str.charAt(i);\r
+\r
+            // Atmost escape every second character\r
+            if (prevWasEscapeChar || (c != escapeChar)) {\r
+                prevWasEscapeChar = false;\r
+                sb.append(c);\r
+            } else {\r
+                prevWasEscapeChar = true;\r
+            }\r
+        }\r
+\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Scans escaped string\r
+     * e.g. key=val\,ue,key2=xx returns key=val\,ue with endMark ,\r
+     * \r
+     * @param str string to scan\r
+     * @param escapeChar escape character\r
+     * @param endMark end mark\r
+     * @return everything before endMark\r
+     */\r
+    public static String scanEscapedString(String str, char escapeChar, char endMark)\r
+    {\r
+        StringBuilder sb = new StringBuilder(str.length());\r
+        boolean prevWasEscapeChar = false;\r
+        for (int i=0; i<str.length(); i++)\r
+        {\r
+            char c = str.charAt(i);\r
+\r
+            // Atmost escape every second character\r
+            if (prevWasEscapeChar || (c != escapeChar)) {\r
+                if (!prevWasEscapeChar && c==endMark)\r
+                    return sb.toString();\r
+                // the next char won't be escape char\r
+                prevWasEscapeChar = false;\r
+            } else {\r
+                // This is escape char\r
+                prevWasEscapeChar = true;\r
+            }\r
+            sb.append(c);\r
+        }\r
+\r
+        return sb.toString();\r
+    }\r
+\r
+    /**\r
+     * Compiles pattern from simple pattern. Simple pattern is normal\r
+     * wild card compare that supports * and ? wild cards.\r
+     * \r
+     * @param patternStr simple pattern\r
+     * @return Regexp pattern\r
+     */\r
+    public static Pattern compileSimplePattern(String patternStr)\r
+    throws PatternSyntaxException\r
+    {\r
+        String str ="";\r
+        for (int i=0; i<patternStr.length(); i++)\r
+        {\r
+            char c = patternStr.charAt(i);\r
+            if ( (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9'))\r
+                str += c;\r
+            else if ( c=='?' )\r
+                str += ".?";\r
+            else if ( c=='*' )\r
+                str += ".*";\r
+            else str += "\\"+c;\r
+        }\r
+        return Pattern.compile(str);\r
+    }\r
+\r
+    public static boolean simplePatternMatch(String str, String simplePattern)\r
+    {\r
+        try {\r
+            Pattern ptr = compileSimplePattern(simplePattern);\r
+            Matcher m = ptr.matcher(str);\r
+            return m.matches();\r
+        } catch (PatternSyntaxException pse) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    public static void main(String[] args) {\r
+        System.out.println(escapeString("value=5,\\5", ",=", '\\'));\r
+        System.out.println(unescapeString("value\\=5\\,\\\\5", '\\'));\r
+        System.out.println(scanEscapedString("val\\,ue\\=5\\,\\\\5,value2=xxx", '\\', ','));\r
+        System.out.println(scanEscapedString("\\,\\,,\\,\\,", '\\', ','));\r
+\r
+        String value = "STRING 01234"+(char)(128)+(char)(129)+(char)(255);\r
+\r
+        int X = 500;\r
+        System.out.println(X+" = "+intToBEHex(X, 4));\r
+\r
+        byte array[] = toBytes(value);\r
+        System.out.print(value);\r
+        System.out.print(" = ");\r
+        printByteArray(array);\r
+        System.out.println();\r
+\r
+        @SuppressWarnings("unused")\r
+        String str = toString(array);\r
+        System.out.print(value);\r
+        System.out.print(" = ");\r
+        printByteArray(array);\r
+        System.out.println();\r
+\r
+        String text = "Reads b.length bytes from this file into the "+\r
+        "byte array, starting at the current file pointer. This method"+\r
+        " reads repeatedly from the file until the requested number of "+\r
+        "bytes are read. This method blocks until the requested number of "+\r
+        "bytes are read, the end of the stream is detected, or an exception "+\r
+        "is thrown";\r
+        text = wordWrap(text, 20, 30);\r
+        System.out.println(text);\r
+\r
+\r
+        List<String> v = new ArrayList<String>();\r
+        v.add("jeps");\r
+        v.add("jops");\r
+        v.add("kops");\r
+        v.add("hops");\r
+        System.out.println(implode(v));\r
+    }\r
+\r
+\r
+}\r