33import java .util .HashMap ;
44import java .util .Map ;
55
6+ /**
7+ * Utility class for escaping strings for safe inclusion in JSON.
8+ *
9+ * <p>Replaces control characters, special characters, and Unicode ranges with appropriate escape
10+ * sequences to produce valid JSON string literals.
11+ */
612final class JsonEscape {
713
14+ /** Mapping of characters to their JSON escape sequences. */
815 private static final Map <Character , String > REPLACEMENTS = new HashMap <>();
916
1017 static {
@@ -18,6 +25,18 @@ final class JsonEscape {
1825 REPLACEMENTS .put ('/' , "\\ /" );
1926 }
2027
28+ /** Private constructor to prevent instantiation. */
29+ private JsonEscape () {}
30+
31+ /**
32+ * Escapes the given string for inclusion in JSON.
33+ *
34+ * <p>Replaces control characters, special characters, and certain Unicode ranges with appropriate
35+ * escape sequences.
36+ *
37+ * @param value the string to escape
38+ * @return the escaped string
39+ */
2140 static String escape (String value ) {
2241 StringBuilder result = new StringBuilder ();
2342
@@ -34,24 +53,56 @@ static String escape(String value) {
3453 return result .toString ();
3554 }
3655
56+ /**
57+ * Determines if the character should be replaced using a predefined escape sequence.
58+ *
59+ * @param character the character to check
60+ * @return true if the character has a predefined replacement
61+ */
3762 private static boolean shouldBeReplaced (char character ) {
3863 return REPLACEMENTS .containsKey (character );
3964 }
4065
66+ /**
67+ * Appends the JSON escape sequence for a character that has a predefined replacement.
68+ *
69+ * @param result the StringBuilder to append to
70+ * @param character the character to escape
71+ */
4172 private static void replace (StringBuilder result , char character ) {
4273 result .append (REPLACEMENTS .get (character ));
4374 }
4475
76+ /**
77+ * Determines if the character should be escaped using a Unicode hexadecimal escape.
78+ *
79+ * <p>Characters that are control characters or in certain Unicode ranges are escaped.
80+ *
81+ * @param character the character to check
82+ * @return true if the character should be represented as a Unicode escape
83+ */
4584 private static boolean shouldBeHexed (char character ) {
4685 return character <= '\u001F'
4786 || character >= '\u007F' && character <= '\u009F'
4887 || character >= '\u2000' && character <= '\u20FF' ;
4988 }
5089
90+ /**
91+ * Appends the Unicode hexadecimal escape sequence for the given character to the result.
92+ *
93+ * <p>The escape sequence is in the format {@code "\\uXXXX"}, where {@code "XXXX"} is the
94+ * uppercase hexadecimal representation of the character code, padded with leading zeros to four
95+ * digits.
96+ *
97+ * @param result the StringBuilder to append the escape sequence to
98+ * @param character the character to be escaped
99+ */
51100 private static void hex (StringBuilder result , char character ) {
52- String hexedCharacter = Integer .toHexString (character );
101+ String hexedCharacter = Integer .toHexString (character ). toUpperCase () ;
53102 result .append ("\\ u" );
54- result .append ("0" .repeat (4 - hexedCharacter .length ()));
55- result .append (hexedCharacter .toUpperCase ());
103+ for (int i = 0 ; i < 4 - hexedCharacter .length (); i ++) {
104+ result .append ('0' );
105+ }
106+ result .append (hexedCharacter );
56107 }
57108}
0 commit comments