001package Torello.JSON; 002 003import Torello.Java.StringParse; 004import Torello.Java.UnreachableError; 005 006import Torello.Java.Function.IntTFunction; 007import Torello.Java.Function.IntIntTFunc; 008 009import Torello.Java.Additional.Counter; 010 011import java.util.function.Function; 012import java.util.function.Predicate; 013 014import java.math.BigDecimal; 015import java.math.BigInteger; 016 017import javax.json.JsonNumber; 018import javax.json.JsonObject; 019import javax.json.JsonArray; 020 021 022// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 023// This class provides LAMBDA'S / FUNCTION-POINTERS / FUNCTIONAL-INTERFACES 024// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 025// 026// OK, This Class provides the Vast-Majority of the Lambda / Functional-Interfaces that can be 027// associated with the Standard Java Primitive-Types which are handled by this Json-Package. This 028// Package handle 7 of 8 standard Java-Types, but leaves out the 'char' Primitive-Type, because 029// Json doesn't have much of anything resembling a 'char' type, and the concept just seemed 030// generally, completely unnecessary. 031// 032// This class also has a configuration-record for the types: String, Number & even Object. 033// 034// 035// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 036// WHAT TO KNOW ABOUT THESE LAMBDA'S 037// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 038// 039// The Lambda's which are "stored" or "saved" in all of the builder methods here are exactly the 040// Lambda's which *DO NOT REQUIRE USER-INPUT* in order to generate. This is "as opposed to" the 041// Functional-Interfaces which are produced by the Class 'TempFlags'. 042// 043// In class "TempFlags", the Lambda-Functions that are generated / selected / produced there are 044// in *STRICT ADHERENCE* with the choices that the user has made using the "JFlags" parameter - the 045// Flag-Mask that allows a user to confgure specific behavior of the Json-Parser. 046// 047// To summarize - *AGAIN* - the Lambda's / Functional-Interfaces / a.k.a. "Method Pointers" which 048// are declared inside this class are all of the ones which are associated with the **SPECIFIC 049// TYPE** that was decided-upon, based on the RJArr Method that he has invoked. These Lambda's 050// are constant, and would never change based on user-preference. Though they could be eliminated 051// or ignored, it isn't possible for them to "Modified by User-Preferences", etc... 052// 053// Class 'TempFlags' has a giant dispatch engine that dispatches based on flags the user has 054// provided 055// 056// 057// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 058// The "Funtion-Pointer" Reminder 059// *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 060// 061// It is important to remember that everything that is done inside the Json-Array Processing 062// Classes (Specifically, those which begin with "RJArr") - is done by a single "Processing Loop" 063// Main-Class. Please review the contents of the "ProcessJsonArray" class to see how any 064// invocation of either the RJArr: Stream, Consumer or Array Classes all use the "ProcessJsonArray" 065// class to perform their parse. 066// 067// This is acheived by wrapping the dozens of User-Choices, Configurations, Preferences & 068// Selections into a suite of Functional-Interfaces (Function-Pointers) and saving them inide of 069// a giant "SettingsRec". The Java Byte-Code Optimizer is likely capable of doing enough 070// optimizations to ensure that all of the Pointer-Reference "De-Referencing" that is going on 071// is done efficiently. More testing needs to be done to check this out... 072 073public class BASIC_TYPES<T> 074{ 075 // ******************************************************************************************** 076 // ******************************************************************************************** 077 // Main Fields (These are used to FURTHER help configure class "SettingsRec") 078 // ******************************************************************************************** 079 // ******************************************************************************************** 080 081 082 // Used by the Multi-Dimensional Array Processor only 083 // final Function<JsonArray, U> array1DGenerator; 084 085 final byte whichType; 086 087 // Essentially: Not STRING, BOOLEAN or OBJECT 088 final boolean isNumberType; 089 090 // same as primitive or boxed (I think) 091 final boolean referenceOrPrimitive; 092 093 // Class of the Stream.Builder "accept" Parameter 094 final Class<T> CLASS; 095 096 // Number size tester 097 final Predicate<JsonNumber> jsonNumWillFit; 098 099 // String-tester (for parsing number-strings) 100 final Predicate<String> validStrTester; 101 102 // default-parser (number-string to Integer) 103 final Function<String, T> defaultParser; 104 105 // numberConverter (JAPPROX_ON_AEX *AND* usual-ans) 106 final Function<Number, T> numberConverter; 107 108 // Generates AEX on fail 109 final Function<BigDecimal, T> numberConverterExThrow; 110 111 112 // ******************************************************************************************** 113 // ******************************************************************************************** 114 // Exported (and also internally used) Static Constants 115 // ******************************************************************************************** 116 // ******************************************************************************************** 117 118 119 static final boolean REFERENCE = true; 120 static final boolean BOXED = true; 121 static final boolean PRIMITIVE = false; 122 123 static final byte INTEGER = 0; 124 static final byte SHORT = 1; 125 static final byte BYTE = 2; 126 static final byte LONG = 3; 127 static final byte DOUBLE = 4; 128 static final byte FLOAT = 5; 129 130 static final byte BOOLEAN = 6; 131 static final byte NUMBER = 7; 132 static final byte STRING = 8; 133 134 static final byte JSON_OBJECT = 9; 135 static final byte JSON_ARRAY = 10; 136 137 static final byte EXTENDED_OBJ = 11; 138 139 140 // ******************************************************************************************** 141 // ******************************************************************************************** 142 // Internal, Private, Static Singleton-Instances THAT ARE INITIALLY NULL AND ARE LAZILY-LOADED! 143 // ******************************************************************************************** 144 // ******************************************************************************************** 145 146 147 // Rather than generating 18 Records, 16 or 17 of which will likely never be used throughout 148 // the life-cycle of the program, this set of fields are all assigned null, and are not 149 // instantiated until they are requested by the user. 150 // 151 // These are, indeed, all singleton instances that contain CONSTANT-DATA which is re-used for 152 // each and every call for a request of the configurations that are present inside this data 153 // class. 154 155 private static BASIC_TYPES<Integer> BOXED_INTEGER = null; 156 private static BASIC_TYPES<Integer> PRIMITIVE_INTEGER = null; 157 158 private static BASIC_TYPES<Short> BOXED_SHORT = null; 159 private static BASIC_TYPES<Short> PRIMITIVE_SHORT = null; 160 161 private static BASIC_TYPES<Byte> BOXED_BYTE = null; 162 private static BASIC_TYPES<Byte> PRIMITIVE_BYTE = null; 163 164 private static BASIC_TYPES<Long> BOXED_LONG = null; 165 private static BASIC_TYPES<Long> PRIMITIVE_LONG = null; 166 167 private static BASIC_TYPES<Double> BOXED_DOUBLE = null; 168 private static BASIC_TYPES<Double> PRIMITIVE_DOUBLE = null; 169 170 private static BASIC_TYPES<Float> BOXED_FLOAT = null; 171 private static BASIC_TYPES<Float> PRIMITIVE_FLOAT = null; 172 173 private static BASIC_TYPES<Boolean> BOXED_BOOLEAN = null; 174 private static BASIC_TYPES<Boolean> PRIMITIVE_BOOLEAN = null; 175 176 private static BASIC_TYPES<String> STRING_REC = null; 177 private static BASIC_TYPES<Number> NUMBER_REC = null; 178 179 private static BASIC_TYPES<JsonObject> JSON_OBJECT_REC = null; 180 private static BASIC_TYPES<JsonArray> JSON_ARRAY_REC = null; 181 182 183 // ******************************************************************************************** 184 // ******************************************************************************************** 185 // The Lazy-Loading Methods / Getters (These methods do both at the same time) 186 // ******************************************************************************************** 187 // ******************************************************************************************** 188 189 190 // These are nothing more than "getters" for the above Data-Field Singleton-Instances. These 191 // 18 methods are simply designed to return the same constant singleton instance each and every 192 // time that any of these methods are invoked. 193 // 194 // Most important, notice that on the very first call to these methods, the value assigned to 195 // these fields will always be null (after being loaded by the class-loader). These methods 196 // will call the constructor for these fields the first time they are called, and then from 197 // point forward, the same singleton will be returned each and ever time 198 199 static BASIC_TYPES<Integer> BOXED_INTEGER() 200 { return (BOXED_INTEGER !=null) ? BOXED_INTEGER : (BOXED_INTEGER = INTEGER(BOXED)); } 201 202 static BASIC_TYPES<Integer> PRIMITIVE_INTEGER() 203 { 204 return (PRIMITIVE_INTEGER !=null) 205 ? PRIMITIVE_INTEGER 206 : (PRIMITIVE_INTEGER = INTEGER(PRIMITIVE)); 207 } 208 209 210 static BASIC_TYPES<Short> BOXED_SHORT() 211 { return (BOXED_SHORT !=null) ? BOXED_SHORT : (BOXED_SHORT = SHORT(BOXED)); } 212 213 static BASIC_TYPES<Short> PRIMITIVE_SHORT() 214 { return (PRIMITIVE_SHORT !=null) ? PRIMITIVE_SHORT : (PRIMITIVE_SHORT = SHORT(PRIMITIVE)); } 215 216 217 static BASIC_TYPES<Byte> BOXED_BYTE() 218 { return (BOXED_BYTE !=null) ? BOXED_BYTE : (BOXED_BYTE = BYTE(BOXED)); } 219 220 static BASIC_TYPES<Byte> PRIMITIVE_BYTE() 221 { return (PRIMITIVE_BYTE !=null) ? PRIMITIVE_BYTE : (PRIMITIVE_BYTE = BYTE(PRIMITIVE)); } 222 223 224 static BASIC_TYPES<Long> BOXED_LONG() 225 { return (BOXED_LONG !=null) ? BOXED_LONG : (BOXED_LONG = LONG(BOXED)); } 226 227 static BASIC_TYPES<Long> PRIMITIVE_LONG() 228 { return (PRIMITIVE_LONG !=null) ? PRIMITIVE_LONG : (PRIMITIVE_LONG = LONG(PRIMITIVE)); } 229 230 231 static BASIC_TYPES<Double> BOXED_DOUBLE() 232 { return (BOXED_DOUBLE !=null) ? BOXED_DOUBLE : (BOXED_DOUBLE = DOUBLE(BOXED)); } 233 234 static BASIC_TYPES<Double> PRIMITIVE_DOUBLE() 235 { 236 return (PRIMITIVE_DOUBLE !=null) 237 ? PRIMITIVE_DOUBLE 238 : (PRIMITIVE_DOUBLE = DOUBLE(PRIMITIVE)); 239 } 240 241 242 static BASIC_TYPES<Float> BOXED_FLOAT() 243 { return (BOXED_FLOAT !=null) ? BOXED_FLOAT : (BOXED_FLOAT = FLOAT(BOXED)); } 244 245 static BASIC_TYPES<Float> PRIMITIVE_FLOAT() 246 { return (PRIMITIVE_FLOAT !=null) ? PRIMITIVE_FLOAT : (PRIMITIVE_FLOAT = FLOAT(PRIMITIVE)); } 247 248 249 static BASIC_TYPES<Boolean> BOXED_BOOLEAN() 250 { return (BOXED_BOOLEAN !=null) ? BOXED_BOOLEAN : (BOXED_BOOLEAN = BOOLEAN(BOXED)); } 251 252 static BASIC_TYPES<Boolean> PRIMITIVE_BOOLEAN() 253 { 254 return (PRIMITIVE_BOOLEAN !=null) 255 ? PRIMITIVE_BOOLEAN 256 : (PRIMITIVE_BOOLEAN = BOOLEAN(PRIMITIVE)); 257 } 258 259 260 static BASIC_TYPES<Number> NUMBER_REC() 261 { return (NUMBER_REC !=null) ? NUMBER_REC : (NUMBER_REC = NUMBER()); } 262 263 static BASIC_TYPES<String> STRING_REC() 264 { return (STRING_REC !=null) ? STRING_REC : (STRING_REC = STRING()); } 265 266 static BASIC_TYPES<JsonObject> JSON_OBJECT_REC() 267 { return (JSON_OBJECT_REC !=null) ? JSON_OBJECT_REC : (JSON_OBJECT_REC = JO()); } 268 269 static BASIC_TYPES<JsonArray> JSON_ARRAY_REC() 270 { return (JSON_ARRAY_REC !=null) ? JSON_ARRAY_REC : (JSON_ARRAY_REC = JA()); } 271 272 273 // ******************************************************************************************** 274 // ******************************************************************************************** 275 // Constructor 276 // ******************************************************************************************** 277 // ******************************************************************************************** 278 279 280 private BASIC_TYPES( 281 final byte whichType, 282 final boolean referenceOrPrimitive, 283 final Class<T> CLASS, 284 final Predicate<JsonNumber> jsonNumWillFit, 285 final Predicate<String> validStrTester, 286 final Function<String, T> defaultParser, 287 final Function<Number, T> numberConverter, 288 final Function<BigDecimal, T> numberConverterExThrow 289 ) 290 { 291 this.whichType = whichType; 292 this.referenceOrPrimitive = referenceOrPrimitive; 293 this.CLASS = CLASS; 294 this.jsonNumWillFit = jsonNumWillFit; 295 this.validStrTester = validStrTester; 296 this.defaultParser = defaultParser; 297 this.numberConverter = numberConverter; 298 this.numberConverterExThrow = numberConverterExThrow; 299 300 this.isNumberType = 301 (this.whichType != STRING) 302 && (this.whichType != BOOLEAN) 303 && (this.whichType != JSON_OBJECT) 304 && (this.whichType != JSON_ARRAY); 305 306 307 // This constructor is private, and cannot be used by the "EXTENDED_TYPES" subclass. 308 // Leave this here, because is serves (sort of) as a comment, and a reminder. 309 310 if (this.whichType == EXTENDED_OBJ) throw new UnreachableError(); 311 } 312 313 314 // This is a specialize constructor which is being added to allow for providing an 315 // "Object-Builder" variant of the "objArr". What that means, in English, is that a new 316 // version of the method for reading an Array of Objects is being added. The original version 317 // of "Object Array Handler" required that the Object have a constructor which accepts a 318 // Json-Object as Input in order to produce an instance of the Object. 319 // 320 // This new variant of "Basic Type" will allow the user to provide any old lambda function, 321 // whatsoever, to produce / build / construct an instance of the Object that has been retrieved 322 // from the Json-Array of Objects. This feature was added in April 2025. It is needed for the 323 // Java-Doc Frames & Package-Summary Sorter "Feature." The user provides a Json based 324 // Configuration-File, and that Configuration-File contains an array of objects. 325 // 326 // The Code looks much nicer when there is a "B1" Builder and a "D1" Data-Record, than when 327 // there is just one giant "D1" Data-Record with a large constructor shoved inside of it. 328 // By adding this new "Basic-Type" thing-y, I can separate the two! 329 330 // Here is the original constructor. Since there is only one method that invokes this 331 // constructor there is, therefore, no need to accept all of these parameters, and they can be 332 // automatically hard-wired to accept null. 333 334 BASIC_TYPES(final Class<T> CLASS) 335 { 336 this.whichType = EXTENDED_OBJ; 337 this.referenceOrPrimitive = true; 338 this.CLASS = CLASS; 339 this.jsonNumWillFit = null; 340 this.validStrTester = null; 341 this.defaultParser = null; 342 this.numberConverter = null; 343 this.numberConverterExThrow = null; 344 this.isNumberType = false; 345 } 346 347 348 // ******************************************************************************************** 349 // ******************************************************************************************** 350 // All of the actual Configurations themselves - as "private static builder methods" 351 // ******************************************************************************************** 352 // ******************************************************************************************** 353 354 355 private static BASIC_TYPES<Integer> INTEGER(final boolean boxedOrPrimitive) 356 { 357 return new BASIC_TYPES<>( 358 INTEGER, // final byte whichType 359 boxedOrPrimitive, // final boolean referenceOrPrimitive 360 361 // final Class<T> CLASS 362 boxedOrPrimitive ? Integer.class : int.class, 363 364 // final Predicate<JsonNumber> jsonNumWillFit 365 (JsonNumber jn) -> jn.numberValue().getClass() == Integer.class, 366 367 StringParse::isInteger, // final Predicate<String> validStrTester 368 Integer::parseInt, // final Function<String, T> defaultParser 369 Number::intValue, // final Function<Number, T> numberConverter 370 BigDecimal::intValueExact // final Function<BigDecimal, T> numberConverterExThrow 371 ); 372 } 373 374 private static BASIC_TYPES<Short> SHORT(final boolean boxedOrPrimitive) 375 { 376 return new BASIC_TYPES<>( 377 SHORT, // final byte whichType 378 boxedOrPrimitive, // final boolean referenceOrPrimitive 379 380 // final Class<T> CLASS 381 boxedOrPrimitive ? Short.class : short.class, 382 383 BASIC_TYPES::shortTypePred, // final Predicate<JsonNumber> jsonNumWillFit 384 StringParse::isShort, // final Predicate<String> validStrTester 385 Short::parseShort, // final Function<String, T> defaultParser 386 Number::shortValue, // final Function<Number, T> numberConverter 387 BigDecimal::shortValueExact // final Function<BigDecimal, T> numberConverterExThrow 388 ); 389 } 390 391 private static BASIC_TYPES<Byte> BYTE(final boolean boxedOrPrimitive) 392 { 393 return new BASIC_TYPES<>( 394 BYTE, // final byte whichType 395 boxedOrPrimitive, // final boolean referenceOrPrimitive 396 397 // final Class<T> CLASS 398 boxedOrPrimitive ? Byte.class : byte.class, 399 400 BASIC_TYPES::byteTypePred, // final Predicate<JsonNumber> jsonNumWillFit 401 StringParse::isByte, // final Predicate<String> validStrTester 402 Byte::parseByte, // final Function<String, T> defaultParser 403 Number::byteValue, // final Function<Number, T> numberConverter 404 BigDecimal::byteValueExact // final Function<BigDecimal, T> numberConverterExThrow 405 ); 406 } 407 408 private static BASIC_TYPES<Long> LONG(final boolean boxedOrPrimitive) 409 { 410 return new BASIC_TYPES<>( 411 LONG, // final byte whichType 412 boxedOrPrimitive, // final boolean referenceOrPrimitive 413 414 // final Class<T> CLASS 415 boxedOrPrimitive ? Long.class : long.class, 416 417 BASIC_TYPES::longTypePred, // final Predicate<JsonNumber> jsonNumWillFit 418 StringParse::isLong, // final Predicate<String> validStrTester 419 Long::parseLong, // final Function<String, T> defaultParser 420 Number::longValue, // final Function<Number, T> numberConverter 421 BigDecimal::longValueExact // final Function<BigDecimal, T> numberConverterExThrow 422 ); 423 } 424 425 private static BASIC_TYPES<Double> DOUBLE(final boolean boxedOrPrimitive) 426 { 427 return new BASIC_TYPES<>( 428 DOUBLE, // final byte whichType 429 boxedOrPrimitive, // final boolean referenceOrPrimitive 430 431 // final Class<T> CLASS 432 boxedOrPrimitive ? Double.class : double.class, 433 434 // final Predicate<JsonNumber> jsonNumWillFit, doubleTypePred doesn't exist 435 null, 436 437 StringParse::isDouble, // final Predicate<String> validStrTester 438 Double::parseDouble, // final Function<String, T> defaultParser 439 Number::doubleValue, // final Function<Number, T> numberConverter 440 441 // final Function<BigDecimal, T> numberConverterExThrow 442 (BigDecimal bd) -> { throw new ArithmeticException("Invalid Input"); } 443 ); 444 } 445 446 private static BASIC_TYPES<Float> FLOAT(final boolean boxedOrPrimitive) 447 { 448 return new BASIC_TYPES<>( 449 FLOAT, // final byte whichType 450 boxedOrPrimitive, // final boolean referenceOrPrimitive 451 452 // final Class<T> CLASS 453 boxedOrPrimitive ? Float.class : float.class, 454 455 // final Predicate<JsonNumber> jsonNumWillFit, floatTypePred doesn't exist 456 null, 457 458 StringParse::isDouble, // final Predicate<String> validStrTester 459 // StringParse doesn't have an "isFloat" 460 Float::parseFloat, // final Function<String, T> defaultParser 461 Number::floatValue, // final Function<Number, T> numberConverter 462 463 // final Function<BigDecimal, T> numberConverterExThrow 464 (BigDecimal bd) -> { throw new ArithmeticException("Invalid Input"); } 465 ); 466 } 467 468 private static BASIC_TYPES<Boolean> BOOLEAN(final boolean boxedOrPrimitive) 469 { 470 return new BASIC_TYPES<>( 471 BOOLEAN, // final byte whichType 472 boxedOrPrimitive, // final boolean referenceOrPrimitive 473 474 // final Class<T> CLASS 475 boxedOrPrimitive ? Boolean.class : boolean.class, 476 477 // final Predicate<JsonNumber> jsonNumWillFit - Boolean is not a JsonNumber! 478 null, 479 480 s -> true, // final Predicate<String> validStrTester 481 // String-tester (for parsing number-strings) 482 Boolean::parseBoolean, // final Function<String, T> defaultParser 483 null, // numberConverter (JAPPROX_ON_AEX *AND* usual-ans) 484 null // The Arithmetic-Exception thing 485 ); 486 } 487 488 private static BASIC_TYPES<Number> NUMBER() 489 { 490 // It's been 2.5 years since I originally wrote this, and I really don't remember 491 // how this one works... 492 493 return new BASIC_TYPES<Number>( 494 NUMBER, // final byte whichType, 495 BOXED, // final boolean referenceOrPrimitive, 496 Number.class, // final Class<T> CLASS, 497 (JsonNumber jn) -> true, // final Predicate<JsonNumber> jsonNumWillFit, 498 499 500 // These are all Hard-Coded into the "SettingsRec" 501 // There is a special case when this.whiteType == BASIC_TYPES.NUMBER 502 503 null, // final Predicate<String> validStrTester, 504 null, // final Function<String, T> defaultParser, 505 null, // final Function<Number, T> numberConverter, 506 null // final Function<BigDecimal, T> numberConverterExThrow 507 ); 508 } 509 510 // None of these little configurtion-lambdas are needed because 'String' is not a number 511 private static BASIC_TYPES<String> STRING() 512 { 513 return new BASIC_TYPES<>( 514 STRING, // final byte whichType, 515 true, // final boolean referenceOrPrimitive, 516 String.class, // final Class<T> CLASS, 517 null, // final Predicate<JsonNumber> jsonNumWillFit, 518 null, // final Predicate<String> validStrTester, 519 null, // final Function<String, T> defaultParser, 520 null, // final Function<Number, T> numberConverter w/Approx, 521 null // final Function<BigDecimal, T> numberConverter w/AEX 522 ); 523 } 524 525 // None of these little configurtion-lambdas are needed because 'JsonObject' is not a number 526 private static BASIC_TYPES<JsonObject> JO() 527 { 528 return new BASIC_TYPES<>( 529 JSON_OBJECT, // final byte whichType, 530 true, // final boolean referenceOrPrimitive, 531 JsonObject.class, // final Class<T> CLASS, 532 null, // final Predicate<JsonNumber> jsonNumWillFit, 533 null, // final Predicate<String> validStrTester, 534 null, // final Function<String, T> defaultParser, 535 null, // final Function<Number, T> numberConverter w/Approx, 536 null // final Function<BigDecimal, T> numberConverter w/AEX 537 ); 538 } 539 540 // None of these little configurtion-lambdas are needed because 'JsonObject' is not a number 541 private static BASIC_TYPES<JsonArray> JA() 542 { 543 return new BASIC_TYPES<>( 544 JSON_ARRAY, // final byte whichType, 545 true, // final boolean referenceOrPrimitive, 546 JsonArray.class, // final Class<T> CLASS, 547 null, // final Predicate<JsonNumber> jsonNumWillFit, 548 null, // final Predicate<String> validStrTester, 549 null, // final Function<String, T> defaultParser, 550 null, // final Function<Number, T> numberConverter w/Approx, 551 null // final Function<BigDecimal, T> numberConverter w/AEX 552 ); 553 } 554 555 556 // ******************************************************************************************** 557 // ******************************************************************************************** 558 // Three Minor Helper Predicates 559 // ******************************************************************************************** 560 // ******************************************************************************************** 561 562 563 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 564 // Long-Type Test-Predicate 565 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 566 567 private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); 568 private static final BigInteger LONG_MIN = BigInteger.valueOf(Long.MIN_VALUE); 569 570 private static boolean longTypePred(JsonNumber jn) 571 { 572 if (! jn.isIntegral()) return false; 573 574 BigInteger bi = jn.bigIntegerValue(); 575 int signum = bi.signum(); 576 577 return ((signum > 0) && (bi.compareTo(LONG_MAX) <= 0)) 578 || ((signum < 0) && (bi.compareTo(LONG_MIN) >= 0)) 579 || (signum == 0); 580 } 581 582 583 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 584 // Short-Type Test-Predicate 585 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 586 587 private static final BigInteger SHORT_MAX = BigInteger.valueOf(Short.MAX_VALUE); 588 private static final BigInteger SHORT_MIN = BigInteger.valueOf(Short.MIN_VALUE); 589 590 private static boolean shortTypePred(JsonNumber jn) 591 { 592 if (! jn.isIntegral()) return false; 593 594 BigInteger bi = jn.bigIntegerValue(); 595 int signum = bi.signum(); 596 597 return ((signum > 0) && (bi.compareTo(SHORT_MAX) <= 0)) 598 || ((signum < 0) && (bi.compareTo(SHORT_MIN) >= 0)) 599 || (signum == 0); 600 } 601 602 603 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 604 // Byte-Type Test-Predicate 605 // *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 606 607 private static final BigInteger BYTE_MAX = BigInteger.valueOf(Byte.MAX_VALUE); 608 private static final BigInteger BYTE_MIN = BigInteger.valueOf(Byte.MIN_VALUE); 609 610 private static boolean byteTypePred(JsonNumber jn) 611 { 612 if (! jn.isIntegral()) return false; 613 614 BigInteger bi = jn.bigIntegerValue(); 615 int signum = bi.signum(); 616 617 return ((signum > 0) && (bi.compareTo(BYTE_MAX) <= 0)) 618 || ((signum < 0) && (bi.compareTo(BYTE_MIN) >= 0)) 619 || (signum == 0); 620 } 621}