Big update to custom expression feature.
[debian/openrocket] / core / src / net / sf / openrocket / util / TextUtil.java
1 package net.sf.openrocket.util;
2
3 import java.nio.ByteBuffer;
4 import java.nio.charset.Charset;
5
6
7 public class TextUtil {
8
9         
10         private static final char[] HEX = {
11                         '0', '1', '2', '3', '4', '5', '6', '7',
12                         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
13         };
14
15         /**
16          * Return the byte array for the string in the given charset.
17          * 
18          * This function is implemented because Froyo (Android API 8) does not support
19          * String.getBytes(Charset)
20          * 
21          * @param string
22          * @param charSet
23          * @return
24          */
25         public static byte[] convertStringToBytes( String string, Charset charSet ) {
26                 ByteBuffer encoded = charSet.encode(string);
27                 return encoded.array();
28         }
29
30         
31         /**
32          * Return the bytes formatted as a hexadecimal string.  The length of the
33          * string will be twice the number of bytes, with no spacing between the bytes
34          * and lowercase letters utilized.
35          * 
36          * @param bytes         the bytes to convert.
37          * @return                      the bytes in hexadecimal notation.
38          */
39         public static final String hexString(byte[] bytes) {
40                 StringBuilder sb = new StringBuilder(bytes.length * 2);
41                 for (byte b : bytes) {
42                         sb.append(HEX[(b >>> 4) & 0xF]);
43                         sb.append(HEX[b & 0xF]);
44                 }
45                 return sb.toString();
46         }
47         
48         /**
49          * Return a string of the double value with suitable precision (5 digits).
50          * The string is the shortest representation of the value including the
51          * required precision.
52          * 
53          * @param d             the value to present.
54          * @return              a representation with suitable precision.
55          */
56         public static final String doubleToString(double d) {
57                 
58                 // Check for special cases
59                 if (MathUtil.equals(d, 0))
60                         return "0";
61                 
62                 if (Double.isNaN(d))
63                         return "NaN";
64                 
65                 if (Double.isInfinite(d)) {
66                         if (d < 0)
67                                 return "-Inf";
68                         else
69                                 return "Inf";
70                 }
71                 
72
73                 final String sign = (d < 0) ? "-" : "";
74                 double abs = Math.abs(d);
75                 
76                 // Small and large values always in exponential notation
77                 if (abs < 0.001 || abs >= 100000000) {
78                         return sign + exponentialFormat(abs);
79                 }
80                 
81                 // Check whether decimal or exponential notation is shorter
82                 
83                 String exp = exponentialFormat(abs);
84                 String dec = decimalFormat(abs);
85                 
86                 if (dec.length() <= exp.length())
87                         return sign + dec;
88                 else
89                         return sign + exp;
90         }
91         
92         
93         /*
94          * value must be positive and not zero!
95          */
96         private static String exponentialFormat(double value) {
97                 int exp;
98                 
99                 exp = 0;
100                 while (value < 1.0) {
101                         value *= 10;
102                         exp--;
103                 }
104                 while (value >= 10.0) {
105                         value /= 10;
106                         exp++;
107                 }
108                 
109                 return shortDecimal(value, 4) + "e" + exp;
110         }
111         
112         
113         /*
114          * value must be positive and not zero!
115          */
116         private static String decimalFormat(double value) {
117                 if (value >= 10000)
118                         return "" + (int) (value + 0.5);
119                 
120                 int decimals = 1;
121                 double v = value;
122                 while (v < 1000) {
123                         v *= 10;
124                         decimals++;
125                 }
126                 
127                 return shortDecimal(value, decimals);
128         }
129         
130         
131
132
133         /*
134          * value must be positive!
135          */
136         private static String shortDecimal(double value, int decimals) {
137                 
138                 // Calculate rounding and limit values (rounding slightly smaller)
139                 int rounding = 1;
140                 double limit = 0.5;
141                 for (int i = 0; i < decimals; i++) {
142                         rounding *= 10;
143                         limit /= 10;
144                 }
145                 
146                 // Round value
147                 value = (Math.rint(value * rounding) + 0.1) / rounding;
148                 
149
150                 int whole = (int) value;
151                 value -= whole;
152                 
153
154                 if (value < limit)
155                         return "" + whole;
156                 limit *= 10;
157                 
158                 StringBuilder sb = new StringBuilder();
159                 sb.append("" + whole);
160                 sb.append('.');
161                 
162
163                 for (int i = 0; i < decimals; i++) {
164                         
165                         value *= 10;
166                         whole = (int) value;
167                         value -= whole;
168                         sb.append((char) ('0' + whole));
169                         
170                         if (value < limit)
171                                 return sb.toString();
172                         limit *= 10;
173                         
174                 }
175                 
176                 return sb.toString();
177         }
178         
179         
180         public static String htmlEncode(String s) {
181                 s = s.replace("&", "&amp;");
182                 s = s.replace("\"", "&quot;");
183                 s = s.replace("<", "&lt;");
184                 s = s.replace(">", "&gt;");
185                 return s;
186         }
187         
188         /*
189          * Returns a word-wrapped version of given input string using HTML syntax, wrapped to len characters.
190          */
191         public static String wrap(String in,int len) {
192                 in=in.trim();
193                 if(in.length()<len) return in;
194                 if(in.substring(0, len).contains("\n"))
195                         return in.substring(0, in.indexOf("\n")).trim() + "\n\n" + wrap(in.substring(in.indexOf("\n") + 1), len);
196                 int place=Math.max(Math.max(in.lastIndexOf(" ",len),in.lastIndexOf("\t",len)),in.lastIndexOf("-",len));
197                 return "<html>"+in.substring(0,place).trim()+"<br>"+wrap(in.substring(place),len);
198         }
199
200 }