Skip to content

Commit 8550175

Browse files
authored
Merge pull request stleary#856 from michael-ameri/custom-delimiter
add ability for custom delimiters
2 parents 010e83b + 72214f1 commit 8550175

File tree

2 files changed

+164
-79
lines changed

2 files changed

+164
-79
lines changed

src/main/java/org/json/CDL.java

Lines changed: 125 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55
*/
66

77
/**
8-
* This provides static methods to convert comma delimited text into a
9-
* JSONArray, and to convert a JSONArray into comma delimited text. Comma
8+
* This provides static methods to convert comma (or otherwise) delimited text into a
9+
* JSONArray, and to convert a JSONArray into comma (or otherwise) delimited text. Comma
1010
* delimited text is a very popular format for data interchange. It is
1111
* understood by most database, spreadsheet, and organizer programs.
1212
* <p>
1313
* Each row of text represents a row in a table or a data record. Each row
1414
* ends with a NEWLINE character. Each row contains one or more values.
1515
* Values are separated by commas. A value can contain any character except
16-
* for comma, unless is is wrapped in single quotes or double quotes.
16+
* for comma, unless it is wrapped in single quotes or double quotes.
1717
* <p>
1818
* The first row usually contains the names of the columns.
1919
* <p>
@@ -29,50 +29,48 @@ public class CDL {
2929
* Get the next value. The value can be wrapped in quotes. The value can
3030
* be empty.
3131
* @param x A JSONTokener of the source text.
32+
* @param delimiter used in the file
3233
* @return The value string, or null if empty.
3334
* @throws JSONException if the quoted string is badly formed.
3435
*/
35-
private static String getValue(JSONTokener x) throws JSONException {
36+
private static String getValue(JSONTokener x, char delimiter) throws JSONException {
3637
char c;
3738
char q;
3839
StringBuilder sb;
3940
do {
4041
c = x.next();
4142
} while (c == ' ' || c == '\t');
42-
switch (c) {
43-
case 0:
44-
return null;
45-
case '"':
46-
case '\'':
47-
q = c;
48-
sb = new StringBuilder();
49-
for (;;) {
50-
c = x.next();
51-
if (c == q) {
52-
//Handle escaped double-quote
53-
char nextC = x.next();
54-
if(nextC != '\"') {
55-
// if our quote was the end of the file, don't step
56-
if(nextC > 0) {
57-
x.back();
58-
}
59-
break;
60-
}
61-
}
62-
if (c == 0 || c == '\n' || c == '\r') {
63-
throw x.syntaxError("Missing close quote '" + q + "'.");
64-
}
65-
sb.append(c);
66-
}
67-
return sb.toString();
68-
case ',':
69-
x.back();
70-
return "";
71-
default:
72-
x.back();
73-
return x.nextTo(',');
74-
}
75-
}
43+
if (c == 0) {
44+
return null;
45+
} else if (c == '"' || c == '\'') {
46+
q = c;
47+
sb = new StringBuilder();
48+
for (;;) {
49+
c = x.next();
50+
if (c == q) {
51+
//Handle escaped double-quote
52+
char nextC = x.next();
53+
if (nextC != '\"') {
54+
// if our quote was the end of the file, don't step
55+
if (nextC > 0) {
56+
x.back();
57+
}
58+
break;
59+
}
60+
}
61+
if (c == 0 || c == '\n' || c == '\r') {
62+
throw x.syntaxError("Missing close quote '" + q + "'.");
63+
}
64+
sb.append(c);
65+
}
66+
return sb.toString();
67+
} else if (c == delimiter) {
68+
x.back();
69+
return "";
70+
}
71+
x.back();
72+
return x.nextTo(delimiter);
73+
}
7674

