BackupDataInput.java revision e28290e21f908b4e917099ff2aa41e3aab9310c2
11cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato/*
21cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Copyright (C) 2009 The Android Open Source Project
31cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
41cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * you may not use this file except in compliance with the License.
61cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * You may obtain a copy of the License at
71cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
81cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato *
101cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * Unless required by applicable law or agreed to in writing, software
111cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * See the License for the specific language governing permissions and
141cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato * limitations under the License.
151cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato */
161cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
171cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratopackage android.backup;
181cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
191cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport android.content.Context;
201cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
211cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport java.io.FileDescriptor;
221cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratoimport java.io.IOException;
231cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
24e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate/**
25e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate * STOPSHIP: document!
26e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate */
271cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onoratopublic class BackupDataInput {
281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    int mBackupReader;
291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private EntityHeader mHeader = new EntityHeader();
311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private boolean mHeaderReady;
321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
331cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private static class EntityHeader {
341cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        String key;
351cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        int dataSize;
361cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
371cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
38e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /** @hide */
391cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public BackupDataInput(FileDescriptor fd) {
401cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (fd == null) throw new NullPointerException();
411cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        mBackupReader = ctor(fd);
421cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (mBackupReader == 0) {
431cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new RuntimeException("Native initialization failed with fd=" + fd);
441cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
451cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
461cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
47e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /** @hide */
481cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    protected void finalize() throws Throwable {
491cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        try {
501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            dtor(mBackupReader);
511cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } finally {
521cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            super.finalize();
531cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
541cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
551cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
56e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
57e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Consumes the next header from the restore stream.
58e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
59e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return true when there is an entity ready for consumption from the restore stream,
60e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *    false if the restore stream has been fully consumed.
61e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IOException if an error occurred while reading the restore stream
62e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
631cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public boolean readNextHeader() throws IOException {
641cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        int result = readNextHeader_native(mBackupReader, mHeader);
651cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (result == 0) {
661cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            // read successfully
671cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            mHeaderReady = true;
681cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return true;
691cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else if (result > 0) {
701cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            // done
711cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            mHeaderReady = false;
721cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return false;
731cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
741cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            // error
751cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            mHeaderReady = false;
761cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IOException("result=0x" + Integer.toHexString(result));
771cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
781cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
791cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
80e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
81e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Report the key associated with the current record in the restore stream
82e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return the current record's key string
83e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IllegalStateException if the next record header has not yet been read
84e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
851cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public String getKey() {
861cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (mHeaderReady) {
871cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return mHeader.key;
881cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
891cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IllegalStateException("mHeaderReady=false");
901cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
911cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
921cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
93e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
94e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Report the size in bytes of the data associated with the current record in the
95e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * restore stream.
96e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
97e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return The size of the record's raw data, in bytes
98e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IllegalStateException if the next record header has not yet been read
99e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
1001cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    public int getDataSize() {
1011cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (mHeaderReady) {
1021cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            return mHeader.dataSize;
1031cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
1041cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IllegalStateException("mHeaderReady=false");
1051cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
1061cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1071cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
108e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
109e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Read a record's raw data from the restore stream.  The record's header must first
110e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * have been processed by the {@link #readNextHeader()} method.  Multiple calls to
111e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * this method may be made in order to process the data in chunks; not all of it
112e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * must be read in a single call.
113e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
114e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param data An allocated byte array of at least 'size' bytes
115e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param offset Offset within the 'data' array at which the data will be placed
116e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *    when read from the stream.
117e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @param size The number of bytes to read in this pass.
118e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @return The number of bytes of data read
119e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IOException if an error occurred when trying to read the restore data stream
120e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
1215f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    public int readEntityData(byte[] data, int offset, int size) throws IOException {
1221cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        if (mHeaderReady) {
1235f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato            int result = readEntityData_native(mBackupReader, data, offset, size);
1241cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            if (result >= 0) {
1251cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato                return result;
1261cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            } else {
1271cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato                throw new IOException("result=0x" + Integer.toHexString(result));
1281cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            }
1291cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        } else {
1301cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato            throw new IllegalStateException("mHeaderReady=false");
1311cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato        }
1321cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    }
1331cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
134e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate    /**
135e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * Consume the current record's data without actually reading it into a buffer
136e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * for further processing.  This allows a {@link android.backup.BackupAgent} to
137e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * efficiently discard obsolete or otherwise uninteresting records during the
138e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * restore operation.
139e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     *
140e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     * @throws IOException if an error occurred when trying to read the restore data stream
141e28290e21f908b4e917099ff2aa41e3aab9310c2Christopher Tate     */
1425f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    public void skipEntityData() throws IOException {
1435f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        if (mHeaderReady) {
1449bb8fd77c8dc177aab9ac96bed4f55972dcda70aJoe Onorato            skipEntityData_native(mBackupReader);
1455f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        } else {
1465f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato            throw new IllegalStateException("mHeaderReady=false");
1475f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato        }
1485f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    }
1495f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato
1501cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private native static int ctor(FileDescriptor fd);
1511cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private native static void dtor(int mBackupReader);
1521cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato
1531cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato    private native int readNextHeader_native(int mBackupReader, EntityHeader entity);
1545f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    private native int readEntityData_native(int mBackupReader, byte[] data, int offset, int size);
1555f15d151b5101fadfe6cba1e8f4aa6367e8c603eJoe Onorato    private native int skipEntityData_native(int mBackupReader);
1561cf587496fcb1d652bab9fc6792fb106b6fefaa4Joe Onorato}
157