private static Integer readNumber(int b0, DataInput input) throws IOException {

    if (b0 == 28) {
      int b1 = input.readUnsignedByte();
      int b2 = input.readUnsignedByte();

      return (int) (short) (b1 << 8 | b2);
    } else if (b0 >= 32 && b0 <= 246) {
      return b0 - 139;
    } else if (b0 >= 247 && b0 <= 250) {
      int b1 = input.readUnsignedByte();

      return (b0 - 247) * 256 + b1 + 108;
    } else if (b0 >= 251 && b0 <= 254) {
      int b1 = input.readUnsignedByte();

      return -(b0 - 251) * 256 - b1 - 108;
    } else if (b0 == 255) {
      int b1 = input.readUnsignedByte();
      int b2 = input.readUnsignedByte();
      // The lower bytes are representing the digits after
      // the decimal point and aren't needed in this context
      input.readUnsignedByte();
      input.readUnsignedByte();
      return (int) (short) (b1 << 8 | b2);
    } else {
      throw new IllegalArgumentException();
    }
  }
  private CharStringCommand readCommand(int b0, DataInput input) throws IOException {

    if (b0 == 1 || b0 == 18) {
      hstemCount += peekNumbers().size() / 2;
    } else if (b0 == 3 || b0 == 19 || b0 == 20 || b0 == 23) {
      vstemCount += peekNumbers().size() / 2;
    } // End if

    if (b0 == 12) {
      int b1 = input.readUnsignedByte();

      return new CharStringCommand(b0, b1);
    } else if (b0 == 19 || b0 == 20) {
      int[] value = new int[1 + getMaskLength()];
      value[0] = b0;

      for (int i = 1; i < value.length; i++) {
        value[i] = input.readUnsignedByte();
      }

      return new CharStringCommand(value);
    }

    return new CharStringCommand(b0);
  }
  /**
   * Read a long previously written by writeLong().
   *
   * @exception IOException an exception was thrown by a method on in.
   */
  public static final long readLong(DataInput in) throws IOException {

    int int_value = in.readUnsignedByte();

    if ((int_value & ~0x3f) == 0) {
      // test for small case first - assuming this is usual case.
      // this is stored in 2 bytes.

      return ((int_value << 8) | in.readUnsignedByte());
    } else if ((int_value & 0x80) == 0) {
      // value is stored in 4 bytes.  only use low 6 bits from 1st byte.

      return (((int_value & 0x3f) << 24)
          | (in.readUnsignedByte() << 16)
          | (in.readUnsignedByte() << 8)
          | (in.readUnsignedByte()));
    } else {
      // value is stored in 8 bytes.  only use low 7 bits from 1st byte.
      return ((((long) (int_value & 0x7f)) << 56)
          | (((long) in.readUnsignedByte()) << 48)
          | (((long) in.readUnsignedByte()) << 40)
          | (((long) in.readUnsignedByte()) << 32)
          | (((long) in.readUnsignedByte()) << 24)
          | (((long) in.readUnsignedByte()) << 16)
          | (((long) in.readUnsignedByte()) << 8)
          | (((long) in.readUnsignedByte())));
    }
  }
