1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.android_webview;
6
7import android.util.Log;
8
9import org.chromium.base.CalledByNative;
10import org.chromium.base.JNINamespace;
11
12import java.io.IOException;
13import java.io.InputStream;
14
15/**
16 * Utility methods for calling InputStream methods. These take care of exception handling.
17 */
18@JNINamespace("android_webview")
19class InputStreamUtil {
20    private static final String LOGTAG = "InputStreamUtil";
21    // The InputStream APIs return -1 in some cases. In order to convey the extra information that
22    // the call had failed due to an exception being thrown we simply map all negative return values
23    // from the original calls to -1 and make -2 mean that an exception has been thrown.
24    private static final int CALL_FAILED_STATUS = -1;
25    private static final int EXCEPTION_THROWN_STATUS = -2;
26
27    private static String logMessage(String method) {
28        return "Got exception when calling " + method + "() on an InputStream returned from " +
29            "shouldInterceptRequest. This will cause the related request to fail.";
30    }
31
32    @CalledByNative
33    public static void close(InputStream stream) {
34        try {
35            stream.close();
36        } catch (IOException e) {
37            Log.e(LOGTAG, logMessage("close"), e);
38        }
39    }
40
41    @CalledByNative
42    public static int available(InputStream stream) {
43        try {
44            return Math.max(CALL_FAILED_STATUS, stream.available());
45        } catch (IOException e) {
46            Log.e(LOGTAG, logMessage("available"), e);
47            return EXCEPTION_THROWN_STATUS;
48        }
49    }
50
51    @CalledByNative
52    public static int read(InputStream stream, byte[] b, int off, int len) {
53        try {
54            return Math.max(CALL_FAILED_STATUS, stream.read(b, off, len));
55        } catch (IOException e) {
56            Log.e(LOGTAG, logMessage("read"), e);
57            return EXCEPTION_THROWN_STATUS;
58        }
59    }
60
61    @CalledByNative
62    public static long skip(InputStream stream, long n) {
63        try {
64            return Math.max(CALL_FAILED_STATUS, stream.skip(n));
65        } catch (IOException e) {
66            Log.e(LOGTAG, logMessage("skip"), e);
67            return EXCEPTION_THROWN_STATUS;
68        }
69    }
70}
71