AcmAsyncInputStream.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android.android_acm_serial;
00018 
00019 import com.google.common.base.Preconditions;
00020 
00021 import android.hardware.usb.UsbConstants;
00022 import android.hardware.usb.UsbEndpoint;
00023 import android.hardware.usb.UsbRequest;
00024 import android.util.Log;
00025 
00026 import java.io.IOException;
00027 import java.io.InputStream;
00028 import java.nio.ByteBuffer;
00029 
00030 public class AcmAsyncInputStream extends InputStream {
00031 
00032   private static final boolean DEBUG = false;
00033   private static final String TAG = "AcmAsyncInputStream";
00034 
00035   private final UsbRequestPool usbRequestPool;
00036   private final UsbEndpoint endpoint;
00037 
00038   public AcmAsyncInputStream(UsbRequestPool usbRequestPool, UsbEndpoint endpoint) {
00039     Preconditions.checkArgument(endpoint.getDirection() == UsbConstants.USB_DIR_IN);
00040     this.endpoint = endpoint;
00041     this.usbRequestPool = usbRequestPool;
00042   }
00043 
00044   @Override
00045   public void close() throws IOException {
00046     usbRequestPool.shutdown();
00047   }
00048 
00049   @Override
00050   public int read(byte[] buffer, int offset, int count) throws IOException {
00051     Preconditions.checkNotNull(buffer);
00052     if (offset < 0 || count < 0 || offset + count > buffer.length) {
00053       throw new IndexOutOfBoundsException();
00054     }
00055     // NOTE(damonkohler): According to the InputStream.read() javadoc, we should
00056     // be able to return 0 when we didn't read anything. However, it also says
00057     // we should block until input is available. Blocking seems to be the
00058     // preferred behavior.
00059     if (DEBUG) {
00060       Log.i(TAG, "Reading " + count + " bytes.");
00061     }
00062     int byteCount = 0;
00063     while (byteCount == 0) {
00064       UsbRequest request = usbRequestPool.poll(endpoint);
00065       if (!request.queue(ByteBuffer.wrap(buffer, offset, count), count)) {
00066         Log.e(TAG, "IO error while queuing " + count + " bytes to be read.");
00067       }
00068     }
00069     if (byteCount < 0) {
00070       throw new IOException("USB read failed.");
00071     }
00072     // System.arraycopy(slice, 0, buffer, offset, byteCount);
00073     if (DEBUG) {
00074       Log.i(TAG, "Actually read " + byteCount + " bytes.");
00075       // Log.i(TAG, "Slice: " + byteArrayToHexString(slice));
00076     }
00077     return byteCount;
00078   }
00079 
00080   @Override
00081   public int read() throws IOException {
00082     throw new UnsupportedOperationException();
00083   }
00084 
00085   // TODO(damonkohler): Possibly move this to some common place?
00086   private static String byteArrayToHexString(byte[] data) {
00087     if (data == null) {
00088       return "null";
00089     }
00090     if (data.length == 0) {
00091       return "empty";
00092     }
00093     StringBuilder out = new StringBuilder(data.length * 5);
00094     for (byte b : data) {
00095       out.append(String.format("%02x", b));
00096     }
00097     return out.toString();
00098   }
00099 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Aug 27 2015 12:11:33