Exemple #4
0
  private static Node deserializeNode(DataInput input) throws IOException {
    int level = input.readUnsignedByte();
    long value = input.readLong();
    double weight = input.readDouble();

    return new Node(value, level, weight);
  }
  private Object read(
      DataInput objBuffer,
      Type propertyType,
      boolean array,
      UnrealPackageReadOnly.ExportEntry arrayInner,
      String structName,
      UnrealPackageReadOnly up)
      throws IOException {
    switch (propertyType) {
      case NONE:
        return null;
      case BYTE:
        return objBuffer.readUnsignedByte();
      case INT:
        return objBuffer.readInt();
      case BOOL:
        return array;
      case FLOAT:
        return objBuffer.readFloat();
      case OBJECT:
        return objBuffer.readCompactInt();
      case NAME:
        return objBuffer.readCompactInt();
      case ARRAY:
        int arraySize = objBuffer.readCompactInt();
        List<Object> arrayList = new ArrayList<>(arraySize);

        String a = arrayInner.getObjectClass().getObjectName().getName();
        Property f = unrealClassLoader.getProperty(arrayInner.getObjectFullName());

        array = false;
        arrayInner = null;
        structName = null;
        propertyType = Type.valueOf(a.replace("Property", "").toUpperCase());
        if (propertyType == Type.STRUCT) {
          StructProperty structProperty = (StructProperty) f;
          structName = structProperty.getStructType().getObjectFullName();
        }
        if (propertyType == Type.ARRAY) {
          array = true;
          ArrayProperty arrayProperty = (ArrayProperty) f;
          arrayInner = (UnrealPackageReadOnly.ExportEntry) arrayProperty.getInner();
        }

        for (int i = 0; i < arraySize; i++) {
          arrayList.add(read(objBuffer, propertyType, array, arrayInner, structName, up));
        }
        return arrayList;
      case STRUCT:
        return readStruct(objBuffer, structName, up);
        /*case VECTOR:
            return readStruct(objBuffer, "Vector", up);
        case ROTATOR:
            return readStruct(objBuffer, "Rotator", up);*/
      case STR:
        return objBuffer.readLine();
      default:
        throw new IllegalStateException("Unk type(" + structName + "): " + propertyType);
    }
  }
  /**
   * Read an integer previously written by writeInt().
   *
   * @exception IOException an exception was thrown by a method on in.
   */
  public static final int readInt(DataInput in) throws IOException {

    int value = in.readUnsignedByte();

    if ((value & ~0x3f) == 0) {
      // length is stored in this byte, we also know that the 0x80 bit
      // was not set, so no need to mask off the sign extension from
      // the byte to int conversion.

      // account for 1 byte stored length of field + 1 for all returns
      return (value);
    } else if ((value & 0x80) == 0) {
      // length is stored in 2 bytes.  only use low 6 bits from 1st byte.

      if (SanityManager.DEBUG) {
        SanityManager.ASSERT((value & 0x40) == 0x40);
      }

      // top 8 bits of 2 byte length is stored in this byte, we also
      // know that the 0x80 bit was not set, so no need to mask off the
      // sign extension from the 1st byte to int conversion.  Need to
      // mask the byte in data[offset + 1] to account for possible sign
      // extension.

      return (((value & 0x3f) << 8) | in.readUnsignedByte());
    } else {
      // length is stored in 4 bytes.  only use low 7 bits from 1st byte.

      if (SanityManager.DEBUG) {
        SanityManager.ASSERT((value & 0x80) == 0x80);
      }

      // top 8 bits of 4 byte length is stored in this byte, we also
      // know that the 0x80 bit was set, so need to mask off the
      // sign extension from the 1st byte to int conversion.  Need to
      // mask the bytes from the next 3 bytes data[offset + 1,2,3] to
      // account for possible sign extension.
      //
      return (((value & 0x7f) << 24)
          | (in.readUnsignedByte() << 16)
          | (in.readUnsignedByte() << 8)
          | (in.readUnsignedByte()));
    }
  }
