public void write()

in tools/dexfuzz/src/dexfuzz/rawdex/RawDexFile.java [77:303]


  public void write(DexRandomAccessFile file) throws IOException {
    file.seek(0);

    // We read the header first, and then the map list, and then everything
    // else. Therefore, when we get to the end of the header, tell OffsetTracker
    // to skip past the map list offsets, and then when we get to the map list,
    // tell OffsetTracker to skip back there, and then return to where it was previously.

    // Update the map items' sizes first
    // - but only update the items that we expect to have changed size.
    // ALSO update the header's table sizes!
    for (MapItem mapItem : mapList.mapItems) {
      switch (mapItem.type) {
        case MapItem.TYPE_STRING_ID_ITEM:
          if (mapItem.size != stringIds.size()) {
            Log.debug("Updating StringIDs List size: " + stringIds.size());
            mapItem.size = stringIds.size();
            header.stringIdsSize = stringIds.size();
          }
          break;
        case MapItem.TYPE_STRING_DATA_ITEM:
          if (mapItem.size != stringDatas.size()) {
            Log.debug("Updating StringDatas List size: " + stringDatas.size());
            mapItem.size = stringDatas.size();
          }
          break;
        case MapItem.TYPE_METHOD_ID_ITEM:
          if (mapItem.size != methodIds.size()) {
            Log.debug("Updating MethodIDs List size: " + methodIds.size());
            mapItem.size = methodIds.size();
            header.methodIdsSize = methodIds.size();
          }
          break;
        case MapItem.TYPE_FIELD_ID_ITEM:
          if (mapItem.size != fieldIds.size()) {
            Log.debug("Updating FieldIDs List size: " + fieldIds.size());
            mapItem.size = fieldIds.size();
            header.fieldIdsSize = fieldIds.size();
          }
          break;
        case MapItem.TYPE_PROTO_ID_ITEM:
          if (mapItem.size != protoIds.size()) {
            Log.debug("Updating ProtoIDs List size: " + protoIds.size());
            mapItem.size = protoIds.size();
            header.protoIdsSize = protoIds.size();
          }
          break;
        case MapItem.TYPE_TYPE_ID_ITEM:
          if (mapItem.size != typeIds.size()) {
            Log.debug("Updating TypeIDs List size: " + typeIds.size());
            mapItem.size = typeIds.size();
            header.typeIdsSize = typeIds.size();
          }
          break;
        case MapItem.TYPE_TYPE_LIST:
          if (mapItem.size != typeLists.size()) {
            Log.debug("Updating TypeLists List size: " + typeLists.size());
            mapItem.size = typeLists.size();
          }
          break;
        default:
      }
    }

    // Use the map list to write the file.
    for (MapItem mapItem : mapList.mapItems) {
      switch (mapItem.type) {
        case MapItem.TYPE_HEADER_ITEM:
          header.write(file);
          file.getOffsetTracker().skipToAfterMapList();
          break;
        case MapItem.TYPE_STRING_ID_ITEM:
          if (mapItem.size != stringIds.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches StringIDs table size " + stringIds.size());
          }
          for (StringIdItem stringId : stringIds) {
            stringId.write(file);
          }
          break;
        case MapItem.TYPE_TYPE_ID_ITEM:
          if (mapItem.size != typeIds.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches TypeIDs table size " + typeIds.size());
          }
          for (TypeIdItem typeId : typeIds) {
            typeId.write(file);
          }
          break;
        case MapItem.TYPE_PROTO_ID_ITEM:
          if (mapItem.size != protoIds.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches ProtoIDs table size " + protoIds.size());
          }
          for (ProtoIdItem protoId : protoIds) {
            protoId.write(file);
          }
          break;
        case MapItem.TYPE_FIELD_ID_ITEM:
          if (mapItem.size != fieldIds.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches FieldIDs table size " + fieldIds.size());
          }
          for (FieldIdItem fieldId : fieldIds) {
            fieldId.write(file);
          }
          break;
        case MapItem.TYPE_METHOD_ID_ITEM:
          if (mapItem.size != methodIds.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches MethodIDs table size " + methodIds.size());
          }
          for (MethodIdItem methodId : methodIds) {
            methodId.write(file);
          }
          break;
        case MapItem.TYPE_CLASS_DEF_ITEM:
          if (mapItem.size != classDefs.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches ClassDefs table size " + classDefs.size());
          }
          for (ClassDefItem classDef : classDefs) {
            classDef.write(file);
          }
          break;
        case MapItem.TYPE_MAP_LIST:
          file.getOffsetTracker().goBackToMapList();
          mapList.write(file);
          file.getOffsetTracker().goBackToPreviousPoint();
          break;
        case MapItem.TYPE_TYPE_LIST:
          if (mapItem.size != typeLists.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches TypeLists table size " + typeLists.size());
          }
          for (TypeList typeList : typeLists) {
            typeList.write(file);
          }
          break;
        case MapItem.TYPE_ANNOTATION_SET_REF_LIST:
          if (mapItem.size != annotationSetRefLists.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches AnnotationSetRefLists table size "
                + annotationSetRefLists.size());
          }
          for (AnnotationSetRefList annotationSetRefList : annotationSetRefLists) {
            annotationSetRefList.write(file);
          }
          break;
        case MapItem.TYPE_ANNOTATION_SET_ITEM:
          if (mapItem.size != annotationSetItems.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches AnnotationSetItems table size "
                + annotationSetItems.size());
          }
          for (AnnotationSetItem annotationSetItem : annotationSetItems) {
            annotationSetItem.write(file);
          }
          break;
        case MapItem.TYPE_CLASS_DATA_ITEM:
          if (mapItem.size != classDatas.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches ClassDataItems table size " + classDatas.size());
          }
          for (ClassDataItem classData : classDatas) {
            classData.write(file);
          }
          break;
        case MapItem.TYPE_CODE_ITEM:
          if (mapItem.size != codeItems.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches CodeItems table size " + codeItems.size());
          }
          for (CodeItem codeItem : codeItems) {
            codeItem.write(file);
          }
          break;
        case MapItem.TYPE_STRING_DATA_ITEM:
          if (mapItem.size != stringDatas.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches StringDataItems table size "
                + stringDatas.size());
          }
          for (StringDataItem stringDataItem : stringDatas) {
            stringDataItem.write(file);
          }
          break;
        case MapItem.TYPE_DEBUG_INFO_ITEM:
          debugInfoItem.write(file);
          break;
        case MapItem.TYPE_ANNOTATION_ITEM:
          if (mapItem.size != annotationItems.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches AnnotationItems table size "
                + annotationItems.size());
          }
          for (AnnotationItem annotationItem : annotationItems) {
            annotationItem.write(file);
          }
          break;
        case MapItem.TYPE_ENCODED_ARRAY_ITEM:
          if (mapItem.size != encodedArrayItems.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches EncodedArrayItems table size "
                + encodedArrayItems.size());
          }
          for (EncodedArrayItem encodedArrayItem : encodedArrayItems) {
            encodedArrayItem.write(file);
          }
          break;
        case MapItem.TYPE_ANNOTATIONS_DIRECTORY_ITEM:
          if (mapItem.size != annotationsDirectoryItems.size()) {
            Log.errorAndQuit("MapItem's size " + mapItem.size
                + " no longer matches AnnotationDirectoryItems table size "
                + annotationsDirectoryItems.size());
          }
          for (AnnotationsDirectoryItem annotationsDirectory : annotationsDirectoryItems) {
            annotationsDirectory.write(file);
          }
          break;
        default:
          Log.errorAndQuit("Encountered unknown map item in map item list.");
      }
    }

    file.getOffsetTracker().updateOffsets(file);
  }