Skip to content

Commit e22bec6

Browse files
authored
Merge pull request #19 from fpatron/skip-nl-ws
only process required bytes
2 parents b934c54 + 3c809c8 commit e22bec6

4 files changed

Lines changed: 62 additions & 82 deletions

File tree

jsonc.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,45 +18,42 @@ func stripComments(data []byte) []byte {
1818
)
1919

2020
state := OUTSIDE
21-
result := make([]byte, len(data))
22-
copy(result, data)
21+
result := make([]byte, 0, len(data))
2322

24-
for i := 0; i < len(result); i++ {
23+
for i := 0; i < len(data); i++ {
2524
switch state {
2625
case OUTSIDE:
2726
if data[i] == '/' && i+1 < len(data) {
2827
if data[i+1] == '/' {
2928
state = SINGLE_LINE
30-
result[i] = ' '
31-
result[i+1] = ' '
3229
i++
3330
} else if data[i+1] == '*' {
3431
state = MULTI_LINE
35-
result[i] = ' '
36-
result[i+1] = ' '
3732
i++
33+
} else {
34+
result = append(result, data[i])
3835
}
39-
} else if data[i] == '"' {
40-
state = IN_STRING
36+
} else {
37+
if data[i] == '"' {
38+
state = IN_STRING
39+
}
40+
result = append(result, data[i])
4141
}
4242
case SINGLE_LINE:
4343
if data[i] == '\n' {
4444
state = OUTSIDE
45-
} else {
46-
result[i] = ' '
45+
result = append(result, '\n')
4746
}
4847
case MULTI_LINE:
49-
if data[i] == '*' && i+1 < len(result) && data[i+1] == '/' {
48+
if data[i] == '*' && i+1 < len(data) && data[i+1] == '/' {
5049
state = OUTSIDE
51-
result[i] = ' '
52-
result[i+1] = ' '
5350
i++
54-
} else if result[i] != '\n' {
55-
result[i] = ' '
5651
}
5752
case IN_STRING:
53+
result = append(result, data[i])
5854
if data[i] == '\\' && i+1 < len(data) {
5955
i++
56+
result = append(result, data[i])
6057
} else if data[i] == '"' {
6158
state = OUTSIDE
6259
}

jsonc_test.go

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -82,56 +82,49 @@ func TestStripComments(t *testing.T) {
8282
{
8383
name: "Single line comment",
8484
input: `{"name": "Alice"} // Comment`,
85-
expected: `{"name": "Alice"} `,
85+
expected: `{"name": "Alice"} `,
8686
},
8787
{
8888
name: "Multi-line comment",
8989
input: `{"name": "Alice" /* Comment */}`,
90-
expected: `{"name": "Alice" }`,
90+
expected: `{"name": "Alice" }`,
9191
},
9292
{
9393
name: "Nested comments",
9494
input: `{"name": "Alice" /* Comment // Nested comment */}`,
95-
expected: `{"name": "Alice" }`,
95+
expected: `{"name": "Alice" }`,
9696
},
9797
{
9898
name: "Comment at the end of file without newline",
9999
input: `{"name": "Alice"} // Comment`,
100-
expected: `{"name": "Alice"} `,
100+
expected: `{"name": "Alice"} `,
101101
},
102102
{
103103
name: "Comment at the end of file with newline",
104104
input: `{"name": "Alice"} // Comment
105105
`,
106-
expected: `{"name": "Alice"}
107-
`,
106+
expected: "{\"name\": \"Alice\"} \n",
108107
},
109108
{
110109
name: "Multiple single line comments",
111110
input: `// Comment 1
112111
// Comment 2
113112
{"name": "Alice"}`,
114-
expected: `
115-
116-
{"name": "Alice"}`,
113+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
117114
},
118115
{
119116
name: "Multiple multi-line comments",
120117
input: `/* Comment 1 */
121118
/* Comment 2 */
122119
{"name": "Alice"}`,
123-
expected: `
124-
125-
{"name": "Alice"}`,
120+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
126121
},
127122
{
128123
name: "Mixed comments",
129124
input: `/* Comment 1 */
130125
// Comment 2
131126
{"name": "Alice"}`,
132-
expected: `
133-
134-
{"name": "Alice"}`,
127+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
135128
},
136129
{
137130
name: "No comments",
@@ -151,12 +144,12 @@ func TestStripComments(t *testing.T) {
151144
{
152145
name: "Comment slashes inside string followed by actual comment",
153146
input: `{"name": "//Alice"} // Comment`,
154-
expected: `{"name": "//Alice"} `,
147+
expected: `{"name": "//Alice"} `,
155148
},
156149
{
157150
name: "Multi-line comment delimiters inside string",
158151
input: `{"name": "/*Alice*/"} /* Comment */`,
159-
expected: `{"name": "/*Alice*/"} `,
152+
expected: `{"name": "/*Alice*/"} `,
160153
},
161154
{
162155
name: "Empty input",
@@ -166,22 +159,22 @@ func TestStripComments(t *testing.T) {
166159
{
167160
name: "Only single line comment",
168161
input: `// Comment`,
169-
expected: ` `,
162+
expected: ``,
170163
},
171164
{
172165
name: "Only multi-line comment",
173166
input: `/* Comment */`,
174-
expected: ` `,
167+
expected: ``,
175168
},
176169
{
177170
name: "Comment after a comma",
178171
input: `{"name": "Alice", /* Comment */ "age": 30}`,
179-
expected: `{"name": "Alice", "age": 30}`,
172+
expected: `{"name": "Alice", "age": 30}`,
180173
},
181174
{
182175
name: "Comment inside array",
183176
input: `["Alice", /* Comment */ "Bob"]`,
184-
expected: `["Alice", "Bob"]`,
177+
expected: `["Alice", "Bob"]`,
185178
},
186179
{
187180
name: "Newline inside string",
@@ -195,19 +188,19 @@ func TestStripComments(t *testing.T) {
195188
input: `{"message": "Hello
196189
World"} // Comment`,
197190
expected: `{"message": "Hello
198-
World"} `,
191+
World"} `,
199192
},
200193
{
201194
name: "Newline inside string with multi-line comment after",
202195
input: `{"message": "Hello
203196
World"} /* Comment */`,
204197
expected: `{"message": "Hello
205-
World"} `,
198+
World"} `,
206199
},
207200
{
208201
name: "Multiple newlines inside string & single comment at the end",
209202
input: "{\"message\": \"Hello\n\nWorld\"}// ",
210-
expected: "{\"message\": \"Hello\n\nWorld\"} ",
203+
expected: "{\"message\": \"Hello\n\nWorld\"}",
211204
},
212205
{
213206
name: "Newline inside string with actual newline after",
@@ -216,7 +209,7 @@ World"}
216209
// Comment`,
217210
expected: `{"message": "Hello
218211
World"}
219-
`,
212+
`,
220213
},
221214
}
222215

v2/jsonc.go

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,42 @@ func stripComments(data []byte) []byte {
1616
)
1717

1818
state := OUTSIDE
19-
result := make([]byte, len(data))
20-
copy(result, data)
19+
result := make([]byte, 0, len(data))
2120

22-
for i := 0; i < len(result); i++ {
21+
for i := 0; i < len(data); i++ {
2322
switch state {
2423
case OUTSIDE:
2524
if data[i] == '/' && i+1 < len(data) {
2625
if data[i+1] == '/' {
2726
state = SINGLE_LINE
28-
result[i] = ' '
29-
result[i+1] = ' '
3027
i++
3128
} else if data[i+1] == '*' {
3229
state = MULTI_LINE
33-
result[i] = ' '
34-
result[i+1] = ' '
3530
i++
31+
} else {
32+
result = append(result, data[i])
3633
}
37-
} else if data[i] == '"' {
38-
state = IN_STRING
34+
} else {
35+
if data[i] == '"' {
36+
state = IN_STRING
37+
}
38+
result = append(result, data[i])
3939
}
4040
case SINGLE_LINE:
4141
if data[i] == '\n' {
4242
state = OUTSIDE
43-
} else {
44-
result[i] = ' '
43+
result = append(result, '\n')
4544
}
4645
case MULTI_LINE:
47-
if data[i] == '*' && i+1 < len(result) && data[i+1] == '/' {
46+
if data[i] == '*' && i+1 < len(data) && data[i+1] == '/' {
4847
state = OUTSIDE
49-
result[i] = ' '
50-
result[i+1] = ' '
5148
i++
52-
} else if result[i] != '\n' {
53-
result[i] = ' '
5449
}
5550
case IN_STRING:
51+
result = append(result, data[i])
5652
if data[i] == '\\' && i+1 < len(data) {
5753
i++
54+
result = append(result, data[i])
5855
} else if data[i] == '"' {
5956
state = OUTSIDE
6057
}

v2/jsonc_test.go

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -78,56 +78,49 @@ func TestStripComments(t *testing.T) {
7878
{
7979
name: "Single line comment",
8080
input: `{"name": "Alice"} // Comment`,
81-
expected: `{"name": "Alice"} `,
81+
expected: `{"name": "Alice"} `,
8282
},
8383
{
8484
name: "Multi-line comment",
8585
input: `{"name": "Alice" /* Comment */}`,
86-
expected: `{"name": "Alice" }`,
86+
expected: `{"name": "Alice" }`,
8787
},
8888
{
8989
name: "Nested comments",
9090
input: `{"name": "Alice" /* Comment // Nested comment */}`,
91-
expected: `{"name": "Alice" }`,
91+
expected: `{"name": "Alice" }`,
9292
},
9393
{
9494
name: "Comment at the end of file without newline",
9595
input: `{"name": "Alice"} // Comment`,
96-
expected: `{"name": "Alice"} `,
96+
expected: `{"name": "Alice"} `,
9797
},
9898
{
9999
name: "Comment at the end of file with newline",
100100
input: `{"name": "Alice"} // Comment
101101
`,
102-
expected: `{"name": "Alice"}
103-
`,
102+
expected: "{\"name\": \"Alice\"} \n",
104103
},
105104
{
106105
name: "Multiple single line comments",
107106
input: `// Comment 1
108107
// Comment 2
109108
{"name": "Alice"}`,
110-
expected: `
111-
112-
{"name": "Alice"}`,
109+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
113110
},
114111
{
115112
name: "Multiple multi-line comments",
116113
input: `/* Comment 1 */
117114
/* Comment 2 */
118115
{"name": "Alice"}`,
119-
expected: `
120-
121-
{"name": "Alice"}`,
116+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
122117
},
123118
{
124119
name: "Mixed comments",
125120
input: `/* Comment 1 */
126121
// Comment 2
127122
{"name": "Alice"}`,
128-
expected: `
129-
130-
{"name": "Alice"}`,
123+
expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}",
131124
},
132125
{
133126
name: "No comments",
@@ -147,12 +140,12 @@ func TestStripComments(t *testing.T) {
147140
{
148141
name: "Comment slashes inside string followed by actual comment",
149142
input: `{"name": "//Alice"} // Comment`,
150-
expected: `{"name": "//Alice"} `,
143+
expected: `{"name": "//Alice"} `,
151144
},
152145
{
153146
name: "Multi-line comment delimiters inside string",
154147
input: `{"name": "/*Alice*/"} /* Comment */`,
155-
expected: `{"name": "/*Alice*/"} `,
148+
expected: `{"name": "/*Alice*/"} `,
156149
},
157150
{
158151
name: "Empty input",
@@ -162,22 +155,22 @@ func TestStripComments(t *testing.T) {
162155
{
163156
name: "Only single line comment",
164157
input: `// Comment`,
165-
expected: ` `,
158+
expected: ``,
166159
},
167160
{
168161
name: "Only multi-line comment",
169162
input: `/* Comment */`,
170-
expected: ` `,
163+
expected: ``,
171164
},
172165
{
173166
name: "Comment after a comma",
174167
input: `{"name": "Alice", /* Comment */ "age": 30}`,
175-
expected: `{"name": "Alice", "age": 30}`,
168+
expected: `{"name": "Alice", "age": 30}`,
176169
},
177170
{
178171
name: "Comment inside array",
179172
input: `["Alice", /* Comment */ "Bob"]`,
180-
expected: `["Alice", "Bob"]`,
173+
expected: `["Alice", "Bob"]`,
181174
},
182175
{
183176
name: "Newline inside string",
@@ -191,19 +184,19 @@ func TestStripComments(t *testing.T) {
191184
input: `{"message": "Hello
192185
World"} // Comment`,
193186
expected: `{"message": "Hello
194-
World"} `,
187+
World"} `,
195188
},
196189
{
197190
name: "Newline inside string with multi-line comment after",
198191
input: `{"message": "Hello
199192
World"} /* Comment */`,
200193
expected: `{"message": "Hello
201-
World"} `,
194+
World"} `,
202195
},
203196
{
204197
name: "Multiple newlines inside string & single comment at the end",
205198
input: "{\"message\": \"Hello\n\nWorld\"}// ",
206-
expected: "{\"message\": \"Hello\n\nWorld\"} ",
199+
expected: "{\"message\": \"Hello\n\nWorld\"}",
207200
},
208201
{
209202
name: "Newline inside string with actual newline after",
@@ -212,7 +205,7 @@ World"}
212205
// Comment`,
213206
expected: `{"message": "Hello
214207
World"}
215-
`,
208+
`,
216209
},
217210
}
218211

0 commit comments

Comments
 (0)