diff --git a/jsonc.go b/jsonc.go index 1930aba..dec6fab 100644 --- a/jsonc.go +++ b/jsonc.go @@ -18,45 +18,42 @@ func stripComments(data []byte) []byte { ) state := OUTSIDE - result := make([]byte, len(data)) - copy(result, data) + result := make([]byte, 0, len(data)) - for i := 0; i < len(result); i++ { + for i := 0; i < len(data); i++ { switch state { case OUTSIDE: if data[i] == '/' && i+1 < len(data) { if data[i+1] == '/' { state = SINGLE_LINE - result[i] = ' ' - result[i+1] = ' ' i++ } else if data[i+1] == '*' { state = MULTI_LINE - result[i] = ' ' - result[i+1] = ' ' i++ + } else { + result = append(result, data[i]) } - } else if data[i] == '"' { - state = IN_STRING + } else { + if data[i] == '"' { + state = IN_STRING + } + result = append(result, data[i]) } case SINGLE_LINE: if data[i] == '\n' { state = OUTSIDE - } else { - result[i] = ' ' + result = append(result, '\n') } case MULTI_LINE: - if data[i] == '*' && i+1 < len(result) && data[i+1] == '/' { + if data[i] == '*' && i+1 < len(data) && data[i+1] == '/' { state = OUTSIDE - result[i] = ' ' - result[i+1] = ' ' i++ - } else if result[i] != '\n' { - result[i] = ' ' } case IN_STRING: + result = append(result, data[i]) if data[i] == '\\' && i+1 < len(data) { i++ + result = append(result, data[i]) } else if data[i] == '"' { state = OUTSIDE } diff --git a/jsonc_test.go b/jsonc_test.go index fa0bbe7..b6e824e 100644 --- a/jsonc_test.go +++ b/jsonc_test.go @@ -82,56 +82,49 @@ func TestStripComments(t *testing.T) { { name: "Single line comment", input: `{"name": "Alice"} // Comment`, - expected: `{"name": "Alice"} `, + expected: `{"name": "Alice"} `, }, { name: "Multi-line comment", input: `{"name": "Alice" /* Comment */}`, - expected: `{"name": "Alice" }`, + expected: `{"name": "Alice" }`, }, { name: "Nested comments", input: `{"name": "Alice" /* Comment // Nested comment */}`, - expected: `{"name": "Alice" }`, + expected: `{"name": "Alice" }`, }, { name: "Comment at the end of file without newline", input: `{"name": "Alice"} // Comment`, - expected: `{"name": "Alice"} `, + expected: `{"name": "Alice"} `, }, { name: "Comment at the end of file with newline", input: `{"name": "Alice"} // Comment `, - expected: `{"name": "Alice"} -`, + expected: "{\"name\": \"Alice\"} \n", }, { name: "Multiple single line comments", input: `// Comment 1 // Comment 2 {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "Multiple multi-line comments", input: `/* Comment 1 */ /* Comment 2 */ {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "Mixed comments", input: `/* Comment 1 */ // Comment 2 {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "No comments", @@ -151,12 +144,12 @@ func TestStripComments(t *testing.T) { { name: "Comment slashes inside string followed by actual comment", input: `{"name": "//Alice"} // Comment`, - expected: `{"name": "//Alice"} `, + expected: `{"name": "//Alice"} `, }, { name: "Multi-line comment delimiters inside string", input: `{"name": "/*Alice*/"} /* Comment */`, - expected: `{"name": "/*Alice*/"} `, + expected: `{"name": "/*Alice*/"} `, }, { name: "Empty input", @@ -166,22 +159,22 @@ func TestStripComments(t *testing.T) { { name: "Only single line comment", input: `// Comment`, - expected: ` `, + expected: ``, }, { name: "Only multi-line comment", input: `/* Comment */`, - expected: ` `, + expected: ``, }, { name: "Comment after a comma", input: `{"name": "Alice", /* Comment */ "age": 30}`, - expected: `{"name": "Alice", "age": 30}`, + expected: `{"name": "Alice", "age": 30}`, }, { name: "Comment inside array", input: `["Alice", /* Comment */ "Bob"]`, - expected: `["Alice", "Bob"]`, + expected: `["Alice", "Bob"]`, }, { name: "Newline inside string", @@ -195,19 +188,19 @@ func TestStripComments(t *testing.T) { input: `{"message": "Hello World"} // Comment`, expected: `{"message": "Hello - World"} `, + World"} `, }, { name: "Newline inside string with multi-line comment after", input: `{"message": "Hello World"} /* Comment */`, expected: `{"message": "Hello - World"} `, + World"} `, }, { name: "Multiple newlines inside string & single comment at the end", input: "{\"message\": \"Hello\n\nWorld\"}// ", - expected: "{\"message\": \"Hello\n\nWorld\"} ", + expected: "{\"message\": \"Hello\n\nWorld\"}", }, { name: "Newline inside string with actual newline after", @@ -216,7 +209,7 @@ World"} // Comment`, expected: `{"message": "Hello World"} - `, +`, }, } diff --git a/v2/jsonc.go b/v2/jsonc.go index 443c96f..9215900 100644 --- a/v2/jsonc.go +++ b/v2/jsonc.go @@ -16,45 +16,42 @@ func stripComments(data []byte) []byte { ) state := OUTSIDE - result := make([]byte, len(data)) - copy(result, data) + result := make([]byte, 0, len(data)) - for i := 0; i < len(result); i++ { + for i := 0; i < len(data); i++ { switch state { case OUTSIDE: if data[i] == '/' && i+1 < len(data) { if data[i+1] == '/' { state = SINGLE_LINE - result[i] = ' ' - result[i+1] = ' ' i++ } else if data[i+1] == '*' { state = MULTI_LINE - result[i] = ' ' - result[i+1] = ' ' i++ + } else { + result = append(result, data[i]) } - } else if data[i] == '"' { - state = IN_STRING + } else { + if data[i] == '"' { + state = IN_STRING + } + result = append(result, data[i]) } case SINGLE_LINE: if data[i] == '\n' { state = OUTSIDE - } else { - result[i] = ' ' + result = append(result, '\n') } case MULTI_LINE: - if data[i] == '*' && i+1 < len(result) && data[i+1] == '/' { + if data[i] == '*' && i+1 < len(data) && data[i+1] == '/' { state = OUTSIDE - result[i] = ' ' - result[i+1] = ' ' i++ - } else if result[i] != '\n' { - result[i] = ' ' } case IN_STRING: + result = append(result, data[i]) if data[i] == '\\' && i+1 < len(data) { i++ + result = append(result, data[i]) } else if data[i] == '"' { state = OUTSIDE } diff --git a/v2/jsonc_test.go b/v2/jsonc_test.go index d6e4be7..70d1855 100644 --- a/v2/jsonc_test.go +++ b/v2/jsonc_test.go @@ -78,56 +78,49 @@ func TestStripComments(t *testing.T) { { name: "Single line comment", input: `{"name": "Alice"} // Comment`, - expected: `{"name": "Alice"} `, + expected: `{"name": "Alice"} `, }, { name: "Multi-line comment", input: `{"name": "Alice" /* Comment */}`, - expected: `{"name": "Alice" }`, + expected: `{"name": "Alice" }`, }, { name: "Nested comments", input: `{"name": "Alice" /* Comment // Nested comment */}`, - expected: `{"name": "Alice" }`, + expected: `{"name": "Alice" }`, }, { name: "Comment at the end of file without newline", input: `{"name": "Alice"} // Comment`, - expected: `{"name": "Alice"} `, + expected: `{"name": "Alice"} `, }, { name: "Comment at the end of file with newline", input: `{"name": "Alice"} // Comment `, - expected: `{"name": "Alice"} -`, + expected: "{\"name\": \"Alice\"} \n", }, { name: "Multiple single line comments", input: `// Comment 1 // Comment 2 {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "Multiple multi-line comments", input: `/* Comment 1 */ /* Comment 2 */ {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "Mixed comments", input: `/* Comment 1 */ // Comment 2 {"name": "Alice"}`, - expected: ` - - {"name": "Alice"}`, + expected: "\n\t\t\t\n\t\t\t{\"name\": \"Alice\"}", }, { name: "No comments", @@ -147,12 +140,12 @@ func TestStripComments(t *testing.T) { { name: "Comment slashes inside string followed by actual comment", input: `{"name": "//Alice"} // Comment`, - expected: `{"name": "//Alice"} `, + expected: `{"name": "//Alice"} `, }, { name: "Multi-line comment delimiters inside string", input: `{"name": "/*Alice*/"} /* Comment */`, - expected: `{"name": "/*Alice*/"} `, + expected: `{"name": "/*Alice*/"} `, }, { name: "Empty input", @@ -162,22 +155,22 @@ func TestStripComments(t *testing.T) { { name: "Only single line comment", input: `// Comment`, - expected: ` `, + expected: ``, }, { name: "Only multi-line comment", input: `/* Comment */`, - expected: ` `, + expected: ``, }, { name: "Comment after a comma", input: `{"name": "Alice", /* Comment */ "age": 30}`, - expected: `{"name": "Alice", "age": 30}`, + expected: `{"name": "Alice", "age": 30}`, }, { name: "Comment inside array", input: `["Alice", /* Comment */ "Bob"]`, - expected: `["Alice", "Bob"]`, + expected: `["Alice", "Bob"]`, }, { name: "Newline inside string", @@ -191,19 +184,19 @@ func TestStripComments(t *testing.T) { input: `{"message": "Hello World"} // Comment`, expected: `{"message": "Hello - World"} `, + World"} `, }, { name: "Newline inside string with multi-line comment after", input: `{"message": "Hello World"} /* Comment */`, expected: `{"message": "Hello - World"} `, + World"} `, }, { name: "Multiple newlines inside string & single comment at the end", input: "{\"message\": \"Hello\n\nWorld\"}// ", - expected: "{\"message\": \"Hello\n\nWorld\"} ", + expected: "{\"message\": \"Hello\n\nWorld\"}", }, { name: "Newline inside string with actual newline after", @@ -212,7 +205,7 @@ World"} // Comment`, expected: `{"message": "Hello World"} - `, +`, }, }