-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for JsonGenerator.Key #47
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -150,6 +150,18 @@ private JsonGenerator writeName(String name) { | |
return this; | ||
} | ||
|
||
private void writeName(Key name) { | ||
writeComma(); | ||
final char[] escaped = name.toCharArray(); | ||
final int required = escaped.length; | ||
if (len + required >= buf.length) { | ||
flushBuffer(); | ||
} | ||
System.arraycopy(escaped, 0, buf, len, required); | ||
len += required; | ||
writeColon(); | ||
} | ||
|
||
@Override | ||
public JsonGenerator write(String name, String fieldValue) { | ||
write(name, (CharSequence) fieldValue); | ||
|
@@ -464,6 +476,19 @@ public JsonGenerator writeKey(String name) { | |
return this; | ||
} | ||
|
||
@Override | ||
public JsonGenerator writeKey(JsonGenerator.Key name) { | ||
if (currentContext.scope != Scope.IN_OBJECT) { | ||
throw new JsonGenerationException( | ||
JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope)); | ||
} | ||
writeName(name); | ||
stack.push(currentContext); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could refactor extract these 4 lines as they are the same as the lines from |
||
currentContext = new Context(Scope.IN_FIELD); | ||
currentContext.first = false; | ||
return this; | ||
} | ||
|
||
@Override | ||
public JsonGenerator writeEnd() { | ||
if (currentContext.scope == Scope.IN_NONE) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
/* | ||
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License v. 2.0, which is available at | ||
* http://www.eclipse.org/legal/epl-2.0. | ||
* | ||
* This Source Code may also be made available under the following Secondary | ||
* Licenses when the conditions for such availability set forth in the | ||
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License, | ||
* version 2 with the GNU Classpath Exception, which is available at | ||
* https://www.gnu.org/software/classpath/license.html. | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 | ||
*/ | ||
|
||
package org.eclipse.parsson; | ||
|
||
import jakarta.json.stream.JsonGenerator; | ||
|
||
final class JsonGeneratorKeyImpl { | ||
|
||
static JsonGenerator.Key createKey(String name) { | ||
return new Key(quoteEscape(name)); | ||
} | ||
|
||
/** | ||
* A key that is already escaped so then can just be written directly. | ||
*/ | ||
private static class Key implements JsonGenerator.Key { | ||
|
||
private final char[] escapedName; | ||
|
||
Key(String escapedName) { | ||
this.escapedName = escapedName.toCharArray(); | ||
} | ||
|
||
@Override | ||
public char[] toCharArray() { | ||
return escapedName; | ||
} | ||
} | ||
|
||
private static String quoteEscape(CharSequence string) { | ||
StringBuilder builder = new StringBuilder(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same escape logic as |
||
builder.append('"'); | ||
int len = string.length(); | ||
for (int i = 0; i < len; i++) { | ||
int begin = i, end = i; | ||
char c = string.charAt(i); | ||
// find all the characters that need not be escaped | ||
// unescaped = %x20-21 | %x23-5B | %x5D-10FFFF | ||
while (c >= 0x20 && c <= 0x10ffff && c != 0x22 && c != 0x5c) { | ||
i++; | ||
end = i; | ||
if (i < len) { | ||
c = string.charAt(i); | ||
} else { | ||
break; | ||
} | ||
} | ||
// Write characters without escaping | ||
if (begin < end) { | ||
builder.append(string, begin, end); | ||
if (i == len) { | ||
break; | ||
} | ||
} | ||
|
||
switch (c) { | ||
case '"': | ||
case '\\': | ||
builder.append('\\'); | ||
builder.append(c); | ||
break; | ||
case '\b': | ||
builder.append('\\'); | ||
builder.append('b'); | ||
break; | ||
case '\f': | ||
builder.append('\\'); | ||
builder.append('f'); | ||
break; | ||
case '\n': | ||
builder.append('\\'); | ||
builder.append('n'); | ||
break; | ||
case '\r': | ||
builder.append('\\'); | ||
builder.append('r'); | ||
break; | ||
case '\t': | ||
builder.append('\\'); | ||
builder.append('t'); | ||
break; | ||
default: | ||
String hex = "000" + Integer.toHexString(c); | ||
builder.append("\\u" + hex.substring(hex.length() - 4)); | ||
} | ||
} | ||
return builder.append('"').toString(); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nb:
char[] escaped
includes the quotes