Home | History | Annotate | Download | only in server
      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 
     17 package com.android.server;
     18 
     19 import android.util.Slog;
     20 
     21 import java.io.Closeable;
     22 import java.io.DataOutput;
     23 import java.io.EOFException;
     24 import java.io.FileInputStream;
     25 import java.io.IOException;
     26 import java.io.InputStream;
     27 import java.io.RandomAccessFile;
     28 
     29 /**
     30  * A 4k block of random {@code byte}s.
     31  */
     32 class RandomBlock {
     33 
     34     private static final String TAG = "RandomBlock";
     35     private static final boolean DEBUG = false;
     36     private static final int BLOCK_SIZE = 4096;
     37     private byte[] block = new byte[BLOCK_SIZE];
     38 
     39     private RandomBlock() { }
     40 
     41     static RandomBlock fromFile(String filename) throws IOException {
     42         if (DEBUG) Slog.v(TAG, "reading from file " + filename);
     43         InputStream stream = null;
     44         try {
     45             stream = new FileInputStream(filename);
     46             return fromStream(stream);
     47         } finally {
     48             close(stream);
     49         }
     50     }
     51 
     52     private static RandomBlock fromStream(InputStream in) throws IOException {
     53         RandomBlock retval = new RandomBlock();
     54         int total = 0;
     55         while(total < BLOCK_SIZE) {
     56             int result = in.read(retval.block, total, BLOCK_SIZE - total);
     57             if (result == -1) {
     58                 throw new EOFException();
     59             }
     60             total += result;
     61         }
     62         return retval;
     63     }
     64 
     65     void toFile(String filename, boolean sync) throws IOException {
     66         if (DEBUG) Slog.v(TAG, "writing to file " + filename);
     67         RandomAccessFile out = null;
     68         try {
     69             out = new RandomAccessFile(filename, sync ? "rws" : "rw");
     70             toDataOut(out);
     71             truncateIfPossible(out);
     72         } finally {
     73             close(out);
     74         }
     75     }
     76 
     77     private static void truncateIfPossible(RandomAccessFile f) {
     78         try {
     79             f.setLength(BLOCK_SIZE);
     80         } catch (IOException e) {
     81             // ignore this exception.  Sometimes, the file we're trying to
     82             // write is a character device, such as /dev/urandom, and
     83             // these character devices do not support setting the length.
     84         }
     85     }
     86 
     87     private void toDataOut(DataOutput out) throws IOException {
     88         out.write(block);
     89     }
     90 
     91     private static void close(Closeable c) {
     92         try {
     93             if (c == null) {
     94                 return;
     95             }
     96             c.close();
     97         } catch (IOException e) {
     98             Slog.w(TAG, "IOException thrown while closing Closeable", e);
     99         }
    100     }
    101 }
    102