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 Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc
.squirreljme
.jvm
.suite
;
12 import java
.lang
.ref
.Reference
;
13 import java
.lang
.ref
.WeakReference
;
16 * This represents a suite version.
20 public final class SuiteVersion
21 implements Comparable
<SuiteVersion
>
23 /** The minimum version number. */
24 public static final SuiteVersion MIN_VERSION
=
25 new SuiteVersion(0, 0, 0);
27 /** The maximum version number. */
28 public static final SuiteVersion MAX_VERSION
=
29 new SuiteVersion(99, 99, 99);
31 /** The major version. */
32 protected final int major
;
34 /** The minor version. */
35 protected final int minor
;
37 /** The release version. */
38 protected final int release
;
40 /** The string representation. */
41 private Reference
<String
> _string
;
44 * Initializes the version.
46 * @param __v The value to parse.
47 * @throws InvalidSuiteException If there are too many or too little
48 * version fields, they contain illegal charactes, or have an out of range
50 * @throws NullPointerException On null arguments.
53 public SuiteVersion(String __v
)
54 throws InvalidSuiteException
, NullPointerException
56 this(SuiteVersion
.__decodeVersion(__v
));
60 * Initializes a Midlet version number from the specified array of
63 * @param __v The version triplet, up to the first three elements are
64 * used by the version number.
65 * @throws InvalidSuiteException If the version number has an out of
67 * @throws NullPointerException On null arguments.
70 public SuiteVersion(int[] __v
)
71 throws InvalidSuiteException
, NullPointerException
73 this((__v
.length
> 0 ? __v
[0] : 0),
74 (__v
.length
> 1 ? __v
[1] : 0),
75 (__v
.length
> 2 ? __v
[2] : 0));
79 * Decodes the midlet version, optionally allowing it to a reverse
80 * operation of the {@link #hashCode()} method.
82 * @param __hash If {@code true} then the value to decode is treated as
83 * the hash code returned by this class.
84 * @param __maj If {@code __hash} is {@code true} then this is the hash
85 * code of a SuiteVersion, otherwise it is the major version number.
86 * @throws InvalidSuiteException If the version number has an out of
90 public SuiteVersion(boolean __hash
, int __maj
)
91 throws InvalidSuiteException
93 this((__hash ? __maj
/ 10000 : __maj
),
94 (__hash ?
(__maj
/ 100) % 100 : 0),
95 (__hash ? __maj
% 100 : 0));
99 * Initializes the version.
101 * @param __maj The major version.
102 * @throws IllegalArgumentException If any value is out of range.
105 public SuiteVersion(int __maj
)
111 * Initializes the version.
113 * @param __maj The major version.
114 * @param __min The minor version.
115 * @throws IllegalArgumentException If any value is out of range.
118 public SuiteVersion(int __maj
, int __min
)
120 this(__maj
, __min
, 0);
124 * Initializes the version.
126 * @param __maj The major version.
127 * @param __min The minor version.
128 * @param __rel The release version.
129 * @throws InvalidSuiteException If any value is out of range.
132 public SuiteVersion(int __maj
, int __min
, int __rel
)
133 throws InvalidSuiteException
135 /* {@squirreljme.error DG0i Input version number is out of range, only
136 0 through 99 are valid. (The major version; The minor version; The
138 if (__maj
< 0 || __maj
> 99 || __min
< 0 || __min
> 99 ||
139 __rel
< 0 || __rel
> 99)
140 throw new InvalidSuiteException(String
.format("AR0i %d %d %d",
141 __maj
, __min
, __rel
));
146 this.release
= __rel
;
150 * Checks if this version at least the specified verison.
152 * @param __v The version to check against.
153 * @return {@code true} if this version is at least the other.
154 * @throws NullPointerException On nul arguments.
156 public boolean atLeast(SuiteVersion __v
)
157 throws NullPointerException
161 throw new NullPointerException("NARG");
163 // Can compare the hashcodes
164 return this.hashCode() >= __v
.hashCode();
172 public int compareTo(SuiteVersion __o
)
175 int amaj
= this.major
, bmaj
= __o
.major
;
176 int rv
= amaj
- bmaj
;
181 int amin
= this.minor
, bmin
= __o
.minor
;
187 int arel
= this.release
, brel
= __o
.release
;
201 public boolean equals(Object __o
)
204 if (!(__o
instanceof SuiteVersion
))
208 SuiteVersion o
= (SuiteVersion
)__o
;
209 return this.major
== o
.major
&&
210 this.minor
== o
.minor
&&
211 this.release
== o
.release
;
219 public int hashCode()
221 return (this.major
* 10000) +
227 * Returns the major version.
229 * @return The major version.
238 * Returns the minor version.
240 * @return The minor version.
249 * Returns the release version.
251 * @return The release version.
264 public String
toString()
267 Reference
<String
> ref
= this._string
;
271 if (ref
== null || null == (rv
= ref
.get()))
272 this._string
= new WeakReference
<>((rv
= this.major
+ "." +
273 this.minor
+ "." + this.release
));
280 * Decodes the string based version number
282 * @param __v The input string.
283 * @return The version tuplet.
284 * @throws InvalidSuiteException If the input is not valid.
285 * @throws NullPointerException On null arguments.
288 private static int[] __decodeVersion(String __v
)
289 throws InvalidSuiteException
, NullPointerException
293 throw new NullPointerException("NARG");
299 int[] rv
= new int[3];
301 // Parse the input value
302 int n
= __v
.length(), at
= 0;
303 StringBuilder sb
= new StringBuilder();
304 for (int i
= 0; i
<= n
; i
++)
306 int c
= (i
== n ?
-1 : __v
.charAt(i
));
308 // Decimal point? or end
309 if (c
== '.' || c
== -1)
311 rv
[at
++] = Integer
.parseInt(sb
.toString(), 10);
313 /* {@squirreljme.error DG0j Too many version fields in the
314 specified string. (The input string)} */
315 if (c
!= -1 && at
>= 4)
316 throw new InvalidSuiteException(String
.format("AR0j %s",
324 else if (c
>= '0' && c
<= '9')
327 /* {@squirreljme.error DG0k An illegal character is in the
328 version string. (The input string; The illegal character)} */
330 throw new InvalidSuiteException(String
.format("AR0k %s %04x",