Exemple #7
0
  public static RNASequence readRNASequence(DataInput in) throws IOException {
    int size = in.readInt();
    char[] chars = new char[size];

    int completed = 0;
    while (completed < size) {
      int value = in.readUnsignedByte();
      chars[completed++] = getUnserializedRNABase((value >> 6));
      if (completed < size) {
        chars[completed++] = getUnserializedRNABase(((value >> 4) - ((value >> 6) << 2)));
      }
      if (completed < size) {
        chars[completed++] = getUnserializedRNABase(((value >> 2) - ((value >> 4) << 2)));
      }
      if (completed < size) {
        chars[completed++] = getUnserializedRNABase(((value) - ((value >> 2) << 2)));
      }
    }

    return new RNASequence(new String(chars));
  }
 private static int readPropertySize(int sizeType, DataInput dataInput) throws IOException {
   switch (sizeType) {
     case 0:
       return 1;
     case 1:
       return 2;
     case 2:
       return 4;
     case 3:
       return 12;
     case 4:
       return 16;
     case 5:
       return dataInput.readUnsignedByte();
     case 6:
       return dataInput.readUnsignedShort();
     case 7:
       return dataInput.readInt();
     default:
       throw new IllegalArgumentException();
   }
 }
  public List<L2Property> readProperties(
      DataInput dataInput, String objClass, UnrealPackageReadOnly up) throws UnrealException {
    List<L2Property> properties = new ArrayList<>();

    List<Property> classTemplate = unrealClassLoader.getStructProperties(objClass);

    Collections.reverse(classTemplate);

    try {
      String name;
      while (!(name = up.getNameTable().get(dataInput.readCompactInt()).getName()).equals("None")) {
        int info = dataInput.readUnsignedByte();
        Type propertyType = Type.values()[info & 0b1111]; // TODO
        int sizeType = (info >> 4) & 0b111;
        boolean array = info >> 7 == 1;

        String structName =
            propertyType.equals(Type.STRUCT)
                ? up.getNameTable().get(dataInput.readCompactInt()).getName()
                : null;
        int size = readPropertySize(sizeType, dataInput);
        int arrayIndex = array && !propertyType.equals(Type.BOOL) ? dataInput.readCompactInt() : 0;

        byte[] objBytes = new byte[size];
        dataInput.readFully(objBytes);

        final String n = name;
        PropertiesUtil.getAt(properties, n);
        L2Property property = PropertiesUtil.getAt(properties, n);
        if (property == null) {
          Property template =
              classTemplate
                  .stream()
                  .filter(pt -> pt.getEntry().getObjectName().getName().equalsIgnoreCase((n)))
                  .findAny()
                  .orElse(null);
          if (template == null)
            throw new UnrealException(objClass + ": Property template not found: " + name);

          property = new L2Property(template, up);
          properties.add(property);
        }

        if (structName != null
            && !"Vector".equals(structName)
            && !"Rotator".equals(structName)
            && !"Color".equals(structName)) {
          StructProperty structProperty = (StructProperty) property.getTemplate();
          structName = structProperty.getStructType().getObjectFullName();
        }
        UnrealPackageReadOnly.ExportEntry arrayInner = null;
        if (propertyType.equals(Type.ARRAY)) {
          ArrayProperty arrayProperty = (ArrayProperty) property.getTemplate();
          arrayInner = (UnrealPackageReadOnly.ExportEntry) arrayProperty.getInner();
        }

        DataInput objBuffer =
            new DataInputStream(new ByteArrayInputStream(objBytes), dataInput.getCharset());
        property.putAt(
            arrayIndex,
            read(
                objBuffer,
                propertyType,
                array,
                arrayInner,
                structName,
                up,
                objClass,
                property.getName()));
        property.setType(propertyType);
      }
    } catch (IOException e) {
      throw new UnrealException(e);
    }

    return properties;
  }
  public List<L2Property> readStructBin(
      DataInput objBuffer, String structName, UnrealPackageReadOnly up) throws UnrealException {
    List<Property> properties = unrealClassLoader.getStructProperties(structName);

    try {
      switch (structName) {
        case "Core.Object.Vector":
          {
            L2Property x = new L2Property(properties.get(0), up);
            x.putAt(0, objBuffer.readFloat());
            L2Property y = new L2Property(properties.get(1), up);
            y.putAt(0, objBuffer.readFloat());
            L2Property z = new L2Property(properties.get(2), up);
            z.putAt(0, objBuffer.readFloat());
            return Arrays.asList(x, y, z);
          }
        case "Core.Object.Rotator":
          {
            L2Property pitch = new L2Property(properties.get(0), up);
            pitch.putAt(0, objBuffer.readInt());
            L2Property yaw = new L2Property(properties.get(1), up);
            yaw.putAt(0, objBuffer.readInt());
            L2Property roll = new L2Property(properties.get(2), up);
            roll.putAt(0, objBuffer.readInt());
            return Arrays.asList(pitch, yaw, roll);
          }
        case "Core.Object.Color":
          {
            L2Property b = new L2Property(properties.get(0), up);
            b.putAt(0, objBuffer.readUnsignedByte());
            L2Property g = new L2Property(properties.get(1), up);
            g.putAt(0, objBuffer.readUnsignedByte());
            L2Property r = new L2Property(properties.get(2), up);
            r.putAt(0, objBuffer.readUnsignedByte());
            L2Property a = new L2Property(properties.get(3), up);
            a.putAt(0, objBuffer.readUnsignedByte());
            return Arrays.asList(b, g, r, a);
          }
        case "Fire.FireTexture.Spark":
          {
            L2Property type = new L2Property(properties.get(0), up);
            type.putAt(0, objBuffer.readUnsignedByte());
            L2Property heat = new L2Property(properties.get(1), up);
            heat.putAt(0, objBuffer.readUnsignedByte());
            L2Property x = new L2Property(properties.get(2), up);
            x.putAt(0, objBuffer.readUnsignedByte());
            L2Property y = new L2Property(properties.get(3), up);
            y.putAt(0, objBuffer.readUnsignedByte());
            L2Property byteA = new L2Property(properties.get(4), up);
            byteA.putAt(0, objBuffer.readUnsignedByte());
            L2Property byteB = new L2Property(properties.get(5), up);
            byteB.putAt(0, objBuffer.readUnsignedByte());
            L2Property byteC = new L2Property(properties.get(6), up);
            byteC.putAt(0, objBuffer.readUnsignedByte());
            L2Property byteD = new L2Property(properties.get(7), up);
            byteD.putAt(0, objBuffer.readUnsignedByte());
            return Arrays.asList(type, heat, x, y, byteA, byteB, byteC, byteD);
          }
        default:
          throw new UnsupportedOperationException("Not implemented"); // TODO
      }
    } catch (IOException e) {
      throw new UnrealException(e);
    }
  }
  private List<Object> parse(
      byte[] bytes, IndexData globalSubrIndex, IndexData localSubrIndex, boolean init)
      throws IOException {
    if (init) {
      hstemCount = 0;
      vstemCount = 0;
      sequence = new ArrayList<Object>();
    }
    DataInput input = new DataInput(bytes);
    boolean localSubroutineIndexProvided = localSubrIndex != null && localSubrIndex.getCount() > 0;
    boolean globalSubroutineIndexProvided =
        globalSubrIndex != null && globalSubrIndex.getCount() > 0;

    while (input.hasRemaining()) {
      int b0 = input.readUnsignedByte();
      if (b0 == 10 && localSubroutineIndexProvided) { // process subr command
        Integer operand = (Integer) sequence.remove(sequence.size() - 1);
        // get subrbias
        int bias = 0;
        int nSubrs = localSubrIndex.getCount();

        if (nSubrs < 1240) {
          bias = 107;
        } else if (nSubrs < 33900) {
          bias = 1131;
        } else {
          bias = 32768;
        }
        int subrNumber = bias + operand;
        if (subrNumber < localSubrIndex.getCount()) {
          byte[] subrBytes = localSubrIndex.getBytes(subrNumber);
          parse(subrBytes, globalSubrIndex, localSubrIndex, false);
          Object lastItem = sequence.get(sequence.size() - 1);
          if (lastItem instanceof CharStringCommand
              && ((CharStringCommand) lastItem).getKey().getValue()[0] == 11) {
            sequence.remove(sequence.size() - 1); // remove "return" command
          }
        }

      } else if (b0 == 29 && globalSubroutineIndexProvided) { // process globalsubr command
        Integer operand = (Integer) sequence.remove(sequence.size() - 1);
        // get subrbias
        int bias = 0;
        int nSubrs = globalSubrIndex.getCount();

        if (nSubrs < 1240) {
          bias = 107;
        } else if (nSubrs < 33900) {
          bias = 1131;
        } else {
          bias = 32768;
        }

        int subrNumber = bias + operand;
        if (subrNumber < globalSubrIndex.getCount()) {
          byte[] subrBytes = globalSubrIndex.getBytes(subrNumber);
          parse(subrBytes, globalSubrIndex, localSubrIndex, false);
          Object lastItem = sequence.get(sequence.size() - 1);
          if (lastItem instanceof CharStringCommand
              && ((CharStringCommand) lastItem).getKey().getValue()[0] == 11) {
            sequence.remove(sequence.size() - 1); // remove "return" command
          }
        }

      } else if (b0 >= 0 && b0 <= 27) {
        sequence.add(readCommand(b0, input));
      } else if (b0 == 28) {
        sequence.add(readNumber(b0, input));
      } else if (b0 >= 29 && b0 <= 31) {
        sequence.add(readCommand(b0, input));
      } else if (b0 >= 32 && b0 <= 255) {
        sequence.add(readNumber(b0, input));
      } else {
        throw new IllegalArgumentException();
      }
    }
    return sequence;
  }