checkpoint BackupDatAInput / RestoreHelper
diff --git a/libs/utils/BackupData.cpp b/libs/utils/BackupData.cpp
index 8c9f875..16ff1e5 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/utils/BackupData.cpp
@@ -86,46 +86,6 @@
 }
 
 status_t
-BackupDataWriter::WriteAppHeader(const String8& packageName, int cookie)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    ssize_t amt;
-
-    amt = write_padding_for(m_pos);
-    if (amt != 0) {
-        return amt;
-    }
-
-    app_header_v1 header;
-    ssize_t nameLen;
-
-    nameLen = packageName.length();
-
-    header.type = tolel(BACKUP_HEADER_APP_V1);
-    header.packageLen = tolel(nameLen);
-    header.cookie = cookie;
-
-    amt = write(m_fd, &header, sizeof(app_header_v1));
-    if (amt != sizeof(app_header_v1)) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    amt = write(m_fd, packageName.string(), nameLen+1);
-    if (amt != nameLen+1) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    return NO_ERROR;
-}
-
-status_t
 BackupDataWriter::WriteEntityHeader(const String8& key, size_t dataSize)
 {
     if (m_status != NO_ERROR) {
@@ -188,40 +148,11 @@
     return NO_ERROR;
 }
 
-status_t
-BackupDataWriter::WriteAppFooter(int cookie)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-
-    ssize_t amt;
-
-    amt = write_padding_for(m_pos);
-    if (amt != 0) {
-        return amt;
-    }
-
-    app_footer_v1 footer;
-    ssize_t nameLen;
-
-    footer.type = tolel(BACKUP_FOOTER_APP_V1);
-    footer.entityCount = tolel(m_entityCount);
-    footer.cookie = cookie;
-
-    amt = write(m_fd, &footer, sizeof(app_footer_v1));
-    if (amt != sizeof(app_footer_v1)) {
-        m_status = errno;
-        return m_status;
-    }
-    m_pos += amt;
-
-    return NO_ERROR;
-}
 
 
 BackupDataReader::BackupDataReader(int fd)
     :m_fd(fd),
+     m_done(false),
      m_status(NO_ERROR),
      m_pos(0),
      m_entityCount(0)
@@ -260,31 +191,25 @@
     } while(0)
 
 status_t
-BackupDataReader::ReadNextHeader(int* type)
+BackupDataReader::ReadNextHeader(bool* done, int* type)
 {
+    *done = m_done;
     if (m_status != NO_ERROR) {
         return m_status;
     }
 
     int amt;
 
-    SKIP_PADDING();
+    // No error checking here, in case we're at the end of the stream.  Just let read() fail.
+    skip_padding();
     amt = read(m_fd, &m_header, sizeof(m_header));
+    *done = m_done = (amt == 0);
     CHECK_SIZE(amt, sizeof(m_header));
 
     // validate and fix up the fields.
     m_header.type = fromlel(m_header.type);
     switch (m_header.type)
     {
-        case BACKUP_HEADER_APP_V1:
-            m_header.app.packageLen = fromlel(m_header.app.packageLen);
-            if (m_header.app.packageLen < 0) {
-                LOGD("App header at %d has packageLen<0: 0x%08x\n", (int)m_pos,
-                    (int)m_header.app.packageLen);
-                m_status = EINVAL;
-            }
-            m_header.app.cookie = m_header.app.cookie;
-            break;
         case BACKUP_HEADER_ENTITY_V1:
             m_header.entity.keyLen = fromlel(m_header.entity.keyLen);
             if (m_header.entity.keyLen <= 0) {
@@ -295,15 +220,6 @@
             m_header.entity.dataSize = fromlel(m_header.entity.dataSize);
             m_entityCount++;
             break;
-        case BACKUP_FOOTER_APP_V1:
-            m_header.footer.entityCount = fromlel(m_header.footer.entityCount);
-            if (m_header.footer.entityCount < 0) {
-                LOGD("Entity header at %d has entityCount<0: 0x%08x\n", (int)m_pos,
-                        (int)m_header.footer.entityCount);
-                m_status = EINVAL;
-            }
-            m_header.footer.cookie = m_header.footer.cookie;
-            break;
         default:
             LOGD("Chunk header at %d has invalid type: 0x%08x", (int)m_pos, (int)m_header.type);
             m_status = EINVAL;
@@ -316,30 +232,6 @@
     return m_status;
 }
 
-status_t
-BackupDataReader::ReadAppHeader(String8* packageName, int* cookie)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_HEADER_APP_V1) {
-        return EINVAL;
-    }
-    size_t size = m_header.app.packageLen;
-    char* buf = packageName->lockBuffer(size);
-    if (buf == NULL) {
-        packageName->unlockBuffer();
-        m_status = ENOMEM;
-        return m_status;
-    }
-    int amt = read(m_fd, buf, size+1);
-    CHECK_SIZE(amt, (int)size+1);
-    packageName->unlockBuffer(size);
-    m_pos += size+1;
-    *cookie = m_header.app.cookie;
-    return NO_ERROR;
-}
-
 bool
 BackupDataReader::HasEntities()
 {
@@ -368,6 +260,7 @@
     m_pos += size+1;
     *dataSize = m_header.entity.dataSize;
     SKIP_PADDING();
+    m_dataEndPos = m_pos + *dataSize;
     return NO_ERROR;
 }
 
