BackupDataInput.java revision 4528186e0d65fc68ef0dd1941aa2ac8aefcd55a3
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.app.backup; 18 19import java.io.FileDescriptor; 20import java.io.IOException; 21 22/** 23 * STOPSHIP: document! 24 */ 25public class BackupDataInput { 26 int mBackupReader; 27 28 private EntityHeader mHeader = new EntityHeader(); 29 private boolean mHeaderReady; 30 31 private static class EntityHeader { 32 String key; 33 int dataSize; 34 } 35 36 /** @hide */ 37 public BackupDataInput(FileDescriptor fd) { 38 if (fd == null) throw new NullPointerException(); 39 mBackupReader = ctor(fd); 40 if (mBackupReader == 0) { 41 throw new RuntimeException("Native initialization failed with fd=" + fd); 42 } 43 } 44 45 /** @hide */ 46 protected void finalize() throws Throwable { 47 try { 48 dtor(mBackupReader); 49 } finally { 50 super.finalize(); 51 } 52 } 53 54 /** 55 * Consumes the next header from the restore stream. 56 * 57 * @return true when there is an entity ready for consumption from the restore stream, 58 * false if the restore stream has been fully consumed. 59 * @throws IOException if an error occurred while reading the restore stream 60 */ 61 public boolean readNextHeader() throws IOException { 62 int result = readNextHeader_native(mBackupReader, mHeader); 63 if (result == 0) { 64 // read successfully 65 mHeaderReady = true; 66 return true; 67 } else if (result > 0) { 68 // done 69 mHeaderReady = false; 70 return false; 71 } else { 72 // error 73 mHeaderReady = false; 74 throw new IOException("result=0x" + Integer.toHexString(result)); 75 } 76 } 77 78 /** 79 * Report the key associated with the current record in the restore stream 80 * @return the current record's key string 81 * @throws IllegalStateException if the next record header has not yet been read 82 */ 83 public String getKey() { 84 if (mHeaderReady) { 85 return mHeader.key; 86 } else { 87 throw new IllegalStateException("mHeaderReady=false"); 88 } 89 } 90 91 /** 92 * Report the size in bytes of the data associated with the current record in the 93 * restore stream. 94 * 95 * @return The size of the record's raw data, in bytes 96 * @throws IllegalStateException if the next record header has not yet been read 97 */ 98 public int getDataSize() { 99 if (mHeaderReady) { 100 return mHeader.dataSize; 101 } else { 102 throw new IllegalStateException("mHeaderReady=false"); 103 } 104 } 105 106 /** 107 * Read a record's raw data from the restore stream. The record's header must first 108 * have been processed by the {@link #readNextHeader()} method. Multiple calls to 109 * this method may be made in order to process the data in chunks; not all of it 110 * must be read in a single call. 111 * 112 * @param data An allocated byte array of at least 'size' bytes 113 * @param offset Offset within the 'data' array at which the data will be placed 114 * when read from the stream. 115 * @param size The number of bytes to read in this pass. 116 * @return The number of bytes of data read 117 * @throws IOException if an error occurred when trying to read the restore data stream 118 */ 119 public int readEntityData(byte[] data, int offset, int size) throws IOException { 120 if (mHeaderReady) { 121 int result = readEntityData_native(mBackupReader, data, offset, size); 122 if (result >= 0) { 123 return result; 124 } else { 125 throw new IOException("result=0x" + Integer.toHexString(result)); 126 } 127 } else { 128 throw new IllegalStateException("mHeaderReady=false"); 129 } 130 } 131 132 /** 133 * Consume the current record's data without actually reading it into a buffer 134 * for further processing. This allows a {@link android.app.backup.BackupAgent} to 135 * efficiently discard obsolete or otherwise uninteresting records during the 136 * restore operation. 137 * 138 * @throws IOException if an error occurred when trying to read the restore data stream 139 */ 140 public void skipEntityData() throws IOException { 141 if (mHeaderReady) { 142 skipEntityData_native(mBackupReader); 143 } else { 144 throw new IllegalStateException("mHeaderReady=false"); 145 } 146 } 147 148 private native static int ctor(FileDescriptor fd); 149 private native static void dtor(int mBackupReader); 150 151 private native int readNextHeader_native(int mBackupReader, EntityHeader entity); 152 private native int readEntityData_native(int mBackupReader, byte[] data, int offset, int size); 153 private native int skipEntityData_native(int mBackupReader); 154} 155