Skip to content

Commit 4d37e9f

Browse files
committed
Align string generate method with generate_json_string
1 parent be45c9a commit 4d37e9f

File tree

2 files changed

+59
-48
lines changed

2 files changed

+59
-48
lines changed

java/src/json/ext/Generator.java

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -428,57 +428,10 @@ int guessSize(ThreadContext context, Session session, RubyString object) {
428428

429429
@Override
430430
void generate(ThreadContext context, Session session, RubyString object, OutputStream buffer) throws IOException {
431-
try {
432-
object = ensureValidEncoding(context, object);
433-
} catch (RaiseException re) {
434-
RubyException exc = Utils.buildGeneratorError(context, object, re.getMessage());
435-
exc.setCause(re.getException());
436-
throw exc.toThrowable();
437-
}
438-
439-
StringEncoder stringEncoder = session.getStringEncoder(context);
440-
ByteList byteList = object.getByteList();
441-
stringEncoder.init(byteList);
442-
stringEncoder.out = buffer;
443-
stringEncoder.append('"');
444-
switch (object.scanForCodeRange()) {
445-
case StringSupport.CR_7BIT:
446-
stringEncoder.encodeASCII(context, byteList, buffer);
447-
break;
448-
case StringSupport.CR_VALID:
449-
stringEncoder.encode(context, byteList, buffer);
450-
break;
451-
default:
452-
throw Utils.buildGeneratorError(context, object, "source sequence is illegal/malformed utf-8").toThrowable();
453-
}
454-
stringEncoder.quoteStop(stringEncoder.pos);
455-
stringEncoder.append('"');
431+
session.getStringEncoder(context).generate(context, object, buffer);
456432
}
457433
};
458434

459-
static RubyString ensureValidEncoding(ThreadContext context, RubyString str) {
460-
Encoding encoding = str.getEncoding();
461-
RubyString utf8String;
462-
if (!(encoding == USASCIIEncoding.INSTANCE || encoding == UTF8Encoding.INSTANCE)) {
463-
if (encoding == ASCIIEncoding.INSTANCE) {
464-
utf8String = str.strDup(context.runtime);
465-
utf8String.setEncoding(UTF8Encoding.INSTANCE);
466-
switch (utf8String.getCodeRange()) {
467-
case StringSupport.CR_7BIT:
468-
return utf8String;
469-
case StringSupport.CR_VALID:
470-
// For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
471-
// TODO: Raise in 3.0.0
472-
context.runtime.getWarnings().warn("JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0");
473-
return utf8String;
474-
}
475-
}
476-
477-
str = (RubyString) str.encode(context, context.runtime.getEncodingService().convertEncodingToRubyEncoding(UTF8Encoding.INSTANCE));
478-
}
479-
return str;
480-
}
481-
482435
static final Handler<RubyBoolean> TRUE_HANDLER =
483436
new KeywordHandler<>("true");
484437
static final Handler<RubyBoolean> FALSE_HANDLER =

java/src/json/ext/StringEncoder.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,16 @@
55
*/
66
package json.ext;
77

8+
import org.jcodings.Encoding;
9+
import org.jcodings.specific.ASCIIEncoding;
10+
import org.jcodings.specific.USASCIIEncoding;
11+
import org.jcodings.specific.UTF8Encoding;
12+
import org.jruby.RubyException;
13+
import org.jruby.RubyString;
814
import org.jruby.exceptions.RaiseException;
915
import org.jruby.runtime.ThreadContext;
1016
import org.jruby.util.ByteList;
17+
import org.jruby.util.StringSupport;
1118

1219
import java.io.IOException;
1320
import java.io.OutputStream;
@@ -120,6 +127,57 @@ final class StringEncoder extends ByteListTranscoder {
120127
this.scriptSafe = scriptSafe;
121128
}
122129

130+
// C: generate_json_string
131+
void generate(ThreadContext context, RubyString object, OutputStream buffer) throws IOException {
132+
try {
133+
object = ensureValidEncoding(context, object);
134+
} catch (RaiseException re) {
135+
RubyException exc = Utils.buildGeneratorError(context, object, re.getMessage());
136+
exc.setCause(re.getException());
137+
throw exc.toThrowable();
138+
}
139+
140+
ByteList byteList = object.getByteList();
141+
init(byteList);
142+
out = buffer;
143+
append('"');
144+
switch (object.scanForCodeRange()) {
145+
case StringSupport.CR_7BIT:
146+
encodeASCII(context, byteList, buffer);
147+
break;
148+
case StringSupport.CR_VALID:
149+
encode(context, byteList, buffer);
150+
break;
151+
default:
152+
throw Utils.buildGeneratorError(context, object, "source sequence is illegal/malformed utf-8").toThrowable();
153+
}
154+
quoteStop(pos);
155+
append('"');
156+
}
157+
158+
static RubyString ensureValidEncoding(ThreadContext context, RubyString str) {
159+
Encoding encoding = str.getEncoding();
160+
RubyString utf8String;
161+
if (!(encoding == USASCIIEncoding.INSTANCE || encoding == UTF8Encoding.INSTANCE)) {
162+
if (encoding == ASCIIEncoding.INSTANCE) {
163+
utf8String = str.strDup(context.runtime);
164+
utf8String.setEncoding(UTF8Encoding.INSTANCE);
165+
switch (utf8String.getCodeRange()) {
166+
case StringSupport.CR_7BIT:
167+
return utf8String;
168+
case StringSupport.CR_VALID:
169+
// For historical reason, we silently reinterpret binary strings as UTF-8 if it would work.
170+
// TODO: Raise in 3.0.0
171+
context.runtime.getWarnings().warn("JSON.generate: UTF-8 string passed as BINARY, this will raise an encoding error in json 3.0");
172+
return utf8String;
173+
}
174+
}
175+
176+
str = (RubyString) str.encode(context, context.runtime.getEncodingService().convertEncodingToRubyEncoding(UTF8Encoding.INSTANCE));
177+
}
178+
return str;
179+
}
180+
123181
void encode(ThreadContext context, ByteList src, OutputStream out) throws IOException {
124182
while (hasNext()) {
125183
handleChar(readUtf8Char(context));

0 commit comments

Comments
 (0)