7775
/**
7876
* Produce a JSONArray of strings from a row of comma delimited values.
@@ -81,17 +79,25 @@ private static String getValue(JSONTokener x) throws JSONException {
8179
* @throws JSONException if a called function fails
8280
*/
8381
public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
82+
return rowToJSONArray(x, ',');
83+
}
84+
85+
/**
86+
* Same as {@link #rowToJSONArray(JSONTokener)}, but with a custom delimiter.
87+
* @see #rowToJSONArray(JSONTokener)
88+
*/
89+
public static JSONArray rowToJSONArray(JSONTokener x, char delimiter) throws JSONException {
8490
JSONArray ja = new JSONArray();
8591
for (;;) {
86-
String value = getValue(x);
92+
String value = getValue(x,delimiter);
8793
char c = x.next();
8894
if (value == null ||
89-
(ja.length() == 0 && value.length() == 0 && c != ',')) {
95+
(ja.length() == 0 && value.length() == 0 && c != delimiter)) {
9096
return null;
9197
}
9298
ja.put(value);
9399
for (;;) {
94-
if (c == ',') {
100+
if (c == delimiter) {
95101
break;
96102
}
97103
if (c != ' ') {
@@ -116,9 +122,17 @@ public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
116122
* @return A JSONObject combining the names and values.
117123
* @throws JSONException if a called function fails
118124
*/
119-
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
120-
throws JSONException {
121-
JSONArray ja = rowToJSONArray(x);
125+
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x) throws JSONException {
126+
return rowToJSONObject(names, x, ',');
127+
}
128+
129+
/**
130+
* Same as {@link #rowToJSONObject(JSONArray, JSONTokener)}, but with a custom {@code delimiter}.
131+
*
132+
* @see #rowToJSONObject(JSONArray, JSONTokener)
133+
*/
134+
public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x, char delimiter) throws JSONException {
135+
JSONArray ja = rowToJSONArray(x, delimiter);
122136
return ja != null ? ja.toJSONObject(names) : null;
123137
}
124138

@@ -130,15 +144,23 @@ public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
130144
* @return A string ending in NEWLINE.
131145
*/
132146
public static String rowToString(JSONArray ja) {
147+
return rowToString(ja, ',');
148+
}
149+
150+
/**
151+
* Same as {@link #rowToString(JSONArray)}, but with a custom delimiter.
152+
* @see #rowToString(JSONArray)
153+
*/
154+
public static String rowToString(JSONArray ja, char delimiter) {
133155
StringBuilder sb = new StringBuilder();
134156
for (int i = 0; i < ja.length(); i += 1) {
135157
if (i > 0) {
136-
sb.append(',');
158+
sb.append(delimiter);
137159
}
138160
Object object = ja.opt(i);
139161
if (object != null) {
140162
String string = object.toString();
141-
if (string.length() > 0 && (string.indexOf(',') >= 0 ||
163+
if (string.length() > 0 && (string.indexOf(delimiter) >= 0 ||
142164
string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
143165
string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
144166
sb.append('"');
@@ -167,7 +189,15 @@ public static String rowToString(JSONArray ja) {
167189
* @throws JSONException if a called function fails
168190
*/
169191
public static JSONArray toJSONArray(String string) throws JSONException {
170-
return toJSONArray(new JSONTokener(string));
192+
return toJSONArray(string, ',');
193+
}
194+
195+
/**
196+
* Same as {@link #toJSONArray(String)}, but with a custom delimiter.
197+
* @see #toJSONArray(String)
198+
*/
199+
public static JSONArray toJSONArray(String string, char delimiter) throws JSONException {
200+
return toJSONArray(new JSONTokener(string), delimiter);
171201
}
172202

173203
/**
@@ -178,7 +208,15 @@ public static JSONArray toJSONArray(String string) throws JSONException {
178208
* @throws JSONException if a called function fails
179209
*/
180210
public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
181-
return toJSONArray(rowToJSONArray(x), x);
211+
return toJSONArray(x, ',');
212+
}
213+
214+
/**
215+
* Same as {@link #toJSONArray(JSONTokener)}, but with a custom delimiter.
216+
* @see #toJSONArray(JSONTokener)
217+
*/
218+
public static JSONArray toJSONArray(JSONTokener x, char delimiter) throws JSONException {
219+
return toJSONArray(rowToJSONArray(x, delimiter), x, delimiter);
182220
}
183221

184222
/**
@@ -189,9 +227,16 @@ public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
189227
* @return A JSONArray of JSONObjects.
190228
* @throws JSONException if a called function fails
191229
*/
192-
public static JSONArray toJSONArray(JSONArray names, String string)
193-
throws JSONException {
194-
return toJSONArray(names, new JSONTokener(string));
230+
public static JSONArray toJSONArray(JSONArray names, String string) throws JSONException {
231+
return toJSONArray(names, string, ',');
232+
}
233+
234+
/**
235+
* Same as {@link #toJSONArray(JSONArray, String)}, but with a custom delimiter.
236+
* @see #toJSONArray(JSONArray, String)
237+
*/
238+
public static JSONArray toJSONArray(JSONArray names, String string, char delimiter) throws JSONException {
239+
return toJSONArray(names, new JSONTokener(string), delimiter);
195240
}
196241

197242
/**
@@ -202,14 +247,21 @@ public static JSONArray toJSONArray(JSONArray names, String string)
202247
* @return A JSONArray of JSONObjects.
203248
* @throws JSONException if a called function fails
204249
*/
205-
public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
206-
throws JSONException {
250+
public static JSONArray toJSONArray(JSONArray names, JSONTokener x) throws JSONException {
251+
return toJSONArray(names, x, ',');
252+
}
253+
254+
/**
255+
* Same as {@link #toJSONArray(JSONArray, JSONTokener)}, but with a custom delimiter.
256+
* @see #toJSONArray(JSONArray, JSONTokener)
257+
*/
258+
public static JSONArray toJSONArray(JSONArray names, JSONTokener x, char delimiter) throws JSONException {
207259
if (names == null || names.length() == 0) {
208260
return null;
209261
}
210262
JSONArray ja = new JSONArray();
211263
for (;;) {
212-
JSONObject jo = rowToJSONObject(names, x);
264+
JSONObject jo = rowToJSONObject(names, x, delimiter);
213265
if (jo == null) {
214266
break;
215267
}
@@ -231,11 +283,19 @@ public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
231283
* @throws JSONException if a called function fails
232284
*/
233285
public static String toString(JSONArray ja) throws JSONException {
286+
return toString(ja, ',');
287+
}
288+
289+
/**
290+
* Same as {@link #toString(JSONArray)}, but with a custom delimiter.
291+
* @see #toString(JSONArray)
292+
*/
293+
public static String toString(JSONArray ja, char delimiter) throws JSONException {
234294
JSONObject jo = ja.optJSONObject(0);
235295
if (jo != null) {
236296
JSONArray names = jo.names();
237297
if (names != null) {
238-
return rowToString(names) + toString(names, ja);
298+
return rowToString(names, delimiter) + toString(names, ja, delimiter);
239299
}
240300
}
241301
return null;
@@ -250,16 +310,23 @@ public static String toString(JSONArray ja) throws JSONException {
250310
* @return A comma delimited text.
251311
* @throws JSONException if a called function fails
252312
*/
253-
public static String toString(JSONArray names, JSONArray ja)
254-
throws JSONException {
313+
public static String toString(JSONArray names, JSONArray ja) throws JSONException {
314+
return toString(names, ja, ',');
315+
}
316+
317+
/**
318+
* Same as {@link #toString(JSONArray,JSONArray)}, but with a custom delimiter.
319+
* @see #toString(JSONArray,JSONArray)
320+
*/
321+
public static String toString(JSONArray names, JSONArray ja, char delimiter) throws JSONException {
255322
if (names == null || names.length() == 0) {
256323
return null;
257324
}
258325
StringBuilder sb = new StringBuilder();
259326
for (int i = 0; i < ja.length(); i += 1) {
260327
JSONObject jo = ja.optJSONObject(i);
261328
if (jo != null) {
262-
sb.append(rowToString(jo.toJSONArray(names)));
329+
sb.append(rowToString(jo.toJSONArray(names), delimiter));
263330
}
264331
}
265332
return sb.toString();

0 commit comments

Comments
 (0)