@@ -381,7 +274,7 @@
         return EINVAL;
     }
     if (m_header.entity.dataSize > 0) {
-        int pos = lseek(m_fd, m_header.entity.dataSize, SEEK_CUR);
+        int pos = lseek(m_fd, m_dataEndPos, SEEK_SET);
         return pos == -1 ? (int)errno : (int)NO_ERROR;
     } else {
         return NO_ERROR;
@@ -394,6 +287,15 @@
     if (m_status != NO_ERROR) {
         return m_status;
     }
+    int remaining = m_dataEndPos - m_pos;
+    if (size > remaining) {
+        printf("size=%d m_pos=0x%x m_dataEndPos=0x%x remaining=%d\n",
+                size, m_pos, m_dataEndPos, remaining);
+        size = remaining;
+    }
+    if (remaining <= 0) {
+        return 0;
+    }
     int amt = read(m_fd, data, size);
     CHECK_SIZE(amt, (int)size);
     m_pos += size;
@@ -401,25 +303,6 @@
 }
 
 status_t
-BackupDataReader::ReadAppFooter(int* cookie)
-{
-    if (m_status != NO_ERROR) {
-        return m_status;
-    }
-    if (m_header.type != BACKUP_FOOTER_APP_V1) {
-        return EINVAL;
-    }
-    if (m_header.footer.entityCount != m_entityCount) {
-        LOGD("entity count mismatch actual=%d expected=%d", m_entityCount,
-                m_header.footer.entityCount);
-        m_status = EINVAL;
-        return m_status;
-    }
-    *cookie = m_header.footer.cookie;
-    return NO_ERROR;
-}
-
-status_t
 BackupDataReader::skip_padding()
 {
     ssize_t amt;
diff --git a/libs/utils/BackupHelpers.cpp b/libs/utils/BackupHelpers.cpp
index 4c3e37d..c1d5404 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/utils/BackupHelpers.cpp
@@ -689,41 +689,27 @@
 
 // hexdump -v -e '"    " 8/1 " 0x%02x," "\n"' data_writer.data
 const unsigned char DATA_GOLDEN_FILE[] = {
-     0x41, 0x70, 0x70, 0x31, 0x0b, 0x00, 0x00, 0x00,
-     0xdd, 0xcc, 0xbb, 0xaa, 0x6e, 0x6f, 0x5f, 0x70,
-     0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
      0x44, 0x61, 0x74, 0x61, 0x0b, 0x00, 0x00, 0x00,
      0x0c, 0x00, 0x00, 0x00, 0x6e, 0x6f, 0x5f, 0x70,
      0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x00,
      0x6e, 0x6f, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69,
-     0x6e, 0x67, 0x5f, 0x00, 0x41, 0x70, 0x70, 0x31,
-     0x0c, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
+     0x6e, 0x67, 0x5f, 0x00, 0x44, 0x61, 0x74, 0x61,
+     0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
      0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
      0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
-     0x44, 0x61, 0x74, 0x61, 0x0c, 0x00, 0x00, 0x00,
-     0x0d, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
-     0x00, 0xbc, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x5f, 0x33,
-     0x00, 0xbc, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
-     0x0d, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
      0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x5f, 0x32, 0x5f, 0x5f, 0x00, 0xbc, 0xbc,
+     0x6f, 0x5f, 0x5f, 0x33, 0x00, 0xbc, 0xbc, 0xbc,
      0x44, 0x61, 0x74, 0x61, 0x0d, 0x00, 0x00, 0x00,
      0x0e, 0x00, 0x00, 0x00, 0x70, 0x61, 0x64, 0x64,
      0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
      0x5f, 0x00, 0xbc, 0xbc, 0x70, 0x61, 0x64, 0x64,
      0x65, 0x64, 0x5f, 0x74, 0x6f, 0x5f, 0x32, 0x5f,
-     0x5f, 0x00, 0xbc, 0xbc, 0x41, 0x70, 0x70, 0x31,
-     0x0a, 0x00, 0x00, 0x00, 0xdd, 0xcc, 0xbb, 0xaa,
-     0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
-     0x6f, 0x31, 0x00, 0xbc, 0x44, 0x61, 0x74, 0x61,
+     0x5f, 0x00, 0xbc, 0xbc, 0x44, 0x61, 0x74, 0x61,
      0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
      0x70, 0x61, 0x64, 0x64, 0x65, 0x64, 0x5f, 0x74,
      0x6f, 0x31, 0x00, 0xbc, 0x70, 0x61, 0x64, 0x64,
-     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00, 0xbc,
-     0x46, 0x6f, 0x6f, 0x74, 0x04, 0x00, 0x00, 0x00,
-     0x99, 0x99, 0x77, 0x77
+     0x65, 0x64, 0x5f, 0x74, 0x6f, 0x31, 0x00
+
 };
 const int DATA_GOLDEN_FILE_SIZE = sizeof(DATA_GOLDEN_FILE);
 
@@ -733,12 +719,6 @@
     int err;
     String8 text(str);
 
-    err = writer.WriteAppHeader(text, 0xaabbccdd);
-    if (err != 0) {
-        fprintf(stderr, "WriteAppHeader failed with %s\n", strerror(err));
-        return err;
-    }
-
     err = writer.WriteEntityHeader(text, text.length()+1);
     if (err != 0) {
         fprintf(stderr, "WriteEntityHeader failed with %s\n", strerror(err));
@@ -779,8 +759,6 @@
     err |= test_write_header_and_entity(writer, "padded_to_2__");
     err |= test_write_header_and_entity(writer, "padded_to1");
 
-    writer.WriteAppFooter(0x77779999);
-
     close(fd);
 
     err = compare_file(filename, DATA_GOLDEN_FILE, DATA_GOLDEN_FILE_SIZE);
@@ -800,70 +778,59 @@
     String8 string;
     int cookie = 0x11111111;
     size_t actualSize;
+    bool done;
+    int type;
 
     // printf("\n\n---------- test_read_header_and_entity -- %s\n\n", str);
 
-    err = reader.ReadNextHeader();
+    err = reader.ReadNextHeader(&done, &type);
+    if (done) {
+        fprintf(stderr, "should not be done yet\n");
+        goto finished;
+    }
     if (err != 0) {
         fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
-        goto done;
+        goto finished;
     }
-
-    err = reader.ReadAppHeader(&string, &cookie);
-    if (err != 0) {
-        fprintf(stderr, "ReadAppHeader failed with %s\n", strerror(err));
-        goto done;
-    }
-    if (string != str) {
-        fprintf(stderr, "ReadAppHeader expected packageName '%s' got '%s'\n", str, string.string());
+    if (type != BACKUP_HEADER_ENTITY_V1) {
         err = EINVAL;
-        goto done;
-    }
-    if (cookie != (int)0xaabbccdd) {
-        fprintf(stderr, "ReadAppHeader expected cookie 0x%08x got 0x%08x\n", 0xaabbccdd, cookie);
-        err = EINVAL;
-        goto done;
-    }
-
-    err = reader.ReadNextHeader();
-    if (err != 0) {
-        fprintf(stderr, "ReadNextHeader (for entity header) failed with %s\n", strerror(err));
-        goto done;
+        fprintf(stderr, "type=0x%08x expected 0x%08x\n", type, BACKUP_HEADER_ENTITY_V1);
     }
 
     err = reader.ReadEntityHeader(&string, &actualSize);
     if (err != 0) {
         fprintf(stderr, "ReadEntityHeader failed with %s\n", strerror(err));
-        goto done;
+        goto finished;
     }
     if (string != str) {
         fprintf(stderr, "ReadEntityHeader expected key '%s' got '%s'\n", str, string.string());
         err = EINVAL;
-        goto done;
+        goto finished;
     }
     if ((int)actualSize != bufSize) {
         fprintf(stderr, "ReadEntityHeader expected dataSize 0x%08x got 0x%08x\n", bufSize,
                 actualSize);
         err = EINVAL;
-        goto done;
+        goto finished;
     }
 
     err = reader.ReadEntityData(buf, bufSize);
     if (err != NO_ERROR) {
         fprintf(stderr, "ReadEntityData failed with %s\n", strerror(err));
-        goto done;
+        goto finished;
     }
 
     if (0 != memcmp(buf, str, bufSize)) {
         fprintf(stderr, "ReadEntityData expected '%s' but got something starting with "
-                "%02x %02x %02x %02x\n", str, buf[0], buf[1], buf[2], buf[3]);
+                "%02x %02x %02x %02x  '%c%c%c%c'\n", str, buf[0], buf[1], buf[2], buf[3],
+                buf[0], buf[1], buf[2], buf[3]);
         err = EINVAL;
-        goto done;
+        goto finished;
     }
 
     // The next read will confirm whether it got the right amount of data.
 
-done:
+finished:
     if (err != NO_ERROR) {
         fprintf(stderr, "test_read_header_and_entity failed with %s\n", strerror(err));
     }
@@ -923,23 +890,6 @@
         if (err == NO_ERROR) {
             err = test_read_header_and_entity(reader, "padded_to1");
         }
-
-        if (err == NO_ERROR) {
-            err = reader.ReadNextHeader();
-            if (err != 0) {
-                fprintf(stderr, "ReadNextHeader (for app header) failed with %s\n", strerror(err));
-            }
-
-            if (err == NO_ERROR) {
-                int cookie;
-                err |= reader.ReadAppFooter(&cookie);
-                if (cookie != 0x77779999) {
-                    fprintf(stderr, "app footer cookie expected=0x%08x actual=0x%08x\n",
-                        0x77779999, cookie);
-                    err = EINVAL;
-                }
-            }
-        }
     }
 
     close(fd);