1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the GNU General Public License v3+, or later.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.jvm
.suite
;
12 import cc
.squirreljme
.runtime
.cldc
.annotation
.Exported
;
13 import java
.lang
.ref
.Reference
;
14 import java
.lang
.ref
.WeakReference
;
17 * This represents a suite version.
22 public final class SuiteVersion
23 implements Comparable
<SuiteVersion
>
25 /** The minimum version number. */
27 public static final SuiteVersion MIN_VERSION
=
28 new SuiteVersion(0, 0, 0);
30 /** The maximum version number. */
32 public static final SuiteVersion MAX_VERSION
=
33 new SuiteVersion(99, 99, 99);
35 /** The major version. */
36 protected final int major
;
38 /** The minor version. */
39 protected final int minor
;
41 /** The release version. */
42 protected final int release
;
44 /** The string representation. */
45 private Reference
<String
> _string
;
48 * Initializes the version.
50 * @param __v The value to parse.
51 * @throws InvalidSuiteException If there are too many or too little
52 * version fields, they contain illegal charactes, or have an out of range
54 * @throws NullPointerException On null arguments.
58 public SuiteVersion(String __v
)
59 throws InvalidSuiteException
, NullPointerException
61 this(SuiteVersion
.__decodeVersion(__v
));
65 * Initializes a Midlet version number from the specified array of
68 * @param __v The version triplet, up to the first three elements are
69 * used by the version number.
70 * @throws InvalidSuiteException If the version number has an out of
72 * @throws NullPointerException On null arguments.
76 public SuiteVersion(int[] __v
)
77 throws InvalidSuiteException
, NullPointerException
79 this((__v
.length
> 0 ? __v
[0] : 0),
80 (__v
.length
> 1 ? __v
[1] : 0),
81 (__v
.length
> 2 ? __v
[2] : 0));
85 * Decodes the midlet version, optionally allowing it to a reverse
86 * operation of the {@link #hashCode()} method.
88 * @param __hash If {@code true} then the value to decode is treated as
89 * the hash code returned by this class.
90 * @param __maj If {@code __hash} is {@code true} then this is the hash
91 * code of a SuiteVersion, otherwise it is the major version number.
92 * @throws InvalidSuiteException If the version number has an out of
97 public SuiteVersion(boolean __hash
, int __maj
)
98 throws InvalidSuiteException
100 this((__hash ? __maj
/ 10000 : __maj
),
101 (__hash ?
(__maj
/ 100) % 100 : 0),
102 (__hash ? __maj
% 100 : 0));
106 * Initializes the version.
108 * @param __maj The major version.
109 * @throws IllegalArgumentException If any value is out of range.
113 public SuiteVersion(int __maj
)
119 * Initializes the version.
121 * @param __maj The major version.
122 * @param __min The minor version.
123 * @throws IllegalArgumentException If any value is out of range.
127 public SuiteVersion(int __maj
, int __min
)
129 this(__maj
, __min
, 0);
133 * Initializes the version.
135 * @param __maj The major version.
136 * @param __min The minor version.
137 * @param __rel The release version.
138 * @throws InvalidSuiteException If any value is out of range.
142 public SuiteVersion(int __maj
, int __min
, int __rel
)
143 throws InvalidSuiteException
145 // {@squirreljme.error DG0i Input version number is out of range, only
146 // 0 through 99 are valid. (The major version; The minor version; The
148 if (__maj
< 0 || __maj
> 99 || __min
< 0 || __min
> 99 ||
149 __rel
< 0 || __rel
> 99)
150 throw new InvalidSuiteException(String
.format("AR0i %d %d %d",
151 __maj
, __min
, __rel
));
156 this.release
= __rel
;
160 * Checks if this version at least the specified verison.
162 * @param __v The version to check against.
163 * @return {@code true} if this version is at least the other.
164 * @throws NullPointerException On nul arguments.
167 public boolean atLeast(SuiteVersion __v
)
168 throws NullPointerException
172 throw new NullPointerException("NARG");
174 // Can compare the hashcodes
175 return this.hashCode() >= __v
.hashCode();
183 public int compareTo(SuiteVersion __o
)
186 int amaj
= this.major
, bmaj
= __o
.major
;
187 int rv
= amaj
- bmaj
;
192 int amin
= this.minor
, bmin
= __o
.minor
;
198 int arel
= this.release
, brel
= __o
.release
;
212 public boolean equals(Object __o
)
215 if (!(__o
instanceof SuiteVersion
))
219 SuiteVersion o
= (SuiteVersion
)__o
;
220 return this.major
== o
.major
&&
221 this.minor
== o
.minor
&&
222 this.release
== o
.release
;
230 public int hashCode()
232 return (this.major
* 10000) +
238 * Returns the major version.
240 * @return The major version.
250 * Returns the minor version.
252 * @return The minor version.
262 * Returns the release version.
264 * @return The release version.
278 public String
toString()
281 Reference
<String
> ref
= this._string
;
285 if (ref
== null || null == (rv
= ref
.get()))
286 this._string
= new WeakReference
<>((rv
= this.major
+ "." +
287 this.minor
+ "." + this.release
));
294 * Decodes the string based version number
296 * @param __v The input string.
297 * @return The version tuplet.
298 * @throws InvalidSuiteException If the input is not valid.
299 * @throws NullPointerException On null arguments.
302 private static int[] __decodeVersion(String __v
)
303 throws InvalidSuiteException
, NullPointerException
307 throw new NullPointerException("NARG");
313 int[] rv
= new int[3];
315 // Parse the input value
316 int n
= __v
.length(), at
= 0;
317 StringBuilder sb
= new StringBuilder();
318 for (int i
= 0; i
<= n
; i
++)
320 int c
= (i
== n ?
-1 : __v
.charAt(i
));
322 // Decimal point? or end
323 if (c
== '.' || c
== -1)
325 rv
[at
++] = Integer
.parseInt(sb
.toString(), 10);
327 // {@squirreljme.error DG0j Too many version fields in the
328 // specified string. (The input string)}
329 if (c
!= -1 && at
>= 4)
330 throw new InvalidSuiteException(String
.format("AR0j %s",
338 else if (c
>= '0' && c
<= '9')
341 // {@squirreljme.error DG0k An illegal character is in the
342 // version string. (The input string; The illegal character)}
344 throw new InvalidSuiteException(String
.format("AR0k %s %04x",