Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Refactored code #4369

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 14 additions & 42 deletions src/main/java/com/alibaba/fastjson/asm/TypeCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import java.util.HashMap;
import java.util.Map;

public class TypeCollector {
private static String JSONType = ASMUtils.desc(com.alibaba.fastjson.annotation.JSONType.class);

private static final Map<String, String> primitives = new HashMap<String, String>() {

public abstract class BaseCollector {
protected static final String JSON_TYPE = ASMUtils.desc(com.alibaba.fastjson.annotation.JSONType.class);

protected static final Map<String, String> PRIMITIVES = new HashMap<String, String>() {
{
put("int","I");
put("boolean","Z");
Expand All @@ -22,59 +24,29 @@ public class TypeCollector {
}
};

private final String methodName;
protected final String methodName;

private final Class<?>[] parameterTypes;
protected final Class<?>[] parameterTypes;

protected MethodCollector collector;

protected boolean jsonType;

public TypeCollector(String methodName, Class<?>[] parameterTypes) {
protected BaseCollector(String methodName, Class<?>[] parameterTypes) {
this.methodName = methodName;
this.parameterTypes = parameterTypes;
this.collector = null;
}

protected MethodCollector visitMethod(int access, String name, String desc) {
if (collector != null) {
return null;
}

if (!name.equals(methodName)) {
return null;
}

Type[] argTypes = Type.getArgumentTypes(desc);
int longOrDoubleQuantity = 0;
for (Type t : argTypes) {
String className = t.getClassName();
if (className.equals("long") || className.equals("double")) {
longOrDoubleQuantity++;
}
}

if (argTypes.length != this.parameterTypes.length) {
return null;
}
for (int i = 0; i < argTypes.length; i++) {
if (!correctTypeName(argTypes[i], this.parameterTypes[i].getName())) {
return null;
}
}

return collector = new MethodCollector(
Modifier.isStatic(access) ? 0 : 1,
argTypes.length + longOrDoubleQuantity);
}
protected abstract MethodCollector visitMethod(int access, String name, String desc);

public void visitAnnotation(String desc) {
if (JSONType.equals(desc)) {
if (JSON_TYPE.equals(desc)) {
jsonType = true;
}
}

private boolean correctTypeName(Type type, String paramTypeName) {
protected boolean correctTypeName(Type type, String paramTypeName) {
String s = type.getClassName();
// array notation needs cleanup.
StringBuilder braces = new StringBuilder();
Expand All @@ -83,8 +55,8 @@ private boolean correctTypeName(Type type, String paramTypeName) {
s = s.substring(0, s.length() - 2);
}
if (braces.length() != 0) {
if (primitives.containsKey(s)) {
s = braces.append(primitives.get(s)).toString();
if (PRIMITIVES.containsKey(s)) {
s = braces.append(PRIMITIVES.get(s)).toString();
} else {
s = braces.append('L').append(s).append(';').toString();
}
Expand All @@ -106,4 +78,4 @@ public boolean matched() {
public boolean hasJsonType() {
return jsonType;
}
}
}
90 changes: 44 additions & 46 deletions src/main/java/com/alibaba/fastjson/parser/SymbolTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ public class SymbolTable {

private final String[] symbols;
private final int indexMask;

public SymbolTable(int tableSize){
this.indexMask = tableSize - 1;
this.symbols = new String[tableSize];

this.addSymbol("$ref", 0, 4, "$ref".hashCode());
this.addSymbol(JSON.DEFAULT_TYPE_KEY, 0, JSON.DEFAULT_TYPE_KEY.length(), JSON.DEFAULT_TYPE_KEY.hashCode());
}

public String addSymbol(char[] buffer, int offset, int len) {
public String addSymbol(char[] buffer, int offset, int length) {
// search for identical symbol
int hash = hash(buffer, offset, len);
return addSymbol(buffer, offset, len, hash);
int hash = hash(buffer, offset, length);
return addSymbol(buffer, offset, length, hash);
}

/**
Expand All @@ -46,81 +46,79 @@ public String addSymbol(char[] buffer, int offset, int len) {
*
* @param buffer The buffer containing the new symbol.
* @param offset The offset into the buffer of the new symbol.
* @param len The length of the new symbol in the buffer.
* @param length The length of the new symbol in the buffer.
*/
public String addSymbol(char[] buffer, int offset, int len, int hash) {
public String addSymbol(char[] buffer, int offset, int length, int hash) {
final int bucket = hash & indexMask;

String symbol = symbols[bucket];
if (symbol != null) {
boolean eq = true;
if (hash == symbol.hashCode() //
&& len == symbol.length()) {
for (int i = 0; i < len; i++) {
if (buffer[offset + i] != symbol.charAt(i)) {
eq = false;
break;
}
}
} else {
eq = false;
}

if (eq) {
return symbol;
} else {
return new String(buffer, offset, len);
}
if (symbol != null && areSymbolsEqual(buffer, offset, length, hash, symbol)) {
return symbol;
} else if (symbol != null) {
return createNewSymbol(buffer, offset, length);
}
symbol = new String(buffer, offset, len).intern();

symbol = createNewSymbol(buffer, offset, length).intern();
symbols[bucket] = symbol;
return symbol;
}

public String addSymbol(String buffer, int offset, int len, int hash) {
return addSymbol(buffer, offset, len, hash, false);

private boolean areSymbolsEqual(char[] buffer, int offset, int length, int hash, String symbol) {
if (hash == symbol.hashCode() && length == symbol.length()) {
for (int i = 0; i < length; i++) {
if (buffer[offset + i] != symbol.charAt(i)) {
return false;
}
}
return true;
}
return false;
}

private String createNewSymbol(char[] buffer, int offset, int length) {
return new String(buffer, offset, length);
}

public String addSymbol(String buffer, int offset, int len, int hash, boolean replace) {
public String addSymbol(String buffer, int offset, int length, int hash) {
return addSymbol(buffer, offset, length, hash, false);
}

public String addSymbol(String buffer, int offset, int length, int hash, boolean replace) {
final int bucket = hash & indexMask;

String symbol = symbols[bucket];
if (symbol != null) {
if (hash == symbol.hashCode() //
&& len == symbol.length() //
&& buffer.startsWith(symbol, offset)) {
if (areSymbolsEqual(buffer.toCharArray(), offset, length, hash, symbol)) {
return symbol;
}

String str = subString(buffer, offset, len);
String str = subString(buffer, offset, length);

if (replace) {
symbols[bucket] = str;
}

return str;
}

symbol = len == buffer.length() //
? buffer //
: subString(buffer, offset, len);

symbol = length == buffer.length() ? buffer : subString(buffer, offset, length);
symbol = symbol.intern();
symbols[bucket] = symbol;
return symbol;
}
private static String subString(String src, int offset, int len) {
char[] chars = new char[len];
src.getChars(offset, offset + len, chars, 0);

private static String subString(String src, int offset, int length) {
char[] chars = new char[length];
src.getChars(offset, offset + length, chars, 0);
return new String(chars);
}

public static int hash(char[] buffer, int offset, int len) {
public static int hash(char[] buffer, int offset, int length) {
int h = 0;
int off = offset;

for (int i = 0; i < len; i++) {
for (int i = 0; i < length; i++) {
h = 31 * h + buffer[off++];
}
return h;
Expand Down
34 changes: 18 additions & 16 deletions src/main/java/com/alibaba/fastjson/serializer/ArraySerializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,16 @@
import java.io.IOException;
import java.lang.reflect.Type;

/**
* @author wenshao[[email protected]]
*/
public class ArraySerializer implements ObjectSerializer {

private final Class<?> componentType;
private final ObjectSerializer compObjectSerializer;
private final ArrayItemSerializer[] itemSerializers;

public ArraySerializer(Class<?> componentType, ObjectSerializer compObjectSerializer){
this.componentType = componentType;
this.compObjectSerializer = compObjectSerializer;
public ArraySerializer(ArrayItemSerializer[] itemSerializers){
this.itemSerializers = itemSerializers;
}

public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
throws IOException {
SerializeWriter out = serializer.out;

if (object == null) {
Expand All @@ -49,9 +44,9 @@ public final void write(JSONSerializer serializer, Object object, Object fieldNa
try {
out.append('[');
for (int i = 0; i < size; ++i) {
if (i != 0) {
out.append(',');
}
if (i != 0) {
out.append(',');
}
Object item = array[i];

if (item == null) {
Expand All @@ -60,16 +55,23 @@ public final void write(JSONSerializer serializer, Object object, Object fieldNa
} else {
out.append("null");
}
} else if (item.getClass() == componentType) {
compObjectSerializer.write(serializer, item, i, null, 0);
} else {
ObjectSerializer itemSerializer = serializer.getObjectWriter(item.getClass());
itemSerializer.write(serializer, item, i, null, 0);
ArrayItemSerializer itemSerializer = getItemSerializer(item);
itemSerializer.serialize(serializer, item, i, null, 0);
}
}
out.append(']');
} finally {
serializer.context = context;
}
}

private ArrayItemSerializer getItemSerializer(Object item) {
for (ArrayItemSerializer serializer : itemSerializers) {
if (serializer.canSerialize(item)) {
return serializer;
}
}
throw new IllegalArgumentException("No serializer found for item: " + item);
}
}
Loading