@@ -1390,7 +1390,7 @@ static BigInteger objectToBigInteger(Object val, BigInteger defaultValue) {
13901390 if (!numberIsFinite ((Number )val )) {
13911391 return defaultValue ;
13921392 }
1393- return new BigDecimal (((Number ) val ).doubleValue ()).toBigInteger ();
1393+ return BigDecimal . valueOf (((Number ) val ).doubleValue ()).toBigInteger ();
13941394 }
13951395 if (val instanceof Long || val instanceof Integer
13961396 || val instanceof Short || val instanceof Byte ){
@@ -2041,7 +2041,7 @@ private static int getAnnotationDepth(final Method m, final Class<? extends Anno
20412041 return 1 ;
20422042 }
20432043
2044- // if we've already reached the Object class, return -1;
2044+ // since we've already reached the Object class, return -1;
20452045 Class <?> c = m .getDeclaringClass ();
20462046 if (c .getSuperclass () == null ) {
20472047 return -1 ;
@@ -2057,9 +2057,9 @@ private static int getAnnotationDepth(final Method m, final Class<? extends Anno
20572057 return d + 1 ;
20582058 }
20592059 } catch (final SecurityException ex ) {
2060- continue ;
2060+ // Nothing to do here
20612061 } catch (final NoSuchMethodException ex ) {
2062- continue ;
2062+ // Nothing to do here
20632063 }
20642064 }
20652065
@@ -2427,21 +2427,32 @@ public static Writer quote(String string, Writer w) throws IOException {
24272427 w .write ("\\ r" );
24282428 break ;
24292429 default :
2430- if (c < ' ' || (c >= '\u0080' && c < '\u00a0' )
2431- || (c >= '\u2000' && c < '\u2100' )) {
2432- w .write ("\\ u" );
2433- hhhh = Integer .toHexString (c );
2434- w .write ("0000" , 0 , 4 - hhhh .length ());
2435- w .write (hhhh );
2436- } else {
2437- w .write (c );
2438- }
2430+ writeAsHex (w , c );
24392431 }
24402432 }
24412433 w .write ('"' );
24422434 return w ;
24432435 }
24442436
2437+ /**
2438+ * Convenience method to reduce cognitive complexity of quote()
2439+ * @param w The Writer to which the quoted string will be appended.
2440+ * @param c Character to write
2441+ * @throws IOException
2442+ */
2443+ private static void writeAsHex (Writer w , char c ) throws IOException {
2444+ String hhhh ;
2445+ if (c < ' ' || (c >= '\u0080' && c < '\u00a0' )
2446+ || (c >= '\u2000' && c < '\u2100' )) {
2447+ w .write ("\\ u" );
2448+ hhhh = Integer .toHexString (c );
2449+ w .write ("0000" , 0 , 4 - hhhh .length ());
2450+ w .write (hhhh );
2451+ } else {
2452+ w .write (c );
2453+ }
2454+ }
2455+
24452456 /**
24462457 * Remove a name and its value, if present.
24472458 *
@@ -2470,42 +2481,46 @@ public boolean similar(Object other) {
24702481 if (!this .keySet ().equals (((JSONObject )other ).keySet ())) {
24712482 return false ;
24722483 }
2473- for (final Entry <String ,?> entry : this .entrySet ()) {
2474- String name = entry .getKey ();
2475- Object valueThis = entry .getValue ();
2476- Object valueOther = ((JSONObject )other ).get (name );
2477- if (valueThis == valueOther ) {
2478- continue ;
2479- }
2480- if (valueThis == null ) {
2481- return false ;
2482- }
2483- if (valueThis instanceof JSONObject ) {
2484- if (!((JSONObject )valueThis ).similar (valueOther )) {
2485- return false ;
2486- }
2487- } else if (valueThis instanceof JSONArray ) {
2488- if (!((JSONArray )valueThis ).similar (valueOther )) {
2489- return false ;
2490- }
2491- } else if (valueThis instanceof Number && valueOther instanceof Number ) {
2492- if (!isNumberSimilar ((Number )valueThis , (Number )valueOther )) {
2493- return false ;
2494- }
2495- } else if (valueThis instanceof JSONString && valueOther instanceof JSONString ) {
2496- if (!((JSONString ) valueThis ).toJSONString ().equals (((JSONString ) valueOther ).toJSONString ())) {
2497- return false ;
2498- }
2499- } else if (!valueThis .equals (valueOther )) {
2500- return false ;
2501- }
2502- }
2503- return true ;
2484+ return checkSimilarEntries (other );
25042485 } catch (Throwable exception ) {
25052486 return false ;
25062487 }
25072488 }
25082489
2490+ private boolean checkSimilarEntries (Object other ) {
2491+ for (final Entry <String ,?> entry : this .entrySet ()) {
2492+ String name = entry .getKey ();
2493+ Object valueThis = entry .getValue ();
2494+ Object valueOther = ((JSONObject )other ).get (name );
2495+ if (valueThis == valueOther ) {
2496+ continue ;
2497+ }
2498+ if (valueThis == null ) {
2499+ return false ;
2500+ }
2501+
2502+ if (!checkThis (valueThis , valueOther )) {
2503+ return false ;
2504+ }
2505+ }
2506+ return true ;
2507+ }
2508+
2509+ private boolean checkThis (Object valueThis , Object valueOther ) {
2510+ if (valueThis instanceof JSONObject ) {
2511+ return ((JSONObject )valueThis ).similar (valueOther );
2512+ } else if (valueThis instanceof JSONArray ) {
2513+ return ((JSONArray )valueThis ).similar (valueOther );
2514+ } else if (valueThis instanceof Number && valueOther instanceof Number ) {
2515+ return isNumberSimilar ((Number )valueThis , (Number )valueOther );
2516+ } else if (valueThis instanceof JSONString && valueOther instanceof JSONString ) {
2517+ return ((JSONString ) valueThis ).toJSONString ().equals (((JSONString ) valueOther ).toJSONString ());
2518+ } else if (!valueThis .equals (valueOther )) {
2519+ return false ;
2520+ }
2521+ return true ;
2522+ }
2523+
25092524 /**
25102525 * Compares two numbers to see if they are similar.
25112526 *
@@ -2911,28 +2926,15 @@ static final Writer writeValue(Writer writer, Object value,
29112926 if (value == null || value .equals (null )) {
29122927 writer .write ("null" );
29132928 } else if (value instanceof JSONString ) {
2914- // JSONString must be checked first, so it can overwrite behaviour of other types below
2915- Object o ;
2916- try {
2917- o = ((JSONString ) value ).toJSONString ();
2918- } catch (Exception e ) {
2919- throw new JSONException (e );
2920- }
2921- writer .write (o != null ? o .toString () : quote (value .toString ()));
2929+ // may throw an exception
2930+ processJsonStringToWriteValue (writer , value );
29222931 } else if (value instanceof String ) {
29232932 // assuming most values are Strings, so testing it early
29242933 quote (value .toString (), writer );
29252934 return writer ;
29262935 } else if (value instanceof Number ) {
2927- // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
2928- final String numberAsString = numberToString ((Number ) value );
2929- if (NUMBER_PATTERN .matcher (numberAsString ).matches ()) {
2930- writer .write (numberAsString );
2931- } else {
2932- // The Number value is not a valid JSON number.
2933- // Instead we will quote it as a string
2934- quote (numberAsString , writer );
2935- }
2936+ // may throw an exception
2937+ processNumberToWriteValue (writer , (Number ) value );
29362938 } else if (value instanceof Boolean ) {
29372939 writer .write (value .toString ());
29382940 } else if (value instanceof Enum <?>) {
@@ -2955,6 +2957,41 @@ static final Writer writeValue(Writer writer, Object value,
29552957 return writer ;
29562958 }
29572959
2960+ /**
2961+ * Convenience function to reduce cog complexity of calling method; writes value if string is valid
2962+ * @param writer Object doing the writing
2963+ * @param value Value to be written
2964+ * @throws IOException if something goes wrong
2965+ */
2966+ private static void processJsonStringToWriteValue (Writer writer , Object value ) throws IOException {
2967+ // JSONString must be checked first, so it can overwrite behaviour of other types below
2968+ Object o ;
2969+ try {
2970+ o = ((JSONString ) value ).toJSONString ();
2971+ } catch (Exception e ) {
2972+ throw new JSONException (e );
2973+ }
2974+ writer .write (o != null ? o .toString () : quote (value .toString ()));
2975+ }
2976+
2977+ /**
2978+ * Convenience function to reduce cog complexity of calling method; writes value if number is valid
2979+ * @param writer Object doing the writing
2980+ * @param value Value to be written
2981+ * @throws IOException if something goes wrong
2982+ */
2983+ private static void processNumberToWriteValue (Writer writer , Number value ) throws IOException {
2984+ // not all Numbers may match actual JSON Numbers. i.e. fractions or Imaginary
2985+ final String numberAsString = numberToString (value );
2986+ if (NUMBER_PATTERN .matcher (numberAsString ).matches ()) {
2987+ writer .write (numberAsString );
2988+ } else {
2989+ // The Number value is not a valid JSON number.
2990+ // Instead we will quote it as a string
2991+ quote (numberAsString , writer );
2992+ }
2993+ }
2994+
29582995 static final void indent (Writer writer , int indent ) throws IOException {
29592996 for (int i = 0 ; i < indent ; i += 1 ) {
29602997 writer .write (' ' );
@@ -3004,11 +3041,8 @@ public Writer write(Writer writer, int indentFactor, int indent)
30043041 if (indentFactor > 0 ) {
30053042 writer .write (' ' );
30063043 }
3007- try {
3008- writeValue (writer , entry .getValue (), indentFactor , indent );
3009- } catch (Exception e ) {
3010- throw new JSONException ("Unable to write JSONObject value for key: " + key , e );
3011- }
3044+ // might throw an exception
3045+ attemptWriteValue (writer , indentFactor , indent , entry , key );
30123046 } else if (length != 0 ) {
30133047 final int newIndent = indent + indentFactor ;
30143048 for (final Entry <String ,?> entry : this .entrySet ()) {
@@ -3025,11 +3059,7 @@ public Writer write(Writer writer, int indentFactor, int indent)
30253059 if (indentFactor > 0 ) {
30263060 writer .write (' ' );
30273061 }
3028- try {
3029- writeValue (writer , entry .getValue (), indentFactor , newIndent );
3030- } catch (Exception e ) {
3031- throw new JSONException ("Unable to write JSONObject value for key: " + key , e );
3032- }
3062+ attemptWriteValue (writer , indentFactor , newIndent , entry , key );
30333063 needsComma = true ;
30343064 }
30353065 if (indentFactor > 0 ) {
@@ -3044,6 +3074,30 @@ public Writer write(Writer writer, int indentFactor, int indent)
30443074 }
30453075 }
30463076
3077+ /**
3078+ * Convenience function. Writer attempts to write a value.
3079+ * @param writer
3080+ * Writes the serialized JSON
3081+ * @param indentFactor
3082+ * The number of spaces to add to each level of indentation.
3083+ * @param indent
3084+ * The indentation of the top level.
3085+ * @param entry
3086+ * Contains the value being written
3087+ * @param key
3088+ * Identifies the value
3089+ * @throws JSONException if a called function has an error or a write error
3090+ * occurs
3091+
3092+ */
3093+ private static void attemptWriteValue (Writer writer , int indentFactor , int indent , Entry <String , ?> entry , String key ) {
3094+ try {
3095+ writeValue (writer , entry .getValue (), indentFactor , indent );
3096+ } catch (Exception e ) {
3097+ throw new JSONException ("Unable to write JSONObject value for key: " + key , e );
3098+ }
3099+ }
3100+
30473101 /**
30483102 * Returns a java.util.Map containing all of the entries in this object.
30493103 * If an entry in the object is a JSONArray or JSONObject it will also
0 commit comments