Merge "More cleanup to imgdiff & imgpatch" am: 3541934ff5 am: 91f8574061
am: dda128abbf

Change-Id: I4369d91759d40a1fb261766fb5b1e6aa0ecb36c4
diff --git a/applypatch/Android.mk b/applypatch/Android.mk
index 8be5c36..a7412d2 100644
--- a/applypatch/Android.mk
+++ b/applypatch/Android.mk
@@ -21,8 +21,7 @@
     applypatch.cpp \
     bspatch.cpp \
     freecache.cpp \
-    imgpatch.cpp \
-    utils.cpp
+    imgpatch.cpp
 LOCAL_MODULE := libapplypatch
 LOCAL_MODULE_TAGS := eng
 LOCAL_C_INCLUDES := \
@@ -46,8 +45,7 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
     bspatch.cpp \
-    imgpatch.cpp \
-    utils.cpp
+    imgpatch.cpp
 LOCAL_MODULE := libimgpatch
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/include \
@@ -56,6 +54,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libcrypto \
     libbspatch \
+    libbase \
     libbz \
     libz
 LOCAL_CFLAGS := \
@@ -68,8 +67,7 @@
 include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
     bspatch.cpp \
-    imgpatch.cpp \
-    utils.cpp
+    imgpatch.cpp
 LOCAL_MODULE := libimgpatch
 LOCAL_MODULE_HOST_OS := linux
 LOCAL_C_INCLUDES := \
@@ -79,6 +77,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libcrypto \
     libbspatch \
+    libbase \
     libbz \
     libz
 LOCAL_CFLAGS := \
@@ -123,9 +122,7 @@
 LOCAL_CFLAGS := -Werror
 include $(BUILD_EXECUTABLE)
 
-libimgdiff_src_files := \
-    imgdiff.cpp \
-    utils.cpp
+libimgdiff_src_files := imgdiff.cpp
 
 # libbsdiff is compiled with -D_FILE_OFFSET_BITS=64.
 libimgdiff_cflags := \
diff --git a/applypatch/imgdiff.cpp b/applypatch/imgdiff.cpp
index fba74e8..41d73ab 100644
--- a/applypatch/imgdiff.cpp
+++ b/applypatch/imgdiff.cpp
@@ -145,12 +145,22 @@
 #include <bsdiff.h>
 #include <zlib.h>
 
-#include "utils.h"
-
 using android::base::get_unaligned;
 
 static constexpr auto BUFFER_SIZE = 0x8000;
 
