@Override
  protected synchronized CtClass get0(String className, boolean useCache) throws NotFoundException {
    if (!exclude(className)) {
      if (isSrg) {
        CtClass cachedClass = srgClasses.get(className);
        if (cachedClass != null) {
          return cachedClass;
        }
        cachedClass = super.getCached(className);
        if (cachedClass != null && cachedClass.isPrimitive()) {
          return cachedClass;
        }
        if (!Transformer.remapClassName(className).equals(className)) {
          Log.severe("Attempted to load obfuscated class " + className, new Throwable());
          return null;
        }
        String remappedName = Transformer.unmapClassName(className);

        byte[] bytes = getBytes(remappedName);
        if (bytes != null) {
          bytes = Transformer.transform(bytes);
          try {
            CtClass ctClass = new CtClassType(new ByteArrayInputStream(bytes), this);
            if (!remappedName.equals(className)) {
              ctClass.freeze();
            }
            srgClasses.put(className, ctClass);
            return ctClass;
          } catch (IOException e) {
            Log.severe("Failed to make " + className + " from " + remappedName, e);
          }
          return null;
        }
      } else {
        if (!Transformer.unmapClassName(className).equals(className)) {
          Log.severe(
              "Attempted to load SRG class " + className + " while patching a non-SRG class.",
              new Throwable());
          return null;
        }
      }
    }
    CtClass clazz;
    if (useCache) {
      clazz = getCached(className);
      if (clazz != null) {
        return clazz;
      }
    }

    clazz = createCtClass(className, useCache);
    if (clazz != null) {
      // clazz.getName() != classname if classname is "[L<name>;".
      if (useCache) {
        cacheCtClass(clazz.getName(), clazz, false);
      }
    }

    return clazz;
  }
示例#2
0
  private boolean addSerializeMethods(CtClass cc, boolean callSuper)
      throws NotFoundException, CannotCompileException {
    CtField[] fields = cc.getDeclaredFields();
    int size = 0;
    StringBuffer sb = new StringBuffer();
    sb.append(callSuper ? "{$2=super.pack($1, $2);$1.extend($2" : "{$1.extend($2");
    for (int i = 0; i < fields.length; i++) {
      CtField f = fields[i];
      if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) {
        CtClass type = f.getType();
        if (type.isPrimitive()) {
          if (type == CtClass.booleanType || type == CtClass.byteType) {
            size += 1;
          } else if (type == CtClass.charType || type == CtClass.shortType) {
            size += 2;
          } else if (type == CtClass.longType || type == CtClass.doubleType) {
            size += 8;
          } else {
            size += 4;
          }
        } else if (type.getName().equals("java.lang.String")) {
          sb.append("+org.nachodb.impl.Bytes#sizeof(");
          sb.append(f.getName());
          sb.append(",$3)");
        } else {
          return false;
        }
      }
    }
    cc.addInterface(serializable);

    CtMethod m = new CtMethod(pack, cc, null);
    sb.append('+');
    sb.append(size);
    sb.append(");");
    for (int i = 0; i < fields.length; i++) {
      CtField f = fields[i];
      if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) {
        CtClass type = f.getType();
        String name = f.getName();
        if (type == CtClass.booleanType) {
          sb.append("$1.arr[$2++]=(byte)(");
          sb.append(name);
          sb.append("?1:0);");
        } else if (type == CtClass.charType) {
          sb.append("org.nachodb.impl.Bytes#pack2($1.arr,$2,(short)");
          sb.append(name);
          sb.append(");$2+=2;");
        } else if (type == CtClass.byteType) {
          sb.append("$1.arr[$2++]=");
          sb.append(name);
          sb.append(";");
        } else if (type == CtClass.shortType) {
          sb.append("org.nachodb.impl.Bytes#pack2($1.arr,$2,");
          sb.append(name);
          sb.append(");$2+=2;");
        } else if (type == CtClass.intType) {
          sb.append("org.nachodb.impl.Bytes#pack4($1.arr,$2,");
          sb.append(name);
          sb.append(");$2+=4;");
        } else if (type == CtClass.longType) {
          sb.append("org.nachodb.impl.Bytes#pack8($1.arr,$2,");
          sb.append(name);
          sb.append(");$2+=8;");
        } else if (type == CtClass.doubleType) {
          sb.append("org.nachodb.impl.Bytes#packF8($1.arr,$2,");
          sb.append(name);
          sb.append(");$2+=8;");
        } else if (type == CtClass.floatType) {
          sb.append("org.nachodb.impl.Bytes#packF4($1.arr,$2,");
          sb.append(name);
          sb.append(");$2+=4;");
        } else {
          sb.append("$2=org.nachodb.impl.Bytes#packStr($1.arr,$2,");
          sb.append(name);
          sb.append(",$3);");
        }
      }
    }
    sb.append("return $2;}");
    m.setBody(sb.toString());
    cc.addMethod(m);

    m = new CtMethod(unpack, cc, null);
    sb = new StringBuffer();
    sb.append(callSuper ? "{$2=super.unpack($1, $2);" : "{");
    for (int i = 0; i < fields.length; i++) {
      CtField f = fields[i];
      if ((f.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0) {
        CtClass type = f.getType();
        String name = f.getName();
        sb.append(name);
        sb.append('=');
        if (type == CtClass.booleanType) {
          sb.append("$1[$2++]!=0;");
        } else if (type == CtClass.charType) {
          sb.append("(char)org.nachodb.impl.Bytes#unpack2($1,$2);$2+=2;");
        } else if (type == CtClass.byteType) {
          sb.append("$1[$2++];");
        } else if (type == CtClass.shortType) {
          sb.append("org.nachodb.impl.Bytes#unpack2($1,$2);$2+=2;");
        } else if (type == CtClass.intType) {
          sb.append("org.nachodb.impl.Bytes#unpack4($1,$2);$2+=4;");
        } else if (type == CtClass.longType) {
          sb.append("org.nachodb.impl.Bytes#unpack8($1,$2);$2+=8;");
        } else if (type == CtClass.doubleType) {
          sb.append("org.nachodb.impl.Bytes#unpackF8($1,$2);$2+=8;");
        } else if (type == CtClass.floatType) {
          sb.append("org.nachodb.impl.Bytes#unpackF4($1,$2);$2+=4;");
        } else {
          sb.append(
              "org.nachodb.impl.Bytes#unpackStr($1,$2,$3);$2+=org.nachodb.impl.Bytes#sizeof($1,$2);");
        }
      }
    }
    sb.append("return $2;}");
    m.setBody(sb.toString());
    cc.addMethod(m);
    return true;
  }