-package org.simantics.datatypes.literal;\r
-\r
-import java.util.UUID;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.util.Bean;\r
-\r
-\r
-public class GUID extends Bean {\r
-\r
- public static final Binding BINDING = Bindings.getBindingUnchecked(GUID.class);\r
-\r
- public long mostSignificant;\r
- public long leastSignificant;\r
- \r
- public GUID(long mostSignificant, long leastSignificant) {\r
- super(BINDING);\r
- this.mostSignificant = mostSignificant;\r
- this.leastSignificant = leastSignificant;\r
- }\r
- \r
- public static GUID invalid() {\r
- return new GUID(0, 0);\r
- }\r
- \r
- public static GUID invalid2() {\r
- return new GUID(0, 1);\r
- }\r
-\r
- public boolean isInvalid() {\r
- return mostSignificant == 0 && leastSignificant == 0;\r
- }\r
-\r
- public static GUID random() {\r
- UUID random = UUID.randomUUID();\r
- return new GUID(random.getMostSignificantBits(), random.getLeastSignificantBits());\r
- }\r
- \r
- public String indexString() {\r
- StringBuilder b = new StringBuilder();\r
- b.append(Long.toHexString(mostSignificant));\r
- b.append("_");\r
- b.append(Long.toHexString(leastSignificant));\r
- return b.toString();\r
- }\r
- \r
- public static GUID parseIndexString(String indexString) {\r
- String[] parts = indexString.split("_");\r
- if(parts.length != 2) throw new IllegalArgumentException();\r
- Long mostSignificant = parseUnsignedLong(parts[0].toUpperCase(), 16);\r
- Long leastSignificant = parseUnsignedLong(parts[1], 16);\r
- return new GUID(mostSignificant, leastSignificant);\r
- }\r
-\r
- /**\r
- * Parses the string argument as an unsigned {@code long} in the\r
- * radix specified by the second argument. An unsigned integer\r
- * maps the values usually associated with negative numbers to\r
- * positive numbers larger than {@code MAX_VALUE}.\r
- *\r
- * The characters in the string must all be digits of the\r
- * specified radix (as determined by whether {@link\r
- * java.lang.Character#digit(char, int)} returns a nonnegative\r
- * value), except that the first character may be an ASCII plus\r
- * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting\r
- * integer value is returned.\r
- *\r
- * <p>An exception of type {@code NumberFormatException} is\r
- * thrown if any of the following situations occurs:\r
- * <ul>\r
- * <li>The first argument is {@code null} or is a string of\r
- * length zero.\r
- *\r
- * <li>The radix is either smaller than\r
- * {@link java.lang.Character#MIN_RADIX} or\r
- * larger than {@link java.lang.Character#MAX_RADIX}.\r
- *\r
- * <li>Any character of the string is not a digit of the specified\r
- * radix, except that the first character may be a plus sign\r
- * {@code '+'} ({@code '\u005Cu002B'}) provided that the\r
- * string is longer than length 1.\r
- *\r
- * <li>The value represented by the string is larger than the\r
- * largest unsigned {@code long}, 2<sup>64</sup>-1.\r
- *\r
- * </ul>\r
- *\r
- *\r
- * @param s the {@code String} containing the unsigned integer\r
- * representation to be parsed\r
- * @param radix the radix to be used while parsing {@code s}.\r
- * @return the unsigned {@code long} represented by the string\r
- * argument in the specified radix.\r
- * @throws NumberFormatException if the {@code String}\r
- * does not contain a parsable {@code long}.\r
- * @since 1.8\r
- */\r
- public static long parseUnsignedLong(String s, int radix)\r
- throws NumberFormatException {\r
- if (s == null) {\r
- throw new NumberFormatException("null");\r
- }\r
-\r
- int len = s.length();\r
- if (len > 0) {\r
- char firstChar = s.charAt(0);\r
- if (firstChar == '-') {\r
- throw new\r
- NumberFormatException(String.format("Illegal leading minus sign " +\r
- "on unsigned string %s.", s));\r
- } else {\r
- if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits\r
- (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits\r
- return Long.parseLong(s, radix);\r
- }\r
-\r
- // No need for range checks on len due to testing above.\r
- long first = Long.parseLong(s.substring(0, len - 1), radix);\r
- int second = Character.digit(s.charAt(len - 1), radix);\r
- if (second < 0) {\r
- throw new NumberFormatException("Bad digit at end of " + s);\r
- }\r
- long result = first * radix + second;\r
- if (compareUnsigned(result, first) < 0) {\r
- /*\r
- * The maximum unsigned value, (2^64)-1, takes at\r
- * most one more digit to represent than the\r
- * maximum signed value, (2^63)-1. Therefore,\r
- * parsing (len - 1) digits will be appropriately\r
- * in-range of the signed parsing. In other\r
- * words, if parsing (len -1) digits overflows\r
- * signed parsing, parsing len digits will\r
- * certainly overflow unsigned parsing.\r
- *\r
- * The compareUnsigned check above catches\r
- * situations where an unsigned overflow occurs\r
- * incorporating the contribution of the final\r
- * digit.\r
- */\r
- throw new NumberFormatException(String.format("String value %s exceeds " +\r
- "range of unsigned long.", s));\r
- }\r
- return result;\r
- }\r
- } else {\r
- throw new NumberFormatException("For input string: \"" + s + "\"");\r
- }\r
- }\r
-\r
- /**\r
- * Compares two {@code long} values numerically treating the values\r
- * as unsigned.\r
- *\r
- * @param x the first {@code long} to compare\r
- * @param y the second {@code long} to compare\r
- * @return the value {@code 0} if {@code x == y}; a value less\r
- * than {@code 0} if {@code x < y} as unsigned values; and\r
- * a value greater than {@code 0} if {@code x > y} as\r
- * unsigned values\r
- * @since 1.8\r
- */\r
- public static int compareUnsigned(long x, long y) {\r
- return Long.compare(x + Long.MIN_VALUE, y + Long.MIN_VALUE);\r
- }\r
- \r
-}\r
+package org.simantics.datatypes.literal;
+
+import java.util.UUID;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.util.Bean;
+
+
+public class GUID extends Bean {
+
+ public static final Binding BINDING = Bindings.getBindingUnchecked(GUID.class);
+
+ public long mostSignificant;
+ public long leastSignificant;
+
+ public GUID(long mostSignificant, long leastSignificant) {
+ super(BINDING);
+ this.mostSignificant = mostSignificant;
+ this.leastSignificant = leastSignificant;
+ }
+
+ public static GUID invalid() {
+ return new GUID(0, 0);
+ }
+
+ public static GUID invalid2() {
+ return new GUID(0, 1);
+ }
+
+ public boolean isInvalid() {
+ return mostSignificant == 0 && leastSignificant == 0;
+ }
+
+ public static GUID random() {
+ UUID random = UUID.randomUUID();
+ return new GUID(random.getMostSignificantBits(), random.getLeastSignificantBits());
+ }
+
+ public String indexString() {
+ StringBuilder b = new StringBuilder();
+ b.append(Long.toHexString(mostSignificant));
+ b.append("_");
+ b.append(Long.toHexString(leastSignificant));
+ return b.toString();
+ }
+
+ public static GUID parseIndexString(String indexString) {
+ String[] parts = indexString.split("_");
+ if(parts.length != 2) throw new IllegalArgumentException();
+ Long mostSignificant = parseUnsignedLong(parts[0].toUpperCase(), 16);
+ Long leastSignificant = parseUnsignedLong(parts[1], 16);
+ return new GUID(mostSignificant, leastSignificant);
+ }
+
+ /**
+ * Parses the string argument as an unsigned {@code long} in the
+ * radix specified by the second argument. An unsigned integer
+ * maps the values usually associated with negative numbers to
+ * positive numbers larger than {@code MAX_VALUE}.
+ *
+ * The characters in the string must all be digits of the
+ * specified radix (as determined by whether {@link
+ * java.lang.Character#digit(char, int)} returns a nonnegative
+ * value), except that the first character may be an ASCII plus
+ * sign {@code '+'} ({@code '\u005Cu002B'}). The resulting
+ * integer value is returned.
+ *
+ * <p>An exception of type {@code NumberFormatException} is
+ * thrown if any of the following situations occurs:
+ * <ul>
+ * <li>The first argument is {@code null} or is a string of
+ * length zero.
+ *
+ * <li>The radix is either smaller than
+ * {@link java.lang.Character#MIN_RADIX} or
+ * larger than {@link java.lang.Character#MAX_RADIX}.
+ *
+ * <li>Any character of the string is not a digit of the specified
+ * radix, except that the first character may be a plus sign
+ * {@code '+'} ({@code '\u005Cu002B'}) provided that the
+ * string is longer than length 1.
+ *
+ * <li>The value represented by the string is larger than the
+ * largest unsigned {@code long}, 2<sup>64</sup>-1.
+ *
+ * </ul>
+ *
+ *
+ * @param s the {@code String} containing the unsigned integer
+ * representation to be parsed
+ * @param radix the radix to be used while parsing {@code s}.
+ * @return the unsigned {@code long} represented by the string
+ * argument in the specified radix.
+ * @throws NumberFormatException if the {@code String}
+ * does not contain a parsable {@code long}.
+ * @since 1.8
+ */
+ public static long parseUnsignedLong(String s, int radix)
+ throws NumberFormatException {
+ if (s == null) {
+ throw new NumberFormatException("null");
+ }
+
+ int len = s.length();
+ if (len > 0) {
+ char firstChar = s.charAt(0);
+ if (firstChar == '-') {
+ throw new
+ NumberFormatException(String.format("Illegal leading minus sign " +
+ "on unsigned string %s.", s));
+ } else {
+ if (len <= 12 || // Long.MAX_VALUE in Character.MAX_RADIX is 13 digits
+ (radix == 10 && len <= 18) ) { // Long.MAX_VALUE in base 10 is 19 digits
+ return Long.parseLong(s, radix);
+ }
+
+ // No need for range checks on len due to testing above.
+ long first = Long.parseLong(s.substring(0, len - 1), radix);
+ int second = Character.digit(s.charAt(len - 1), radix);
+ if (second < 0) {
+ throw new NumberFormatException("Bad digit at end of " + s);
+ }
+ long result = first * radix + second;
+ if (compareUnsigned(result, first) < 0) {
+ /*
+ * The maximum unsigned value, (2^64)-1, takes at
+ * most one more digit to represent than the
+ * maximum signed value, (2^63)-1. Therefore,
+ * parsing (len - 1) digits will be appropriately
+ * in-range of the signed parsing. In other
+ * words, if parsing (len -1) digits overflows
+ * signed parsing, parsing len digits will
+ * certainly overflow unsigned parsing.
+ *
+ * The compareUnsigned check above catches
+ * situations where an unsigned overflow occurs
+ * incorporating the contribution of the final
+ * digit.
+ */
+ throw new NumberFormatException(String.format("String value %s exceeds " +
+ "range of unsigned long.", s));
+ }
+ return result;
+ }
+ } else {
+ throw new NumberFormatException("For input string: \"" + s + "\"");
+ }
+ }
+
+ /**
+ * Compares two {@code long} values numerically treating the values
+ * as unsigned.
+ *
+ * @param x the first {@code long} to compare
+ * @param y the second {@code long} to compare
+ * @return the value {@code 0} if {@code x == y}; a value less
+ * than {@code 0} if {@code x < y} as unsigned values; and
+ * a value greater than {@code 0} if {@code x > y} as
+ * unsigned values
+ * @since 1.8
+ */
+ public static int compareUnsigned(long x, long y) {
+ return Long.compare(x + Long.MIN_VALUE, y + Long.MIN_VALUE);
+ }
+
+}