Dexlayout cleanup and refactoring.

Created option to output to a mem map in preparation of hooking
dexlayout into dex2oat.

Test: mm test-art-host-gtest-dexlayout_test
Bug: 29921113
Change-Id: Id42ef15cb8f83cc8d05b025b7647a4338e9b96b0
diff --git a/dexlayout/dex_writer.cc b/dexlayout/dex_writer.cc
index dba5da0..7ffa38b 100644
--- a/dexlayout/dex_writer.cc
+++ b/dexlayout/dex_writer.cc
@@ -104,7 +104,9 @@
 }
 
 size_t DexWriter::Write(const void* buffer, size_t length, size_t offset) {
-  return dex_file_->PwriteFully(buffer, length, offset) ? length : 0;
+  DCHECK_LE(offset + length, mem_map_->Size());
+  memcpy(mem_map_->Begin() + offset, buffer, length);
+  return length;
 }
 
 size_t DexWriter::WriteSleb128(uint32_t value, size_t offset) {
@@ -236,12 +238,13 @@
 
 void DexWriter::WriteStrings() {
   uint32_t string_data_off[1];
-  for (std::unique_ptr<dex_ir::StringId>& string_id : header_.GetCollections().StringIds()) {
+  for (std::unique_ptr<dex_ir::StringId>& string_id : header_->GetCollections().StringIds()) {
     string_data_off[0] = string_id->DataItem()->GetOffset();
     Write(string_data_off, string_id->GetSize(), string_id->GetOffset());
   }
 
-  for (std::unique_ptr<dex_ir::StringData>& string_data : header_.GetCollections().StringDatas()) {
+  for (auto& string_data_pair : header_->GetCollections().StringDatas()) {
+    std::unique_ptr<dex_ir::StringData>& string_data = string_data_pair.second;
     uint32_t offset = string_data->GetOffset();
     offset += WriteUleb128(CountModifiedUtf8Chars(string_data->Data()), offset);
     Write(string_data->Data(), strlen(string_data->Data()), offset);
@@ -250,7 +253,7 @@
 
 void DexWriter::WriteTypes() {
   uint32_t descriptor_idx[1];
-  for (std::unique_ptr<dex_ir::TypeId>& type_id : header_.GetCollections().TypeIds()) {
+  for (std::unique_ptr<dex_ir::TypeId>& type_id : header_->GetCollections().TypeIds()) {
     descriptor_idx[0] = type_id->GetStringId()->GetIndex();
     Write(descriptor_idx, type_id->GetSize(), type_id->GetOffset());
   }
@@ -259,7 +262,8 @@
 void DexWriter::WriteTypeLists() {
   uint32_t size[1];
   uint16_t list[1];
-  for (std::unique_ptr<dex_ir::TypeList>& type_list : header_.GetCollections().TypeLists()) {
+  for (auto& type_list_pair : header_->GetCollections().TypeLists()) {
+    std::unique_ptr<dex_ir::TypeList>& type_list = type_list_pair.second;
     size[0] = type_list->GetTypeList()->size();
     uint32_t offset = type_list->GetOffset();
     offset += Write(size, sizeof(uint32_t), offset);
@@ -272,7 +276,7 @@
 
 void DexWriter::WriteProtos() {
   uint32_t buffer[3];
-  for (std::unique_ptr<dex_ir::ProtoId>& proto_id : header_.GetCollections().ProtoIds()) {
+  for (std::unique_ptr<dex_ir::ProtoId>& proto_id : header_->GetCollections().ProtoIds()) {
     buffer[0] = proto_id->Shorty()->GetIndex();
     buffer[1] = proto_id->ReturnType()->GetIndex();
     buffer[2] = proto_id->Parameters() == nullptr ? 0 : proto_id->Parameters()->GetOffset();
@@ -282,7 +286,7 @@
 
 void DexWriter::WriteFields() {
   uint16_t buffer[4];
-  for (std::unique_ptr<dex_ir::FieldId>& field_id : header_.GetCollections().FieldIds()) {
+  for (std::unique_ptr<dex_ir::FieldId>& field_id : header_->GetCollections().FieldIds()) {
     buffer[0] = field_id->Class()->GetIndex();
     buffer[1] = field_id->Type()->GetIndex();
     buffer[2] = field_id->Name()->GetIndex();
@@ -293,7 +297,7 @@
 
 void DexWriter::WriteMethods() {
   uint16_t buffer[4];
-  for (std::unique_ptr<dex_ir::MethodId>& method_id : header_.GetCollections().MethodIds()) {
+  for (std::unique_ptr<dex_ir::MethodId>& method_id : header_->GetCollections().MethodIds()) {
     buffer[0] = method_id->Class()->GetIndex();
     buffer[1] = method_id->Proto()->GetIndex();
     buffer[2] = method_id->Name()->GetIndex();
@@ -303,16 +307,16 @@
 }
 
 void DexWriter::WriteEncodedArrays() {
-  for (std::unique_ptr<dex_ir::EncodedArrayItem>& encoded_array :
-      header_.GetCollections().EncodedArrayItems()) {
+  for (auto& encoded_array_pair : header_->GetCollections().EncodedArrayItems()) {
+    std::unique_ptr<dex_ir::EncodedArrayItem>& encoded_array = encoded_array_pair.second;
     WriteEncodedArray(encoded_array->GetEncodedValues(), encoded_array->GetOffset());
   }
 }
 
 void DexWriter::WriteAnnotations() {
   uint8_t visibility[1];
-  for (std::unique_ptr<dex_ir::AnnotationItem>& annotation :
-      header_.GetCollections().AnnotationItems()) {
+  for (auto& annotation_pair : header_->GetCollections().AnnotationItems()) {
+    std::unique_ptr<dex_ir::AnnotationItem>& annotation = annotation_pair.second;
     visibility[0] = annotation->GetVisibility();
     size_t offset = annotation->GetOffset();
     offset += Write(visibility, sizeof(uint8_t), offset);
@@ -323,8 +327,8 @@
 void DexWriter::WriteAnnotationSets() {
   uint32_t size[1];
   uint32_t annotation_off[1];
-  for (std::unique_ptr<dex_ir::AnnotationSetItem>& annotation_set :
-      header_.GetCollections().AnnotationSetItems()) {
+  for (auto& annotation_set_pair : header_->GetCollections().AnnotationSetItems()) {
+    std::unique_ptr<dex_ir::AnnotationSetItem>& annotation_set = annotation_set_pair.second;
     size[0] = annotation_set->GetItems()->size();
     size_t offset = annotation_set->GetOffset();
     offset += Write(size, sizeof(uint32_t), offset);
@@ -338,8 +342,8 @@
 void DexWriter::WriteAnnotationSetRefs() {
   uint32_t size[1];
   uint32_t annotations_off[1];
-  for (std::unique_ptr<dex_ir::AnnotationSetRefList>& annotation_set_ref :
-        header_.GetCollections().AnnotationSetRefLists()) {
+  for (auto& anno_set_ref_pair : header_->GetCollections().AnnotationSetRefLists()) {
+    std::unique_ptr<dex_ir::AnnotationSetRefList>& annotation_set_ref = anno_set_ref_pair.second;
     size[0] = annotation_set_ref->GetItems()->size();
     size_t offset = annotation_set_ref->GetOffset();
     offset += Write(size, sizeof(uint32_t), offset);
@@ -353,8 +357,9 @@
 void DexWriter::WriteAnnotationsDirectories() {
   uint32_t directory_buffer[4];
   uint32_t annotation_buffer[2];
-  for (std::unique_ptr<dex_ir::AnnotationsDirectoryItem>& annotations_directory :
-          header_.GetCollections().AnnotationsDirectoryItems()) {
+  for (auto& annotations_directory_pair : header_->GetCollections().AnnotationsDirectoryItems()) {
+    std::unique_ptr<dex_ir::AnnotationsDirectoryItem>& annotations_directory =
+        annotations_directory_pair.second;
     directory_buffer[0] = annotations_directory->GetClassAnnotation() == nullptr ? 0 :
         annotations_directory->GetClassAnnotation()->GetOffset();
     directory_buffer[1] = annotations_directory->GetFieldAnnotations() == nullptr ? 0 :
@@ -393,15 +398,17 @@
 }
 
 void DexWriter::WriteDebugInfoItems() {
-  for (std::unique_ptr<dex_ir::DebugInfoItem>& info : header_.GetCollections().DebugInfoItems()) {
-    Write(info->GetDebugInfo(), info->GetDebugInfoSize(), info->GetOffset());
+  for (auto& debug_info_pair : header_->GetCollections().DebugInfoItems()) {
+    std::unique_ptr<dex_ir::DebugInfoItem>& debug_info = debug_info_pair.second;
+    Write(debug_info->GetDebugInfo(), debug_info->GetDebugInfoSize(), debug_info->GetOffset());
   }
 }
 
 void DexWriter::WriteCodeItems() {
   uint16_t uint16_buffer[4];
   uint32_t uint32_buffer[2];
-  for (std::unique_ptr<dex_ir::CodeItem>& code_item : header_.GetCollections().CodeItems()) {
+  for (auto& code_item_pair : header_->GetCollections().CodeItems()) {
+    std::unique_ptr<dex_ir::CodeItem>& code_item = code_item_pair.second;
     uint16_buffer[0] = code_item->RegistersSize();
     uint16_buffer[1] = code_item->InsSize();
     uint16_buffer[2] = code_item->OutsSize();
@@ -446,7 +453,7 @@
 
 void DexWriter::WriteClasses() {
   uint32_t class_def_buffer[8];
-  for (std::unique_ptr<dex_ir::ClassDef>& class_def : header_.GetCollections().ClassDefs()) {
+  for (std::unique_ptr<dex_ir::ClassDef>& class_def : header_->GetCollections().ClassDefs()) {
     class_def_buffer[0] = class_def->ClassType()->GetIndex();
     class_def_buffer[1] = class_def->GetAccessFlags();
     class_def_buffer[2] = class_def->Superclass() == nullptr ? DexFile::kDexNoIndex :
@@ -464,7 +471,8 @@
     Write(class_def_buffer, class_def->GetSize(), offset);
   }
 
-  for (std::unique_ptr<dex_ir::ClassData>& class_data : header_.GetCollections().ClassDatas()) {
+  for (auto& class_data_pair : header_->GetCollections().ClassDatas()) {
+    std::unique_ptr<dex_ir::ClassData>& class_data = class_data_pair.second;
     size_t offset = class_data->GetOffset();
     offset += WriteUleb128(class_data->StaticFields()->size(), offset);
     offset += WriteUleb128(class_data->InstanceFields()->size(), offset);
@@ -491,7 +499,7 @@
 };
 
 void DexWriter::WriteMapItem() {
-  dex_ir::Collections& collection = header_.GetCollections();
+  dex_ir::Collections& collection = header_->GetCollections();
   std::priority_queue<MapItemContainer> queue;
 
   // Header and index section.
@@ -522,7 +530,7 @@
   }
 
   // Data section.
-  queue.push(MapItemContainer(DexFile::kDexTypeMapList, 1, collection.MapItemOffset()));
+  queue.push(MapItemContainer(DexFile::kDexTypeMapList, 1, collection.MapListOffset()));
   if (collection.TypeListsSize() != 0) {
     queue.push(MapItemContainer(DexFile::kDexTypeTypeList, collection.TypeListsSize(),
         collection.TypeListsOffset()));
@@ -564,7 +572,7 @@
         collection.AnnotationsDirectoryItemsSize(), collection.AnnotationsDirectoryItemsOffset()));
   }
 
-  uint32_t offset = collection.MapItemOffset();
+  uint32_t offset = collection.MapListOffset();
   uint16_t uint16_buffer[2];
   uint32_t uint32_buffer[2];
   uint16_buffer[1] = 0;
@@ -583,19 +591,19 @@
 
 void DexWriter::WriteHeader() {
   uint32_t buffer[20];
-  dex_ir::Collections& collections = header_.GetCollections();
+  dex_ir::Collections& collections = header_->GetCollections();
   size_t offset = 0;
-  offset += Write(header_.Magic(), 8 * sizeof(uint8_t), offset);
-  buffer[0] = header_.Checksum();
+  offset += Write(header_->Magic(), 8 * sizeof(uint8_t), offset);
+  buffer[0] = header_->Checksum();
   offset += Write(buffer, sizeof(uint32_t), offset);
-  offset += Write(header_.Signature(), 20 * sizeof(uint8_t), offset);
-  uint32_t file_size = header_.FileSize();
+  offset += Write(header_->Signature(), 20 * sizeof(uint8_t), offset);
+  uint32_t file_size = header_->FileSize();
   buffer[0] = file_size;
-  buffer[1] = header_.GetSize();
-  buffer[2] = header_.EndianTag();
-  buffer[3] = header_.LinkSize();
-  buffer[4] = header_.LinkOffset();
-  buffer[5] = collections.MapItemOffset();
+  buffer[1] = header_->GetSize();
+  buffer[2] = header_->EndianTag();
+  buffer[3] = header_->LinkSize();
+  buffer[4] = header_->LinkOffset();
+  buffer[5] = collections.MapListOffset();
   buffer[6] = collections.StringIdsSize();
   buffer[7] = collections.StringIdsOffset();
   buffer[8] = collections.TypeIdsSize();
@@ -617,12 +625,7 @@
   Write(buffer, 20 * sizeof(uint32_t), offset);
 }
 
-void DexWriter::WriteFile() {
-  if (dex_file_.get() == nullptr) {
-    fprintf(stderr, "Can't open output dex file\n");
-    return;
-  }
-
+void DexWriter::WriteMemMap() {
   WriteStrings();
   WriteTypes();
   WriteTypeLists();
@@ -641,8 +644,9 @@
   WriteHeader();
 }
 
-void DexWriter::OutputDexFile(dex_ir::Header& header, const char* file_name) {
-  (new DexWriter(header, file_name))->WriteFile();
+void DexWriter::Output(dex_ir::Header* header, MemMap* mem_map) {
+  DexWriter dex_writer(header, mem_map);
+  dex_writer.WriteMemMap();
 }
 
 }  // namespace art