+// If we use this function to write the offset and length (type size_t), their values should not
+// exceed 2^63; because the signed bit will be casted away.
+static inline bool Write8(int fd, int64_t value) {
+  return android::base::WriteFully(fd, &value, sizeof(int64_t));
+}
+
+// Similarly, the value should not exceed 2^31 if we are casting from size_t (e.g. target chunk
+// size).
+static inline bool Write4(int fd, int32_t value) {
+  return android::base::WriteFully(fd, &value, sizeof(int32_t));
+}
+
 class ImageChunk {
  public:
   static constexpr auto WINDOWBITS = -15;  // 32kb window; negative to indicate a raw stream.
@@ -163,11 +173,12 @@
         start_(start),
         input_file_ptr_(file_content),
         raw_data_len_(raw_data_len),
-        entry_name_(""),
         compress_level_(6),
         source_start_(0),
         source_len_(0),
-        source_uncompressed_len_(0) {}
+        source_uncompressed_len_(0) {
+    CHECK(file_content != nullptr) << "input file container can't be nullptr";
+  }
 
   int GetType() const {
     return type_;
@@ -199,7 +210,8 @@
   }
 
   size_t GetHeaderSize(size_t patch_size) const;
-  size_t WriteHeaderToFile(FILE* f, const std::vector<uint8_t> patch, size_t offset);
+  // Return the offset of the next patch into the patch data.
+  size_t WriteHeaderToFd(int fd, const std::vector<uint8_t>& patch, size_t offset);
 
   /*
    * Cause a gzip chunk to be treated as a normal chunk (ie, as a blob
@@ -222,9 +234,9 @@
   void MergeAdjacentNormal(const ImageChunk& other);
 
  private:
-  int type_;                                   // CHUNK_NORMAL, CHUNK_DEFLATE, CHUNK_RAW
-  size_t start_;                               // offset of chunk in the original input file
-  const std::vector<uint8_t>* input_file_ptr_; // pointer to the full content of original input file
+  int type_;                                    // CHUNK_NORMAL, CHUNK_DEFLATE, CHUNK_RAW
+  size_t start_;                                // offset of chunk in the original input file
+  const std::vector<uint8_t>* input_file_ptr_;  // ptr to the full content of original input file
   size_t raw_data_len_;
 
   // --- for CHUNK_DEFLATE chunks only: ---
@@ -280,11 +292,11 @@
 }
 
 void ImageChunk::SetEntryName(std::string entryname) {
-  entry_name_ = entryname;
+  entry_name_ = std::move(entryname);
 }
 
 void ImageChunk::SetUncompressedData(std::vector<uint8_t> data) {
-  uncompressed_data_ = data;
+  uncompressed_data_ = std::move(data);
 }
 
 bool ImageChunk::SetBonusData(const std::vector<uint8_t>& bonus_data) {
@@ -295,7 +307,7 @@
   return true;
 }
 
-// Convert CHUNK_NORMAL & CHUNK_DEFLATE to CHUNK_RAW if the terget size is
+// Convert CHUNK_NORMAL & CHUNK_DEFLATE to CHUNK_RAW if the target size is
 // smaller. Also take the header size into account during size comparison.
 bool ImageChunk::ChangeChunkToRaw(size_t patch_size) {
   if (type_ == CHUNK_RAW) {
@@ -310,6 +322,7 @@
 void ImageChunk::ChangeDeflateChunkToNormal() {
   if (type_ != CHUNK_DEFLATE) return;
   type_ = CHUNK_NORMAL;
+  entry_name_.clear();
   uncompressed_data_.clear();
 }
 
@@ -317,7 +330,7 @@
 // header_type    4 bytes
 // CHUNK_NORMAL   8*3 = 24 bytes
 // CHUNK_DEFLATE  8*5 + 4*5 = 60 bytes
-// CHUNK_RAW      4 bytes
+// CHUNK_RAW      4 bytes + patch_size
 size_t ImageChunk::GetHeaderSize(size_t patch_size) const {
   switch (type_) {
     case CHUNK_NORMAL:
@@ -327,43 +340,43 @@
     case CHUNK_RAW:
       return 4 + 4 + patch_size;
     default:
-      printf("unexpected chunk type: %d\n", type_);  // should not reach here.
-      CHECK(false);
+      CHECK(false) << "unexpected chunk type: " << type_;  // Should not reach here.
       return 0;
   }
 }
 
-size_t ImageChunk::WriteHeaderToFile(FILE* f, const std::vector<uint8_t> patch, size_t offset) {
-  Write4(type_, f);
+size_t ImageChunk::WriteHeaderToFd(int fd, const std::vector<uint8_t>& patch, size_t offset) {
+  Write4(fd, type_);
   switch (type_) {
     case CHUNK_NORMAL:
       printf("normal   (%10zu, %10zu)  %10zu\n", start_, raw_data_len_, patch.size());
-      Write8(source_start_, f);
-      Write8(source_len_, f);
-      Write8(offset, f);
+      Write8(fd, static_cast<int64_t>(source_start_));
+      Write8(fd, static_cast<int64_t>(source_len_));
+      Write8(fd, static_cast<int64_t>(offset));
       return offset + patch.size();
     case CHUNK_DEFLATE:
       printf("deflate  (%10zu, %10zu)  %10zu  %s\n", start_, raw_data_len_, patch.size(),
              entry_name_.c_str());
-      Write8(source_start_, f);
-      Write8(source_len_, f);
-      Write8(offset, f);
-      Write8(source_uncompressed_len_, f);
-      Write8(uncompressed_data_.size(), f);
-      Write4(compress_level_, f);
-      Write4(METHOD, f);
-      Write4(WINDOWBITS, f);
-      Write4(MEMLEVEL, f);
-      Write4(STRATEGY, f);
+      Write8(fd, static_cast<int64_t>(source_start_));
+      Write8(fd, static_cast<int64_t>(source_len_));
+      Write8(fd, static_cast<int64_t>(offset));
+      Write8(fd, static_cast<int64_t>(source_uncompressed_len_));
+      Write8(fd, static_cast<int64_t>(uncompressed_data_.size()));
+      Write4(fd, compress_level_);
+      Write4(fd, METHOD);
+      Write4(fd, WINDOWBITS);
+      Write4(fd, MEMLEVEL);
+      Write4(fd, STRATEGY);
       return offset + patch.size();
     case CHUNK_RAW:
       printf("raw      (%10zu, %10zu)\n", start_, raw_data_len_);
-      Write4(patch.size(), f);
-      fwrite(patch.data(), 1, patch.size(), f);
+      Write4(fd, static_cast<int32_t>(patch.size()));
+      if (!android::base::WriteFully(fd, patch.data(), patch.size())) {
+        CHECK(false) << "failed to write " << patch.size() <<" bytes patch";
+      }
       return offset;
     default:
-      printf("unexpected chunk type: %d\n", type_);
-      CHECK(false);
+      CHECK(false) << "unexpected chunk type: " << type_;
       return offset;
   }
 }
@@ -480,20 +493,21 @@
 
 static bool ReadZip(const char* filename, std::vector<ImageChunk>* chunks,
                     std::vector<uint8_t>* zip_file, bool include_pseudo_chunk) {
-  CHECK(zip_file != nullptr);
+  CHECK(chunks != nullptr && zip_file != nullptr);
+
+  android::base::unique_fd fd(open(filename, O_RDONLY));
+  if (fd == -1) {
+    printf("failed to open \"%s\" %s\n", filename, strerror(errno));
+    return false;
+  }
   struct stat st;
-  if (stat(filename, &st) != 0) {
+  if (fstat(fd, &st) != 0) {
     printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
     return false;
   }
 
   size_t sz = static_cast<size_t>(st.st_size);
   zip_file->resize(sz);
-  android::base::unique_fd fd(open(filename, O_RDONLY));
-  if (fd == -1) {
-    printf("failed to open \"%s\" %s\n", filename, strerror(errno));
-    return false;
-  }
   if (!android::base::ReadFully(fd, zip_file->data(), sz)) {
     printf("failed to read \"%s\" %s\n", filename, strerror(errno));
     return false;
@@ -596,20 +610,21 @@
 // Read the given file and break it up into chunks, and putting the data in to a vector.
 static bool ReadImage(const char* filename, std::vector<ImageChunk>* chunks,
                       std::vector<uint8_t>* img) {
-  CHECK(img != nullptr);
+  CHECK(chunks != nullptr && img != nullptr);
+
+  android::base::unique_fd fd(open(filename, O_RDONLY));
+  if (fd == -1) {
+    printf("failed to open \"%s\" %s\n", filename, strerror(errno));
+    return false;
+  }
   struct stat st;
-  if (stat(filename, &st) != 0) {
+  if (fstat(fd, &st) != 0) {
     printf("failed to stat \"%s\": %s\n", filename, strerror(errno));
     return false;
   }
 
   size_t sz = static_cast<size_t>(st.st_size);
   img->resize(sz);
-  android::base::unique_fd fd(open(filename, O_RDONLY));
-  if (fd == -1) {
-    printf("failed to open \"%s\" %s\n", filename, strerror(errno));
-    return false;
-  }
   if (!android::base::ReadFully(fd, img->data(), sz)) {
     printf("failed to read \"%s\" %s\n", filename, strerror(errno));
     return false;
@@ -618,9 +633,8 @@
   size_t pos = 0;
 
   while (pos < sz) {
-    if (sz - pos >= 4 && img->at(pos) == 0x1f && img->at(pos + 1) == 0x8b &&
-        img->at(pos + 2) == 0x08 &&  // deflate compression
-        img->at(pos + 3) == 0x00) {  // no header flags
+    // 0x00 no header flags, 0x08 deflate compression, 0x1f8b gzip magic number
+    if (sz - pos >= 4 && get_unaligned<uint32_t>(img->data() + pos) == 0x00088b1f) {
       // 'pos' is the offset of the start of a gzip chunk.
       size_t chunk_offset = pos;
 
@@ -695,7 +709,7 @@
       // the uncompressed data.  Double-check to make sure that it
       // matches the size of the data we got when we actually did
       // the decompression.
-      size_t footer_size = Read4(img->data() + pos - 4);
+      size_t footer_size = get_unaligned<uint32_t>(img->data() + pos - 4);
       if (footer_size != body.DataLengthForPatch()) {
         printf("Error: footer size %zu != decompressed size %zu\n", footer_size,
                body.GetRawDataLength());
@@ -708,9 +722,8 @@
       // Scan forward until we find a gzip header.
       size_t data_len = 0;
       while (data_len + pos < sz) {
-        if (data_len + pos + 4 <= sz && img->at(pos + data_len) == 0x1f &&
-            img->at(pos + data_len + 1) == 0x8b && img->at(pos + data_len + 2) == 0x08 &&
-            img->at(pos + data_len + 3) == 0x00) {
+        if (data_len + pos + 4 <= sz &&
+            get_unaligned<uint32_t>(img->data() + pos + data_len) == 0x00088b1f) {
           break;
         }
         data_len++;
@@ -759,13 +772,19 @@
     return false;
   }
 
+  android::base::unique_fd patch_fd(open(ptemp, O_RDONLY));
+  if (patch_fd == -1) {
+    printf("failed to open %s: %s\n", ptemp, strerror(errno));
+    return false;
+  }
   struct stat st;
-  if (stat(ptemp, &st) != 0) {
+  if (fstat(patch_fd, &st) != 0) {
     printf("failed to stat patch file %s: %s\n", ptemp, strerror(errno));
     return false;
   }
 
   size_t sz = static_cast<size_t>(st.st_size);
+  // Change the chunk type to raw if the patch takes less space that way.
   if (tgt->ChangeChunkToRaw(sz)) {
     unlink(ptemp);
     size_t patch_size = tgt->DataLengthForPatch();
@@ -773,12 +792,6 @@
     std::copy(tgt->DataForPatch(), tgt->DataForPatch() + patch_size, patch_data->begin());
     return true;
   }
-
-  android::base::unique_fd patch_fd(open(ptemp, O_RDONLY));
-  if (patch_fd == -1) {
-    printf("failed to open %s: %s\n", ptemp, strerror(errno));
-    return false;
-  }
   patch_data->resize(sz);
   if (!android::base::ReadFully(patch_fd, patch_data->data(), sz)) {
     printf("failed to read \"%s\" %s\n", ptemp, strerror(errno));
@@ -845,18 +858,19 @@
 
   std::vector<uint8_t> bonus_data;
   if (argc >= 3 && strcmp(argv[1], "-b") == 0) {
-    struct stat st;
-    if (stat(argv[2], &st) != 0) {
-      printf("failed to stat bonus file %s: %s\n", argv[2], strerror(errno));
-      return 1;
-    }
-    size_t bonus_size = st.st_size;
-    bonus_data.resize(bonus_size);
     android::base::unique_fd fd(open(argv[2], O_RDONLY));
     if (fd == -1) {
       printf("failed to open bonus file %s: %s\n", argv[2], strerror(errno));
       return 1;
     }
+    struct stat st;
+    if (fstat(fd, &st) != 0) {
+      printf("failed to stat bonus file %s: %s\n", argv[2], strerror(errno));
+      return 1;
+    }
+
+    size_t bonus_size = st.st_size;
+    bonus_data.resize(bonus_size);
     if (!android::base::ReadFully(fd, bonus_data.data(), bonus_size)) {
       printf("failed to read bonus file %s: %s\n", argv[2], strerror(errno));
       return 1;
@@ -999,9 +1013,15 @@
       ImageChunk* src;
       if (tgt_chunks[i].GetType() == CHUNK_DEFLATE &&
           (src = FindChunkByName(tgt_chunks[i].GetEntryName(), src_chunks))) {
-        MakePatch(src, &tgt_chunks[i], &patch_data[i], nullptr);
+        if (!MakePatch(src, &tgt_chunks[i], &patch_data[i], nullptr)) {
+          printf("Failed to generate patch for target chunk %zu: ", i);
+          return 1;
+        }
       } else {
-        MakePatch(&src_chunks[0], &tgt_chunks[i], &patch_data[i], &bsdiff_cache);
+        if (!MakePatch(&src_chunks[0], &tgt_chunks[i], &patch_data[i], &bsdiff_cache)) {
+          printf("Failed to generate patch for target chunk %zu: ", i);
+          return 1;
+        }
       }
     } else {
       if (i == 1 && !bonus_data.empty()) {
@@ -1009,7 +1029,10 @@
         src_chunks[i].SetBonusData(bonus_data);
       }
 
-      MakePatch(&src_chunks[i], &tgt_chunks[i], &patch_data[i], nullptr);
+      if (!MakePatch(&src_chunks[i], &tgt_chunks[i], &patch_data[i], nullptr)) {
+        printf("Failed to generate patch for target chunk %zu: ", i);
+        return 1;
+      }
     }
     printf("patch %3zu is %zu bytes (of %zu)\n", i, patch_data[i].size(),
            src_chunks[i].GetRawDataLength());
@@ -1030,28 +1053,32 @@
 
   size_t offset = total_header_size;
 
-  FILE* f = fopen(argv[3], "wb");
-  if (f == nullptr) {
+  android::base::unique_fd patch_fd(open(argv[3], O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR));
+  if (patch_fd == -1) {
     printf("failed to open \"%s\": %s\n", argv[3], strerror(errno));
+    return 1;
   }
 
   // Write out the headers.
-
-  fwrite("IMGDIFF2", 1, 8, f);
-  Write4(static_cast<int32_t>(tgt_chunks.size()), f);
+  if (!android::base::WriteStringToFd("IMGDIFF2", patch_fd)) {
+    printf("failed to write \"IMGDIFF2\" to \"%s\": %s\n", argv[3], strerror(errno));
+    return 1;
+  }
+  Write4(patch_fd, static_cast<int32_t>(tgt_chunks.size()));
   for (size_t i = 0; i < tgt_chunks.size(); ++i) {
     printf("chunk %zu: ", i);
-    offset = tgt_chunks[i].WriteHeaderToFile(f, patch_data[i], offset);
+    offset = tgt_chunks[i].WriteHeaderToFd(patch_fd, patch_data[i], offset);
   }
 
   // Append each chunk's bsdiff patch, in order.
   for (size_t i = 0; i < tgt_chunks.size(); ++i) {
     if (tgt_chunks[i].GetType() != CHUNK_RAW) {
-      fwrite(patch_data[i].data(), 1, patch_data[i].size(), f);
+      if (!android::base::WriteFully(patch_fd, patch_data[i].data(), patch_data[i].size())) {
+        CHECK(false) << "failed to write " << patch_data[i].size() << " bytes patch for chunk "
+                     << i;
+      }
     }
   }
 
-  fclose(f);
-
   return 0;
 }
diff --git a/applypatch/imgpatch.cpp b/applypatch/imgpatch.cpp
index 8f4a2a4..adcc61f 100644
--- a/applypatch/imgpatch.cpp
+++ b/applypatch/imgpatch.cpp
@@ -31,10 +31,17 @@
 
 #include <applypatch/applypatch.h>
 #include <applypatch/imgdiff.h>
+#include <android-base/memory.h>
 #include <openssl/sha.h>
 #include <zlib.h>
 
-#include "utils.h"
+static inline int64_t Read8(const void *address) {
+  return android::base::get_unaligned<int64_t>(address);
+}
+
+static inline int32_t Read4(const void *address) {
+  return android::base::get_unaligned<int32_t>(address);
+}
 
 int ApplyImagePatch(const unsigned char* old_data, ssize_t old_size,
                     const unsigned char* patch_data, ssize_t patch_size,
@@ -86,9 +93,9 @@
         return -1;
       }
 
-      size_t src_start = Read8(normal_header);
-      size_t src_len = Read8(normal_header + 8);
-      size_t patch_offset = Read8(normal_header + 16);
+      size_t src_start = static_cast<size_t>(Read8(normal_header));
+      size_t src_len = static_cast<size_t>(Read8(normal_header + 8));
+      size_t patch_offset = static_cast<size_t>(Read8(normal_header + 16));
 
       if (src_start + src_len > static_cast<size_t>(old_size)) {
         printf("source data too short\n");
@@ -125,11 +132,11 @@
         return -1;
       }
 
-      size_t src_start = Read8(deflate_header);
-      size_t src_len = Read8(deflate_header + 8);
-      size_t patch_offset = Read8(deflate_header + 16);
-      size_t expanded_len = Read8(deflate_header + 24);
-      size_t target_len = Read8(deflate_header + 32);
+      size_t src_start = static_cast<size_t>(Read8(deflate_header));
+      size_t src_len = static_cast<size_t>(Read8(deflate_header + 8));
+      size_t patch_offset = static_cast<size_t>(Read8(deflate_header + 16));
+      size_t expanded_len = static_cast<size_t>(Read8(deflate_header + 24));
+      size_t target_len = static_cast<size_t>(Read8(deflate_header + 32));
       int level = Read4(deflate_header + 40);
       int method = Read4(deflate_header + 44);
       int windowBits = Read4(deflate_header + 48);
diff --git a/applypatch/utils.cpp b/applypatch/utils.cpp
deleted file mode 100644
index 450dc8d..0000000
--- a/applypatch/utils.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-
-#include "utils.h"
-
-/** Write a 4-byte value to f in little-endian order. */
-void Write4(int value, FILE* f) {
-  fputc(value & 0xff, f);
-  fputc((value >> 8) & 0xff, f);
-  fputc((value >> 16) & 0xff, f);
-  fputc((value >> 24) & 0xff, f);
-}
-
-/** Write an 8-byte value to f in little-endian order. */
-void Write8(int64_t value, FILE* f) {
-  fputc(value & 0xff, f);
-  fputc((value >> 8) & 0xff, f);
-  fputc((value >> 16) & 0xff, f);
-  fputc((value >> 24) & 0xff, f);
-  fputc((value >> 32) & 0xff, f);
-  fputc((value >> 40) & 0xff, f);
-  fputc((value >> 48) & 0xff, f);
-  fputc((value >> 56) & 0xff, f);
-}
-
-int Read2(const void* pv) {
-    const unsigned char* p = reinterpret_cast<const unsigned char*>(pv);
-    return (int)(((unsigned int)p[1] << 8) |
-                 (unsigned int)p[0]);
-}
-
-int Read4(const void* pv) {
-    const unsigned char* p = reinterpret_cast<const unsigned char*>(pv);
-    return (int)(((unsigned int)p[3] << 24) |
-                 ((unsigned int)p[2] << 16) |
-                 ((unsigned int)p[1] << 8) |
-                 (unsigned int)p[0]);
-}
-
-int64_t Read8(const void* pv) {
-    const unsigned char* p = reinterpret_cast<const unsigned char*>(pv);
-    return (int64_t)(((uint64_t)p[7] << 56) |
-                       ((uint64_t)p[6] << 48) |
-                       ((uint64_t)p[5] << 40) |
-                       ((uint64_t)p[4] << 32) |
-                       ((uint64_t)p[3] << 24) |
-                       ((uint64_t)p[2] << 16) |
-                       ((uint64_t)p[1] << 8) |
-                       (uint64_t)p[0]);
-}
diff --git a/applypatch/utils.h b/applypatch/utils.h
deleted file mode 100644
index c7c8e90..0000000
--- a/applypatch/utils.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _BUILD_TOOLS_APPLYPATCH_UTILS_H
-#define _BUILD_TOOLS_APPLYPATCH_UTILS_H
-
-#include <inttypes.h>
-#include <stdio.h>
-
-// Read and write little-endian values of various sizes.
-
-void Write4(int value, FILE* f);
-void Write8(int64_t value, FILE* f);
-int Read2(const void* p);
-int Read4(const void* p);
-int64_t Read8(const void* p);
-
-#endif //  _BUILD_TOOLS_APPLYPATCH_UTILS_H
diff --git a/tests/component/imgdiff_test.cpp b/tests/component/imgdiff_test.cpp
index be2dd38..2f64850 100644
--- a/tests/component/imgdiff_test.cpp
+++ b/tests/component/imgdiff_test.cpp
@@ -18,13 +18,14 @@
 #include <vector>
 
 #include <android-base/file.h>
+#include <android-base/memory.h>
 #include <android-base/test_utils.h>
 #include <applypatch/imgdiff.h>
 #include <applypatch/imgpatch.h>
 #include <gtest/gtest.h>
 #include <ziparchive/zip_writer.h>
 
-#include "applypatch/utils.h"
+using android::base::get_unaligned;
 
 static ssize_t MemorySink(const unsigned char* data, ssize_t len, void* token) {
   std::string* s = static_cast<std::string*>(token);
@@ -41,7 +42,7 @@
   ASSERT_GE(size, 12U);
   ASSERT_EQ("IMGDIFF2", std::string(data, 8));
 
-  const int num_chunks = Read4(data + 8);
+  const int num_chunks = get_unaligned<int32_t>(data + 8);
   ASSERT_GE(num_chunks, 0);
 
   size_t normal = 0;
@@ -51,7 +52,7 @@
   size_t pos = 12;
   for (int i = 0; i < num_chunks; ++i) {
     ASSERT_LE(pos + 4, size);
-    int type = Read4(data + pos);
+    int type = get_unaligned<int32_t>(data + pos);
     pos += 4;
     if (type == CHUNK_NORMAL) {
       pos += 24;
@@ -59,7 +60,7 @@
       normal++;
     } else if (type == CHUNK_RAW) {
       ASSERT_LE(pos + 4, size);
-      ssize_t data_len = Read4(data + pos);
+      ssize_t data_len = get_unaligned<int32_t>(data + pos);
       ASSERT_GT(data_len, 0);
       pos += 4 + data_len;
       ASSERT_LE(pos, size);