14fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich/*
24fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * Copyright (C) 2009 The Android Open Source Project
34fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich *
44fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * Licensed under the Apache License, Version 2.0 (the "License");
54fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * you may not use this file except in compliance with the License.
64fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * You may obtain a copy of the License at
74fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich *
84fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich *      http://www.apache.org/licenses/LICENSE-2.0
94fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich *
104fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * Unless required by applicable law or agreed to in writing, software
114fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * distributed under the License is distributed on an "AS IS" BASIS,
124fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * See the License for the specific language governing permissions and
144fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich * limitations under the License.
154fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich */
164fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
174fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichpackage com.android.server;
184fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
198a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog;
204fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
214fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichimport java.io.Closeable;
222854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevichimport java.io.DataOutput;
234fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichimport java.io.EOFException;
244fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichimport java.io.FileInputStream;
254fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichimport java.io.IOException;
264fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichimport java.io.InputStream;
272854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevichimport java.io.RandomAccessFile;
284fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
294fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich/**
303c2ae2f4eda7ec231519efeb5275c06087ec9e5bAlex Klyubin * A block of 512 random {@code byte}s.
314fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich */
324fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevichclass RandomBlock {
334fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
344fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    private static final String TAG = "RandomBlock";
35bd0a81ff1c0e92e80e05e2f12bb1805c7d081e94Dianne Hackborn    private static final boolean DEBUG = false;
363c2ae2f4eda7ec231519efeb5275c06087ec9e5bAlex Klyubin    private static final int BLOCK_SIZE = 512;
374fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    private byte[] block = new byte[BLOCK_SIZE];
384fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
394fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    private RandomBlock() { }
404fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
414fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    static RandomBlock fromFile(String filename) throws IOException {
428a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "reading from file " + filename);
434fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        InputStream stream = null;
444fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        try {
454fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            stream = new FileInputStream(filename);
464fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            return fromStream(stream);
474fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        } finally {
484fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            close(stream);
494fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        }
504fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    }
514fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
524fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    private static RandomBlock fromStream(InputStream in) throws IOException {
534fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        RandomBlock retval = new RandomBlock();
544fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        int total = 0;
554fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        while(total < BLOCK_SIZE) {
564fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            int result = in.read(retval.block, total, BLOCK_SIZE - total);
574fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            if (result == -1) {
584fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich                throw new EOFException();
594fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            }
604fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            total += result;
614fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        }
624fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        return retval;
634fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    }
644fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
656907891b1f2d706fa2bd6c40b986f73e5666e00eElliott Hughes    void toFile(String filename, boolean sync) throws IOException {
668a9b22056b13477f59df934928c00c58b5871c95Joe Onorato        if (DEBUG) Slog.v(TAG, "writing to file " + filename);
672854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich        RandomAccessFile out = null;
684fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        try {
696907891b1f2d706fa2bd6c40b986f73e5666e00eElliott Hughes            out = new RandomAccessFile(filename, sync ? "rws" : "rw");
702854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            toDataOut(out);
712854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            truncateIfPossible(out);
724fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        } finally {
734fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            close(out);
744fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        }
754fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    }
764fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
772854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich    private static void truncateIfPossible(RandomAccessFile f) {
782854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich        try {
792854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            f.setLength(BLOCK_SIZE);
802854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich        } catch (IOException e) {
812854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            // ignore this exception.  Sometimes, the file we're trying to
822854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            // write is a character device, such as /dev/urandom, and
832854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich            // these character devices do not support setting the length.
842854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich        }
852854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich    }
862854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich
872854254c2f59544d682d41ffee4fc1e1f2a604a3Nick Kralevich    private void toDataOut(DataOutput out) throws IOException {
884fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        out.write(block);
894fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    }
904fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich
914fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    private static void close(Closeable c) {
924fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        try {
934fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            if (c == null) {
944fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich                return;
954fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            }
964fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich            c.close();
974fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        } catch (IOException e) {
988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato            Slog.w(TAG, "IOException thrown while closing Closeable", e);
994fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich        }
1004fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich    }
1014fb256117ca271e3e37284a19b663d116f6ec20cNick Kralevich}
102