Skip to content

Commit 2faf39a

Browse files
important optimiz...
1 parent 3fd9d39 commit 2faf39a

File tree

6 files changed

+167
-70
lines changed

6 files changed

+167
-70
lines changed

SerialX-core/src/main/java/org/ugp/serialx/Utils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,26 @@ public static boolean contains(CharSequence str, char... oneOf)
770770
return false;
771771
}
772772

773+
/**
774+
* @param str | Source string to compare.
775+
* @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work!
776+
* @param from | The beginning index, where to start with comprising (inclusive, most likely 0).
777+
* @param to | The ending marking index, index where to end the comparing (exclusive, most likely <code>str.length()</code>)
778+
*
779+
* @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!<br>
780+
* Note that this function was designed for non-blank ASCII strings and may not work properly for others...<br>
781+
* Also sufficient length of both strings is not checked so adjust from and to accordingly.
782+
*
783+
* @since 1.3.7
784+
*/
785+
public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to)
786+
{
787+
for (; from < to; from++)
788+
if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from))
789+
return false;
790+
return true;
791+
}
792+
773793
/**
774794
* @param str | String to display!
775795
* @param pos | Position to display!

SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package org.ugp.serialx.converters;
22

3+
import static java.lang.Boolean.*;
4+
import static org.ugp.serialx.Utils.equalsLowerCase;
5+
36
/**
47
* This converter is capable of converting {@link String}.
58
* Its case insensitive!
@@ -19,19 +22,19 @@
1922
</tr>
2023
<tr>
2124
<td>true</td>
22-
<td>new Boolean(true)</td>
25+
<td>Boolean.TRUE</td>
2326
</tr>
2427
<tr>
2528
<td>t</td>
26-
<td>new Boolean(true)</td>
29+
<td>Boolean.TRUE</td>
2730
</tr>
2831
<tr>
2932
<td>false</td>
30-
<td>new Boolean(false)</td>
33+
<td>Boolean.FALSE</td>
3134
</tr>
3235
<tr>
3336
<td>f</td>
34-
<td>new Boolean(false)</td>
37+
<td>Boolean.FALSE</td>
3538
</tr>
3639
</table>
3740
@@ -54,12 +57,16 @@ public BooleanConverter(boolean shorten)
5457
}
5558

5659
@Override
57-
public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args)
60+
public Object parse(ParserRegistry myHomeRegistry, String str, Object... args)
5861
{
59-
if (arg.equalsIgnoreCase("T") || arg.equalsIgnoreCase("true"))
60-
return new Boolean(true);
61-
if (arg.equalsIgnoreCase("F") || arg.equalsIgnoreCase("false"))
62-
return new Boolean(false);
62+
int len, ch0;
63+
if ((len = str.length()) > 0)
64+
{
65+
if ((ch0 = str.charAt(0) | ' ') == 't' && (len == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4)))
66+
return TRUE;
67+
if (ch0 == 'f' && (len == 1 || len == 5 && equalsLowerCase(str, "false", 1, 5)))
68+
return FALSE;
69+
}
6370
return CONTINUE;
6471
}
6572

SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.ugp.serialx.converters;
22

3-
import static org.ugp.serialx.Utils.fastReplace;
4-
53
/**
64
* This converter is capable of converting {@link Character}.
75
* Its case sensitive!
@@ -38,16 +36,17 @@ public class CharacterConverter implements DataConverter
3836
@Override
3937
public Object parse(ParserRegistry myHomeRegistry, String str, Object... args)
4038
{
41-
if (str.length() > 1 && str.charAt(0) == '\'' && str.charAt(str.length()-1) == '\'')
39+
int len;
40+
if ((len = str.length()) > 1 && str.charAt(0) == '\'' && str.charAt(--len) == '\'')
4241
try
4342
{
44-
if (str.equals("''")) // TODO: str.length() == 2 + mby cache len
45-
return new Character(' ');
46-
return new Character((char) Integer.parseInt(str = fastReplace(str, "'", "")));
43+
if (len == 1) // str == "''"
44+
return ' ';
45+
return (char) Integer.parseInt(str.substring(1, len));
4746
}
4847
catch (Exception e)
4948
{
50-
return new Character(str.charAt(0));
49+
return str.charAt(0);
5150
}
5251
return CONTINUE;
5352
}

SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.ugp.serialx.converters;
22

3+
import static org.ugp.serialx.Utils.equalsLowerCase;
4+
35
/**
46
* This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}.
57
* Its case insensitive!
@@ -19,7 +21,7 @@
1921
</tr>
2022
<tr>
2123
<td>null</td>
22-
<td>null (object)</td>
24+
<td>null</td>
2325
</tr>
2426
<tr>
2527
<td>void</td>
@@ -36,10 +38,13 @@ public class NullConverter implements DataConverter
3638
@Override
3739
public Object parse(ParserRegistry registry, String str, Object... args)
3840
{
39-
if (str.equalsIgnoreCase("null"))
40-
return null;
41-
if (str.equalsIgnoreCase("void"))
42-
return VOID;
41+
if (str.length() == 4)
42+
{
43+
if (equalsLowerCase(str, "null", 0, 4))
44+
return null;
45+
if (equalsLowerCase(str, "void", 0, 4))
46+
return VOID;
47+
}
4348
return CONTINUE;
4449
}
4550

SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java

Lines changed: 104 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import java.text.DecimalFormatSymbols;
88
import java.util.Locale;
99

10-
import org.ugp.serialx.LogProvider;
11-
1210
/**
1311
* This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java!
1412
* Its case insensitive!
@@ -66,6 +64,8 @@ <td>new Integer(255)</td>
6664
<td>new Integer(15)</td>
6765
</tr>
6866
</table>
67+
*
68+
* @see NumberConverter#numberOf(CharSequence, char, int, int)
6969
*
7070
* @author PETO
7171
*
@@ -89,47 +89,15 @@ public class NumberConverter implements DataConverter
8989
@Override
9090
public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args)
9191
{
92-
if (arg.length() > 0)
92+
int len;
93+
if ((len = arg.length()) > 0)
9394
{
94-
char ch = arg.charAt(0);
95-
if (ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9'))
95+
char ch0 = arg.charAt(0);
96+
if (ch0 == '+' || ch0 == '-' || ch0 == '.' || (ch0 >= '0' && ch0 <= '9'))
9697
{
97-
arg = normFormatNum(arg.toLowerCase());
98-
ch = arg.charAt(arg.length()-1); //ch = last char
99-
100-
if (ch == '.')
101-
return CONTINUE;
102-
if (contains(arg, '.') || (!arg.startsWith("0x") && ch == 'f' || ch == 'd'))
103-
{
104-
if (ch == 'f')
105-
return new Float(fastReplace(arg, "f", ""));
106-
return new Double(fastReplace(arg, "d", ""));
107-
}
108-
109-
try
110-
{
111-
// TODO: Use decode method instead of this mess if possible...
112-
if (ch == 'l')
113-
return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10));
114-
if (ch == 's')
115-
return new Short(Short.parseShort(fastReplace(fastReplace(fastReplace(arg, "s", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10));
116-
if (ch == 'y')
117-
return new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10));
118-
return new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10));
119-
}
120-
catch (NumberFormatException e)
121-
{
122-
if (arg.matches("[0-9.]+"))
123-
try
124-
{
125-
return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10));
126-
}
127-
catch (NumberFormatException e2)
128-
{
129-
LogProvider.instance.logErr("Number " + arg + " is too big for its datatype! Try to change its datatype to double (suffix D)!", e2);
130-
return null;
131-
}
132-
}
98+
Number num;
99+
if ((num = numberOf(arg, ch0, --len, 10, 0)) != null)
100+
return num;
133101
}
134102
}
135103
return CONTINUE;
@@ -174,6 +142,101 @@ public String format(Number num)
174142
return num.toString();
175143
}
176144

145+
/**
146+
* @param str | Source char sequence with number to parse.
147+
* @param ch0 | Should be <code>str.charAt(0)</code>. This is to ensure that string is not null or empty and also for possible optimizations.
148+
* @param end | Index of where to end with parsing. If whole string is meant to be parsed, then <code>str.length()-1</code>, should not be greater than that!
149+
* @param base | Base of the parsed number. Theoretically can be anything but usually should be 2, 8, 10 or 16... Note that base will be overridden by suffixes <code>#</code>. for 16, <code>0x</code> for 16, <code>0b</code> for 2 or <code>0</code> for 8 (only if not followed by <code>.</code>).
150+
* @param type | Preferred datatype of of the number represented by suffixes 'S' for {@link Short}, 'Y' for {@link Byte}, 'L' for {@link Long}, 'D' for {@link Double}, 'F' for {@link Float}. Other stands for {@link Integer}.<br>
151+
* Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!<br>
152+
* Important thing to know is that this argument will be overridden by suffix from str if present!
153+
*
154+
* @return
155+
*
156+
* @since 1.3.7
157+
*/
158+
public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) //TODO
159+
{
160+
int start = 0;
161+
162+
if (ch0 == '#') //Determine base
163+
{
164+
base = 16;
165+
start++;
166+
}
167+
else if (ch0 == '0' && end > 0)
168+
{
169+
int ch1 = str.charAt(1) | ' ';
170+
if (ch1 == 'b')
171+
{
172+
base = 2;
173+
start++;
174+
}
175+
else if (ch1 == 'x')
176+
{
177+
base = 16;
178+
start++;
179+
}
180+
else if (ch1 != '.')
181+
base = 8;
182+
183+
start++;
184+
}
185+
186+
double result = 0, baseCof = 1, exponent = 1;
187+
int chEnd = str.charAt(end--) | ' '; //Determine data type
188+
if (base == 10 ? chEnd >= 'd' : chEnd >= 'l')
189+
type = chEnd;
190+
else if (chEnd == '.')
191+
type = 'd';
192+
else
193+
{
194+
result = chEnd > '9' ? chEnd - 'a' + 10 : chEnd - '0';
195+
baseCof = base;
196+
}
197+
198+
for (int ch; end >= start; end--) //Parsing
199+
{
200+
if ((ch = str.charAt(end)) == '-') // Neg
201+
result = -result;
202+
else if (ch == '.') //Decimal
203+
{
204+
result /= baseCof;
205+
baseCof = 1;
206+
if (type == 0)
207+
type = 'd';
208+
}
209+
else if ((ch |= ' ') == 'e' && base == 10) //Handle E-notation
210+
{
211+
if ((exponent = Math.pow(base, result)) < 1 && type == 0)
212+
type = 'd';
213+
result = 0;
214+
baseCof = 1;
215+
}
216+
else if (ch == ' ') //Not valid
217+
return null;
218+
else if (ch != 127 && ch != '+')
219+
{
220+
result += (ch > '9' ? ch - 'a' + 10 : ch - '0') * baseCof;
221+
baseCof *= base;
222+
}
223+
}
224+
225+
result *= exponent;
226+
227+
if (type == 'd')
228+
return result;
229+
if (type == 'f')
230+
return (float) result;
231+
if (type == 'l' || result > 0x7fffffff || result < 0x80000000)
232+
return (long) result;
233+
if (type == 's')
234+
return (short) result;
235+
if (type == 'y')
236+
return (byte) result;
237+
return (int) result;
238+
}
239+
177240
/**
178241
* @param num | Number string to format!
179242
*

SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ public class StringConverter implements DataConverter
4343
*/
4444
public static boolean serializeStringNormally = true;
4545

46+
@Override
47+
public String parse(ParserRegistry myHomeRegistry, String str, Object... args)
48+
{
49+
int len;
50+
if ((len = str.length()) > 1 && str.charAt(0) == '\"' && str.charAt(--len) == '\"' && indexOfNotInObj(str, ' ') == -1)
51+
{
52+
return str.substring(1, len);
53+
}
54+
return CONTINUE;
55+
}
56+
4657
@Override
4758
public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args)
4859
{
@@ -67,14 +78,6 @@ else if (serializeStringNormally)
6778
return CONTINUE;
6879
}
6980

70-
@Override
71-
public Object parse(ParserRegistry myHomeRegistry, String str, Object... args)
72-
{
73-
if (str.length() > 1 && str.charAt(0) == '\"' && str.charAt(str.length()-1) == '\"' && indexOfNotInObj(str, ' ') == -1)
74-
return str.substring(1, str.length() - 1);
75-
return CONTINUE;
76-
}
77-
7881
@Override
7982
public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert)
8083
{

0 commit comments

Comments
 (0)