This commit is contained in:
redkale
2024-10-16 18:16:41 +08:00
parent a989f1af9f
commit e4bf7432f4
6 changed files with 213 additions and 328 deletions

View File

@@ -85,11 +85,11 @@ public abstract class Writer {
} }
protected final boolean tiny() { protected final boolean tiny() {
return ConvertFactory.checkTinyFeature(features); return features > 0 && ConvertFactory.checkTinyFeature(features);
} }
protected final boolean nullable() { protected final boolean nullable() {
return ConvertFactory.checkNullableFeature(features); return features > 0 && ConvertFactory.checkNullableFeature(features);
} }
/** 输出null值 */ /** 输出null值 */

View File

@@ -384,35 +384,10 @@ public class JsonByteBufferWriter extends JsonWriter {
return writeFieldLatin1Value(fieldBytes, fieldChars, comma, false, String.valueOf(value)); return writeFieldLatin1Value(fieldBytes, fieldChars, comma, false, String.valueOf(value));
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null) {
return comma;
}
byte[] bs1 = fieldBytes;
int expandsize = expand(1 + bs1.length);
if (expandsize == 0) { // 只需要一个buffer
final ByteBuffer buffer = this.buffers[currBufIndex];
if (comma) buffer.put(BYTE_COMMA);
buffer.put(bs1);
} else {
ByteBuffer buffer = this.buffers[currBufIndex];
if (comma) buffer.put(BYTE_COMMA);
for (byte b : bs1) {
if (!buffer.hasRemaining()) {
buffer = nextByteBuffer();
}
buffer.put(b);
}
}
writeString(value);
return true;
}
@Override @Override
public boolean writeFieldObjectValue( public boolean writeFieldObjectValue(
byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) { byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) {
if (value == null) { if (value == null && !nullable()) {
return comma; return comma;
} }
byte[] bs1 = fieldBytes; byte[] bs1 = fieldBytes;
@@ -435,10 +410,35 @@ public class JsonByteBufferWriter extends JsonWriter {
return true; return true;
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null || (tiny() && value.isEmpty())) {
return comma;
}
byte[] bs1 = fieldBytes;
int expandsize = expand(1 + bs1.length);
if (expandsize == 0) { // 只需要一个buffer
final ByteBuffer buffer = this.buffers[currBufIndex];
if (comma) buffer.put(BYTE_COMMA);
buffer.put(bs1);
} else {
ByteBuffer buffer = this.buffers[currBufIndex];
if (comma) buffer.put(BYTE_COMMA);
for (byte b : bs1) {
if (!buffer.hasRemaining()) {
buffer = nextByteBuffer();
}
buffer.put(b);
}
}
writeString(value);
return true;
}
@Override @Override
protected boolean writeFieldLatin1Value( protected boolean writeFieldLatin1Value(
byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) { byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) {
if (value == null) { if (value == null || (tiny() && value.isEmpty())) {
return comma; return comma;
} }
byte[] bs1 = fieldBytes; byte[] bs1 = fieldBytes;

View File

@@ -254,25 +254,10 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
return true; return true;
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null) {
return comma;
}
byte[] bs1 = fieldBytes;
int len1 = bs1.length;
byte[] src = expand(1 + len1);
if (comma) src[count++] = BYTE_COMMA;
System.arraycopy(bs1, 0, src, count, len1);
count += len1;
writeString(value);
return true;
}
@Override @Override
public boolean writeFieldObjectValue( public boolean writeFieldObjectValue(
byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) { byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) {
if (value == null) { if (value == null && !nullable()) {
return comma; return comma;
} }
byte[] bs1 = fieldBytes; byte[] bs1 = fieldBytes;
@@ -285,10 +270,25 @@ public class JsonBytesWriter extends JsonWriter implements ByteTuple {
return true; return true;
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null || (tiny() && value.isEmpty())) {
return comma;
}
byte[] bs1 = fieldBytes;
int len1 = bs1.length;
byte[] src = expand(1 + len1);
if (comma) src[count++] = BYTE_COMMA;
System.arraycopy(bs1, 0, src, count, len1);
count += len1;
writeString(value);
return true;
}
@Override @Override
protected boolean writeFieldLatin1Value( protected boolean writeFieldLatin1Value(
byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) { byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) {
if (value == null) { if (value == null || (tiny() && value.isEmpty())) {
return comma; return comma;
} }
byte[] bs1 = fieldBytes; byte[] bs1 = fieldBytes;

View File

@@ -211,25 +211,10 @@ public class JsonCharsWriter extends JsonWriter {
return true; return true;
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null) {
return comma;
}
char[] bs1 = fieldChars;
int len1 = bs1.length;
char[] src = expand(1 + len1);
if (comma) src[count++] = BYTE_COMMA;
System.arraycopy(bs1, 0, src, count, len1);
count += len1;
writeString(value);
return true;
}
@Override @Override
public boolean writeFieldObjectValue( public boolean writeFieldObjectValue(
byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) { byte[] fieldBytes, char[] fieldChars, boolean comma, Encodeable encodeable, Object value) {
if (value == null) { if (value == null && !nullable()) {
return comma; return comma;
} }
char[] bs1 = fieldChars; char[] bs1 = fieldChars;
@@ -242,10 +227,25 @@ public class JsonCharsWriter extends JsonWriter {
return true; return true;
} }
@Override
public boolean writeFieldStringValue(byte[] fieldBytes, char[] fieldChars, boolean comma, String value) {
if (value == null || (tiny() && value.isEmpty())) {
return comma;
}
char[] bs1 = fieldChars;
int len1 = bs1.length;
char[] src = expand(1 + len1);
if (comma) src[count++] = BYTE_COMMA;
System.arraycopy(bs1, 0, src, count, len1);
count += len1;
writeString(value);
return true;
}
@Override @Override
protected boolean writeFieldLatin1Value( protected boolean writeFieldLatin1Value(
byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) { byte[] fieldBytes, char[] fieldChars, boolean comma, boolean quote, String value) {
if (value == null) { if (value == null || (tiny() && value.isEmpty())) {
return comma; return comma;
} }
char[] bs1 = fieldChars; char[] bs1 = fieldChars;

View File

@@ -113,7 +113,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
} else { } else {
bytesWriterPool.set(null); bytesWriterPool.set(null);
} }
return configWrite((JsonBytesWriter) writer.withFeatures(features)); return configWrite(writer);
} }
@Override @Override
@@ -133,7 +133,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
} else { } else {
bytesWriterPool.set(null); bytesWriterPool.set(null);
} }
return configWrite((JsonBytesWriter) writer.withFeatures(features)); return configWrite(writer);
} }
private void offerJsonBytesWriter(final JsonBytesWriter writer) { private void offerJsonBytesWriter(final JsonBytesWriter writer) {
@@ -150,7 +150,7 @@ public class JsonConvert extends TextConvert<JsonReader, JsonWriter> {
} else { } else {
charsWriterPool.set(null); charsWriterPool.set(null);
} }
return configWrite((JsonCharsWriter) writer.withFeatures(features)); return configWrite(writer);
} }
private void offerJsonCharsWriter(final JsonCharsWriter writer) { private void offerJsonCharsWriter(final JsonCharsWriter writer) {

View File

@@ -52,20 +52,32 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
return null; // 存在ignore等定制配置 return null; // 存在ignore等定制配置
} }
Map<String, AccessibleObject> mixedNames0 = null; final Map<String, AccessibleObject> mixedNames = new HashMap<>();
StringBuilder elementb = new StringBuilder(); StringBuilder elementb = new StringBuilder();
for (AccessibleObject element : elements) { for (AccessibleObject element : elements) {
final String fieldName = factory.readConvertFieldName(clazz, element); final String fieldName = factory.readConvertFieldName(clazz, element);
elementb.append(fieldName).append(','); elementb.append(fieldName).append(',');
final Class fieldType = readGetSetFieldType(element); final Class fieldType = readGetSetFieldType(element);
if (fieldType != String.class && !fieldType.isPrimitive()) { if (fieldType != boolean.class
if (mixedNames0 == null) { && fieldType != byte.class
mixedNames0 = new HashMap<>(); && fieldType != short.class
} && fieldType != char.class
mixedNames0.put(fieldName, element); && fieldType != int.class
&& fieldType != float.class
&& fieldType != long.class
&& fieldType != double.class
&& fieldType != Boolean.class
&& fieldType != Byte.class
&& fieldType != Short.class
&& fieldType != Character.class
&& fieldType != Integer.class
&& fieldType != Float.class
&& fieldType != Long.class
&& fieldType != Double.class
&& fieldType != String.class) {
mixedNames.put(fieldName, element);
} }
} }
final Map<String, AccessibleObject> mixedNames = mixedNames0;
RedkaleClassLoader loader = RedkaleClassLoader.currentClassLoader(); RedkaleClassLoader loader = RedkaleClassLoader.currentClassLoader();
final String newDynName = "org/redkaledyn/convert/json/_Dyn" + JsonDynEncoder.class.getSimpleName() + "__" final String newDynName = "org/redkaledyn/convert/json/_Dyn" + JsonDynEncoder.class.getSimpleName() + "__"
+ clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.getFeatures() + "_" + clazz.getName().replace('.', '_').replace('$', '_') + "_" + factory.getFeatures() + "_"
@@ -75,7 +87,6 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
JsonDynEncoder resultEncoder = JsonDynEncoder resultEncoder =
(JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class) (JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class)
.newInstance(factory, clazz, selfObjEncoder); .newInstance(factory, clazz, selfObjEncoder);
if (mixedNames != null) {
for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) { for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) {
Field f = newClazz.getDeclaredField(en.getKey() + "Encoder"); Field f = newClazz.getDeclaredField(en.getKey() + "Encoder");
f.setAccessible(true); f.setAccessible(true);
@@ -86,7 +97,6 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
? ((Field) en.getValue()).getGenericType() ? ((Field) en.getValue()).getGenericType()
: ((Method) en.getValue()).getGenericReturnType())); : ((Method) en.getValue()).getGenericReturnType()));
} }
}
return resultEncoder; return resultEncoder;
} catch (Throwable ex) { } catch (Throwable ex) {
// do nothing // do nothing
@@ -95,14 +105,13 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
final String supDynName = JsonDynEncoder.class.getName().replace('.', '/'); final String supDynName = JsonDynEncoder.class.getName().replace('.', '/');
final String valtypeName = clazz.getName().replace('.', '/'); final String valtypeName = clazz.getName().replace('.', '/');
final String writerName = JsonWriter.class.getName().replace('.', '/'); final String writerName = JsonWriter.class.getName().replace('.', '/');
final String encodeableName = Encodeable.class.getName().replace('.', '/');
final String objEncoderName = ObjectEncoder.class.getName().replace('.', '/'); final String objEncoderName = ObjectEncoder.class.getName().replace('.', '/');
final String typeDesc = org.redkale.asm.Type.getDescriptor(Type.class); final String typeDesc = org.redkale.asm.Type.getDescriptor(Type.class);
final String jsonfactoryDesc = org.redkale.asm.Type.getDescriptor(JsonFactory.class); final String jsonfactoryDesc = org.redkale.asm.Type.getDescriptor(JsonFactory.class);
final String jsonwriterDesc = org.redkale.asm.Type.getDescriptor(JsonWriter.class); final String jsonwriterDesc = org.redkale.asm.Type.getDescriptor(JsonWriter.class);
final String writerDesc = org.redkale.asm.Type.getDescriptor(Writer.class);
final String encodeableDesc = org.redkale.asm.Type.getDescriptor(Encodeable.class); final String encodeableDesc = org.redkale.asm.Type.getDescriptor(Encodeable.class);
final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class); final String objEncoderDesc = org.redkale.asm.Type.getDescriptor(ObjectEncoder.class);
final String objectDesc = org.redkale.asm.Type.getDescriptor(Object.class);
final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz); final String valtypeDesc = org.redkale.asm.Type.getDescriptor(clazz);
// ------------------------------------------------------------------------------ // ------------------------------------------------------------------------------
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
@@ -116,17 +125,12 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
supDynName, supDynName,
null); null);
final int membersSize = elements.size();
for (AccessibleObject element : elements) { for (AccessibleObject element : elements) {
final String fieldName = factory.readConvertFieldName(clazz, element); final String fieldName = factory.readConvertFieldName(clazz, element);
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldBytes", "[B", null, null); fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldBytes", "[B", null, null);
fv.visitEnd(); fv.visitEnd();
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "CommaFieldBytes", "[B", null, null);
fv.visitEnd();
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldChars", "[C", null, null); fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "FieldChars", "[C", null, null);
fv.visitEnd(); fv.visitEnd();
fv = cw.visitField(ACC_PROTECTED + ACC_FINAL, fieldName + "CommaFieldChars", "[C", null, null);
fv.visitEnd();
final Class fieldType = readGetSetFieldType(element); final Class fieldType = readGetSetFieldType(element);
if (fieldType != String.class && !fieldType.isPrimitive()) { if (fieldType != String.class && !fieldType.isPrimitive()) {
fv = cw.visitField(ACC_PROTECTED, fieldName + "Encoder", encodeableDesc, null, null); fv = cw.visitField(ACC_PROTECTED, fieldName + "Encoder", encodeableDesc, null, null);
@@ -157,21 +161,11 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
mv.visitLdcInsn("\"" + fieldName + "\":"); mv.visitLdcInsn("\"" + fieldName + "\":");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getBytes", "()[B", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getBytes", "()[B", false);
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FieldBytes", "[B"); mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FieldBytes", "[B");
// xxxCommaFieldBytes
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(",\"" + fieldName + "\":");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "getBytes", "()[B", false);
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "CommaFieldBytes", "[B");
// xxxFieldChars // xxxFieldChars
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn("\"" + fieldName + "\":"); mv.visitLdcInsn("\"" + fieldName + "\":");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toCharArray", "()[C", false); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toCharArray", "()[C", false);
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FieldChars", "[C"); mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "FieldChars", "[C");
// xxxCommaFieldChars
mv.visitVarInsn(ALOAD, 0);
mv.visitLdcInsn(",\"" + fieldName + "\":");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "toCharArray", "()[C", false);
mv.visitFieldInsn(PUTFIELD, newDynName, fieldName + "CommaFieldChars", "[C");
} }
mv.visitInsn(RETURN); mv.visitInsn(RETURN);
Label label2 = new Label(); Label label2 = new Label();
@@ -221,34 +215,40 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
} }
int maxLocals = 4;
int elementIndex = -1; int elementIndex = -1;
final boolean tiny = ConvertFactory.checkTinyFeature(factory.getFeatures());
final boolean nullable = ConvertFactory.checkNullableFeature(factory.getFeatures());
final Class firstType = readGetSetFieldType(elements.get(0));
final boolean mustHadComma = (firstType.isPrimitive() && (firstType != boolean.class || !tiny || nullable))
|| membersSize == 1; // byte/short/char/int/float/long/double
{ {
{ // out.writeTo('{'); { // out.writeTo('{');
mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1);
mv.visitIntInsn(BIPUSH, '{'); mv.visitIntInsn(BIPUSH, '{');
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeTo", "(B)V", false); mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeTo", "(B)V", false);
} }
// boolean comma = false;
if (!mustHadComma) { // boolean comma = false; if (elements.size() > 1) {
mv.visitInsn(ICONST_0); mv.visitInsn(ICONST_0);
mv.visitVarInsn(ISTORE, 3); mv.visitVarInsn(ISTORE, 3);
commaLabel = new Label(); commaLabel = new Label();
mv.visitLabel(commaLabel); mv.visitLabel(commaLabel);
} }
// comma = out.writeFieldIntValue(ageFieldBytes, ageFieldChars, comma, value.getAge());
for (AccessibleObject element : elements) { for (AccessibleObject element : elements) {
elementIndex++; elementIndex++;
final String fieldName = factory.readConvertFieldName(clazz, element); final String fieldName = factory.readConvertFieldName(clazz, element);
final Class fieldType = readGetSetFieldType(element); final Class fieldType = readGetSetFieldType(element);
int storeid = ASTORE; mv.visitVarInsn(ALOAD, 1); // JsonWriter
int loadid = ALOAD; mv.visitVarInsn(ALOAD, 0); // this.xxxFieldBytes 第一个参数
{ // String message = value.getMessage(); mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldBytes", "[B");
mv.visitVarInsn(ALOAD, 2); // 加载 value mv.visitVarInsn(ALOAD, 0); // this.xxxFieldChars 第二个参数
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldChars", "[C");
if (commaLabel != null) {
mv.visitVarInsn(ILOAD, 3); // comma 第三个参数
} else {
mv.visitInsn(ICONST_0); // comma=false 第三个参数
}
if (mixedNames.containsKey(fieldName)) { // Encodeable 第四个参数
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "Encoder", encodeableDesc);
}
mv.visitVarInsn(ALOAD, 2); // value.getXXX() 第四/五个参数
if (element instanceof Field) { if (element instanceof Field) {
mv.visitFieldInsn( mv.visitFieldInsn(
GETFIELD, GETFIELD,
@@ -257,205 +257,92 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
org.redkale.asm.Type.getDescriptor(fieldType)); org.redkale.asm.Type.getDescriptor(fieldType));
} else { } else {
mv.visitMethodInsn( mv.visitMethodInsn(
INVOKEVIRTUAL, ((Method) element).getDeclaringClass().isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL,
valtypeName, valtypeName,
((Method) element).getName(), ((Method) element).getName(),
"()" + org.redkale.asm.Type.getDescriptor(fieldType), "()" + org.redkale.asm.Type.getDescriptor(fieldType),
false); false);
} }
if (fieldType == boolean.class) { if (fieldType == boolean.class || fieldType == Boolean.class) {
storeid = ISTORE; mv.visitMethodInsn(
loadid = ILOAD; INVOKEVIRTUAL,
mv.visitVarInsn(storeid, maxLocals); writerName,
} else if (fieldType == byte.class) { "writeFieldBooleanValue",
storeid = ISTORE; "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
loadid = ILOAD; false);
mv.visitVarInsn(storeid, maxLocals); } else if (fieldType == byte.class || fieldType == Byte.class) {
} else if (fieldType == short.class) { mv.visitMethodInsn(
storeid = ISTORE; INVOKEVIRTUAL,
loadid = ILOAD; writerName,
mv.visitVarInsn(storeid, maxLocals); "writeFieldByteValue",
} else if (fieldType == char.class) { "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
storeid = ISTORE; false);
loadid = ILOAD; } else if (fieldType == short.class || fieldType == Short.class) {
mv.visitVarInsn(storeid, maxLocals); mv.visitMethodInsn(
} else if (fieldType == int.class) { INVOKEVIRTUAL,
storeid = ISTORE; writerName,
loadid = ILOAD; "writeFieldShortValue",
mv.visitVarInsn(storeid, maxLocals); "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
} else if (fieldType == float.class) { false);
storeid = FSTORE; } else if (fieldType == char.class || fieldType == Character.class) {
loadid = FLOAD; mv.visitMethodInsn(
mv.visitVarInsn(storeid, maxLocals); INVOKEVIRTUAL,
} else if (fieldType == long.class) { writerName,
storeid = LSTORE; "writeFieldCharValue",
loadid = LLOAD; "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
mv.visitVarInsn(storeid, maxLocals); false);
} else if (fieldType == double.class) { } else if (fieldType == int.class || fieldType == Integer.class) {
storeid = DSTORE; mv.visitMethodInsn(
loadid = DLOAD; INVOKEVIRTUAL,
mv.visitVarInsn(storeid, maxLocals); writerName,
} else { "writeFieldIntValue",
// storeid = ASTORE; "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
// loadid = ALOAD; false);
mv.visitVarInsn(storeid, maxLocals); } else if (fieldType == float.class || fieldType == Float.class) {
} mv.visitMethodInsn(
} INVOKEVIRTUAL,
Label msgnotemptyif = null; writerName,
if (!fieldType.isPrimitive() && !nullable) { // if (message != null) { start "writeFieldFloatValue",
mv.visitVarInsn(loadid, maxLocals); "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
msgnotemptyif = new Label(); false);
mv.visitJumpInsn(IFNULL, msgnotemptyif); } else if (fieldType == long.class || fieldType == Long.class) {
if (tiny && fieldType == String.class) { mv.visitMethodInsn(
mv.visitVarInsn(loadid, maxLocals); INVOKEVIRTUAL,
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "isEmpty", "()Z", false); writerName,
mv.visitJumpInsn(IFNE, msgnotemptyif); "writeFieldLongValue",
} "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
} else if (fieldType == boolean.class && tiny) { false);
mv.visitVarInsn(loadid, maxLocals); } else if (fieldType == double.class || fieldType == Double.class) {
msgnotemptyif = new Label(); mv.visitMethodInsn(
mv.visitJumpInsn(IFEQ, msgnotemptyif); INVOKEVIRTUAL,
} writerName,
if (mustHadComma) { // 第一个字段必然会写入 "writeFieldDoubleValue",
if (elementIndex == 0) { // 第一个 "([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
// out.writeTo(messageFieldBytes); false);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldBytes", "[B");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldChars", "[C");
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeField", "([B[C)V", false);
} else {
// out.writeTo(messageCommaFieldBytes);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "CommaFieldBytes", "[B");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "CommaFieldChars", "[C");
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeField", "([B[C)V", false);
}
} else { // if(comma) {} else {} 代码块
// if (comma) { start
mv.visitVarInsn(ILOAD, 3);
Label commaif = new Label();
mv.visitJumpInsn(IFEQ, commaif);
// out.writeTo(messageCommaFieldBytes);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "CommaFieldBytes", "[B");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "CommaFieldChars", "[C");
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeField", "([B[C)V", false);
Label commaelse = new Label();
mv.visitJumpInsn(GOTO, commaelse);
mv.visitLabel(commaif);
if (fieldType == boolean.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
} else if (fieldType == byte.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
} else if (fieldType == short.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
} else if (fieldType == char.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
} else if (fieldType == int.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.INTEGER}, 0, null);
} else if (fieldType == float.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.FLOAT}, 0, null);
} else if (fieldType == long.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.LONG}, 0, null);
} else if (fieldType == double.class) {
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {Opcodes.DOUBLE}, 0, null);
} else {
mv.visitFrame(
Opcodes.F_APPEND,
2,
new Object[] {Opcodes.INTEGER, "java/lang/String"},
0,
null); // } else { comma
}
// out.writeTo(messageFieldBytes);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldBytes", "[B");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "FieldChars", "[C");
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeField", "([B[C)V", false);
// comma = true;
mv.visitInsn(ICONST_1);
mv.visitVarInsn(ISTORE, 3);
mv.visitLabel(commaelse);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); // if (comma) } end
}
// out.writeString(message);
if (fieldType == boolean.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeBoolean", "(Z)V", false);
} else if (fieldType == byte.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeByte", "(B)V", false);
} else if (fieldType == short.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeShort", "(S)V", false);
} else if (fieldType == char.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeChar", "(C)V", false);
} else if (fieldType == int.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeInt", "(I)V", false);
} else if (fieldType == float.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeFloat", "(F)V", false);
} else if (fieldType == long.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeLong", "(J)V", false);
} else if (fieldType == double.class) {
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(INVOKEVIRTUAL, writerName, "writeDouble", "(D)V", false);
} else if (fieldType == String.class) { } else if (fieldType == String.class) {
if (!isConvertStandardString(factory, element)) { String writeFieldName = "writeFieldStringValue";
mv.visitVarInsn(ALOAD, 1); if (isConvertStandardString(factory, element)) {
mv.visitVarInsn(loadid, maxLocals); writeFieldName = "writeFieldStandardStringValue";
}
mv.visitMethodInsn( mv.visitMethodInsn(
INVOKEVIRTUAL, writerName, "writeString", "(Ljava/lang/String;)V", false); INVOKEVIRTUAL,
writerName,
writeFieldName,
"([B[CZ" + org.redkale.asm.Type.getDescriptor(fieldType) + ")Z",
false);
} else { } else {
mv.visitVarInsn(ALOAD, 1); // writeFieldObjectValue(fieldBytes, fieldChars, comma, encodeable, value)
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn( mv.visitMethodInsn(
INVOKEVIRTUAL, writerName, "writeStandardString", "(Ljava/lang/String;)V", false); INVOKEVIRTUAL,
writerName,
"writeFieldObjectValue",
"([B[CZ" + encodeableDesc + objectDesc + ")Z",
false);
} }
} else { // int[],Boolean[],String[] if (commaLabel != null && elementIndex + 1 < elements.size()) {
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ISTORE, 3); // comma = out.writeFieldXXXValue()
mv.visitFieldInsn(GETFIELD, newDynName, fieldName + "Encoder", encodeableDesc);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(loadid, maxLocals);
mv.visitMethodInsn(
INVOKEINTERFACE,
encodeableName,
"convertTo",
"(" + writerDesc + "Ljava/lang/Object;)V",
true);
}
if (!fieldType.isPrimitive() && !nullable) { // if (message != null) } end
mv.visitLabel(msgnotemptyif);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
} else if (fieldType == boolean.class && tiny) {
mv.visitLabel(msgnotemptyif);
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
}
if (fieldType == long.class || fieldType == double.class) {
maxLocals += 2;
} else { } else {
maxLocals++; mv.visitInsn(POP);
} }
} }
{ // out.writeTo('}'); { // out.writeTo('}');
@@ -473,7 +360,7 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
if (commaLabel != null) { if (commaLabel != null) {
mv.visitLocalVariable("comma", "Z", null, commaLabel, label2, 3); mv.visitLocalVariable("comma", "Z", null, commaLabel, label2, 3);
} }
mv.visitMaxs(maxLocals, maxLocals); mv.visitMaxs(6, 4);
mv.visitEnd(); mv.visitEnd();
} }
{ // convertTo 虚拟方法 { // convertTo 虚拟方法
@@ -504,7 +391,6 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
JsonDynEncoder resultEncoder = JsonDynEncoder resultEncoder =
(JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class) (JsonDynEncoder) newClazz.getConstructor(JsonFactory.class, Type.class, ObjectEncoder.class)
.newInstance(factory, clazz, selfObjEncoder); .newInstance(factory, clazz, selfObjEncoder);
if (mixedNames != null) {
for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) { for (Map.Entry<String, AccessibleObject> en : mixedNames.entrySet()) {
Field f = newClazz.getDeclaredField(en.getKey() + "Encoder"); Field f = newClazz.getDeclaredField(en.getKey() + "Encoder");
f.setAccessible(true); f.setAccessible(true);
@@ -516,7 +402,6 @@ public abstract class JsonDynEncoder<T> extends ObjectEncoder<JsonWriter, T> {
: ((Method) en.getValue()).getGenericReturnType())); : ((Method) en.getValue()).getGenericReturnType()));
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), f); RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), f);
} }
}
return resultEncoder; return resultEncoder;
} catch (Exception ex) { } catch (Exception ex) {
throw new ConvertException(ex); throw new ConvertException(ex);