Skip to content

Commit

Permalink
serialize support java.sql.Clob, fix issue #644
Browse files Browse the repository at this point in the history
  • Loading branch information
wenshao committed Aug 13, 2022
1 parent 2792c67 commit 7669b0a
Show file tree
Hide file tree
Showing 8 changed files with 625 additions and 3 deletions.
26 changes: 26 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
Expand Down Expand Up @@ -866,6 +867,28 @@ public boolean writeTypeName(byte[] typeName, long typeNameHash) {
throw new JSONException("UnsupportedOperation");
}

public void writeString(Reader reader) {
writeRaw(quote);

try {
char[] chars = new char[2048];
for (; ; ) {
int len = reader.read(chars, 0, chars.length);
if (len < 0) {
break;
}

if (len > 0) {
writeString(chars, 0, len, false);
}
}
} catch (Exception ex) {
throw new JSONException("read string from reader error", ex);
}

writeRaw(quote);
}

public abstract void writeString(String str);

public void writeSymbol(String string) {
Expand Down Expand Up @@ -901,6 +924,8 @@ public void writeString(char[] chars) {
write0('"');
}

protected abstract void writeString(char[] chars, int off, int len, boolean quote);

public abstract void writeLocalDate(LocalDate date);

public abstract void writeLocalDateTime(LocalDateTime dateTime);
Expand Down Expand Up @@ -1152,6 +1177,7 @@ public void flushTo(java.io.Writer to) {
public abstract int flushTo(OutputStream to) throws IOException;

public abstract int flushTo(OutputStream out, Charset charset) throws IOException;

static int MAX_ARRAY_SIZE = 1024 * 1024 * 64; // 64M

public static class Context {
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONWriterJSONB.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,11 @@ protected void write0(char ch) {
throw new JSONException("unsupported operation");
}

@Override
public void writeString(char[] chars, int off, int len, boolean quote) {
throw new JSONException("unsupported operation");
}

@Override
public void writeString(char[] str) {
if (str == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ public void writeString(String str) {
jsonWriter.writeString(str);
}

@Override
public void writeString(char[] chars, int off, int len, boolean quote) {
jsonWriter.writeString(chars, off, len, quote);
}

@Override
public void writeLocalDate(LocalDate date) {
jsonWriter.writeLocalDate(date);
Expand Down
138 changes: 138 additions & 0 deletions core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,144 @@ public void writeString(String str) {
chars[off++] = quote;
}

@Override
public void writeString(char[] str, int offset, int len, boolean quote) {
boolean escapeNoneAscii = (context.features & Feature.EscapeNoneAscii.mask) != 0;

int minCapacity = quote ? this.off + 2 : this.off;
if (escapeNoneAscii) {
minCapacity += len * 6;
} else {
minCapacity += len * 2;
}

if (minCapacity - chars.length > 0) {
int oldCapacity = chars.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
if (newCapacity - MAX_ARRAY_SIZE > 0) {
throw new OutOfMemoryError();
}

// minCapacity is usually close to size, so this is a win:
chars = Arrays.copyOf(chars, newCapacity);
}

if (quote) {
chars[off++] = this.quote;
}

for (int i = offset; i < len; ++i) {
char ch = str[i];
switch (ch) {
case '"':
case '\'':
if (ch == this.quote) {
chars[off++] = '\\';
}
chars[off++] = ch;
break;
case '\\':
chars[off++] = '\\';
chars[off++] = ch;
break;
case '\r':
chars[off++] = '\\';
chars[off++] = 'r';
break;
case '\n':
chars[off++] = '\\';
chars[off++] = 'n';
break;
case '\b':
chars[off++] = '\\';
chars[off++] = 'b';
break;
case '\f':
chars[off++] = '\\';
chars[off++] = 'f';
break;
case '\t':
chars[off++] = '\\';
chars[off++] = 't';
break;
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
chars[off++] = '\\';
chars[off++] = 'u';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = (char) ('0' + (int) ch);
break;
case 11:
case 14:
case 15:
chars[off++] = '\\';
chars[off++] = 'u';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = (char) ('a' + (ch - 10));
break;
case 16:
case 17:
case 18:
case 19:
case 20:
case 21:
case 22:
case 23:
case 24:
case 25:
chars[off++] = '\\';
chars[off++] = 'u';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = '1';
chars[off++] = (char) ('0' + (ch - 16));
break;
case 26:
case 27:
case 28:
case 29:
case 30:
case 31:
chars[off++] = '\\';
chars[off++] = 'u';
chars[off++] = '0';
chars[off++] = '0';
chars[off++] = '1';
chars[off++] = (char) ('a' + (ch - 26));
break;
default:
if (escapeNoneAscii && ch > 0x007F) {
chars[off++] = '\\';
chars[off++] = 'u';
chars[off++] = DIGITS[(ch >>> 12) & 15];
chars[off++] = DIGITS[(ch >>> 8) & 15];
chars[off++] = DIGITS[(ch >>> 4) & 15];
chars[off++] = DIGITS[ch & 15];
} else {
chars[off++] = ch;
}
break;
}
}

if (quote) {
chars[off++] = this.quote;
}
}

@Override
public void writeReference(String path) {
this.lastReference = path;
Expand Down
Loading

0 comments on commit 7669b0a

Please # to comment.