} else {
orig = pool.getOrNull(clazz.getName());
}
newClz.setSuperclass(orig);
final FSTClazzInfo clInfo = conf.getClassInfo(clazz);
CtMethod[] methods = orig.getMethods();
for (int i = 0; i < methods.length; i++) {
CtMethod method = methods[i];
final Class curClz = Class.forName( method.getDeclaringClass().getName() );
boolean allowed = ((method.getModifiers() & AccessFlag.ABSTRACT) == 0 ) &&
(method.getModifiers() & AccessFlag.NATIVE) == 0 &&
(method.getModifiers() & AccessFlag.FINAL) == 0 &&
( !method.getDeclaringClass().getName().equals(FSTStruct.class.getName())
||method.getName().equals("getFieldValues")) &&
! method.getDeclaringClass().getName().equals(Object.class.getName());
allowed &= method.getAnnotation(NoAssist.class) == null;
allowed &= (method.getModifiers() & AccessFlag.STATIC) == 0;
if ( allowed && (method.getModifiers() & AccessFlag.FINAL) != 0 && ! method.getDeclaringClass().getName().equals("java.lang.Object") ) {
throw new RuntimeException("final methods are not allowed for struct classes:"+method.getName());
}
if ( allowed && (method.getModifiers() & AccessFlag.PRIVATE) != 0 && ! method.getDeclaringClass().getName().equals("java.lang.Object")) {
throw new RuntimeException("private methods are not allowed for struct classes:"+method.getName());
}
if ( allowed ) {
ClassMap mp = new ClassMap();
mp.fix(clazz.getName());
mp.fix(clazz.getSuperclass().getName()); // ?? only depth 2 ??
method = new CtMethod(method,newClz,mp);
String methName = method.getName();
// array access:
// void [name](int, type)
// [type] [name](int)
FSTClazzInfo.FSTFieldInfo arrayFi = checkForSpecialArrayMethod(clInfo, method, "", null, null);
// array length:
// int [name]Len()
FSTClazzInfo.FSTFieldInfo lenfi = checkForSpecialArrayMethod(clInfo, method, "Len", CtClass.intType, new CtClass[0]);
// get byte index of array data:
// int [name]Index()
FSTClazzInfo.FSTFieldInfo indexfi = checkForSpecialArrayMethod(clInfo, method, "Index", CtClass.intType, new CtClass[0]);
// get size of array element:
// int [name]ElementSize()
FSTClazzInfo.FSTFieldInfo elemlen = checkForSpecialArrayMethod(clInfo, method, "ElementSize", CtClass.intType, new CtClass[0]);
// CREATE non volatile pointer to array[0] element:
// type [name]Pointer() OR type [name]Pointer(pointerToSetup) (for reuse)
FSTClazzInfo.FSTFieldInfo pointerfi = checkForSpecialArrayMethod(clInfo, method, "Pointer", null, null);
// get byte index to structure or array header element:
// type [name]StructIndex()
FSTClazzInfo.FSTFieldInfo structIndex = checkForSpecialMethod(clInfo, method, "StructIndex", CtClass.intType, new CtClass[0], false);
// set with CAS
// boolean [name]CAS(expectedValue,value)
FSTClazzInfo.FSTFieldInfo casAcc = checkForSpecialMethod(clInfo, method, "CAS", CtClass.booleanType, null, false);
if ( casAcc != null ) {
structGen.defineStructSetCAS(casAcc, clInfo, method);
newClz.addMethod(method);
} else
if ( pointerfi != null ) {
structGen.defineArrayPointer(pointerfi, clInfo, method);
newClz.addMethod(method);
} else
if ( structIndex != null ) {
structGen.defineFieldStructIndex(structIndex, clInfo, method);
newClz.addMethod(method);
} else
if ( indexfi != null ) {
structGen.defineArrayIndex(indexfi, clInfo, method);
newClz.addMethod(method);
} else
if ( elemlen != null ) {
structGen.defineArrayElementSize(elemlen, clInfo, method);
newClz.addMethod(method);
} else
if ( arrayFi != null ) {
structGen.defineArrayAccessor(arrayFi, clInfo, method);
newClz.addMethod(method);
} else if ( methName.endsWith("Len") && lenfi != null )
{
structGen.defineArrayLength(lenfi, clInfo, method);
newClz.addMethod(method);
} else {
if ( methName.equals("getFieldValues") &&
( (clInfo.getClazz().getSuperclass().getName().equals("de.nustaq.reallive.impl.RLStructRow")) // oops
|| (curClz != FSTStruct.class) )
) {
FSTClazzInfo.FSTFieldInfo[] fieldInfo = clInfo.getFieldInfo();
StringBuilder body = new StringBuilder("{ return new Object[] { ");
for (int j = 0; j < fieldInfo.length; j++) {
FSTClazzInfo.FSTFieldInfo fstFieldInfo = fieldInfo[j];
int modifiers = fstFieldInfo.getField().getModifiers();
if ( (java.lang.reflect.Modifier.isProtected(modifiers) ||
java.lang.reflect.Modifier.isPublic(modifiers)) &&
!java.lang.reflect.Modifier.isStatic(modifiers)
)
{
body.append( "\""+fstFieldInfo.getField().getName()+"\", " );
Class type = fstFieldInfo.getType();
if ( FSTStruct.class.isAssignableFrom(type) ) {
body.append(fstFieldInfo.getField().getName()).append(".getFieldValues()");
} else {
if ( type.isPrimitive() ) {
if ( long.class == type ) {
body.append("new Long("+fstFieldInfo.getField().getName()+")");
} else if ( float.class == type ||double.class == type ) {
body.append("new Double("+fstFieldInfo.getField().getName()+")");
} else {
body.append("new Integer("+fstFieldInfo.getField().getName()+")");
}
} else {
body.append(fstFieldInfo.getField().getName());
}
}
if ( j != fieldInfo.length-1 )
body.append(",");
}
}
body.append("}; }");
method.setBody(body.toString());
}
newClz.addMethod(method);
method.instrument( new ExprEditor() {
@Override
public void edit(FieldAccess f) throws CannotCompileException {
try {
if ( ! f.isStatic() ) {
CtClass type = null;
type = f.getField().getType();
FSTClazzInfo.FSTFieldInfo fieldInfo = clInfo.getFieldInfo(f.getFieldName(), null);
if ( fieldInfo == null ) {
return;
}
if ( f.isReader() ) {
structGen.defineStructReadAccess(f, type, fieldInfo);