// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "android_webview/native/input_stream_impl.h"

#include "base/android/jni_android.h"
// Disable "Warnings treated as errors" for input_stream_jni as it's a Java
// system class and we have to generate C++ hooks for all methods in the class
// even if they're unused.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include "jni/InputStream_jni.h"
#pragma GCC diagnostic pop
#include "net/base/io_buffer.h"

using base::android::AttachCurrentThread;
using base::android::ClearException;
using base::android::JavaRef;
using JNI_InputStream::Java_InputStream_available;
using JNI_InputStream::Java_InputStream_close;
using JNI_InputStream::Java_InputStream_skip;
using JNI_InputStream::Java_InputStream_readI_AB_I_I;

namespace android_webview {

bool RegisterInputStream(JNIEnv* env) {
  return JNI_InputStream::RegisterNativesImpl(env);
}

// Maximum number of bytes to be read in a single read.
const int InputStreamImpl::kBufferSize = 4096;

//static
const InputStreamImpl* InputStreamImpl::FromInputStream(
        const InputStream* input_stream) {
    return static_cast<const InputStreamImpl*>(input_stream);
}

// TODO: Use unsafe version for all Java_InputStream methods in this file
// once BUG 157880 is fixed and implement graceful exception handling.

InputStreamImpl::InputStreamImpl() {
}

InputStreamImpl::InputStreamImpl(const JavaRef<jobject>& stream)
    : jobject_(stream) {
  DCHECK(!stream.is_null());
}

InputStreamImpl::~InputStreamImpl() {
  JNIEnv* env = AttachCurrentThread();
  Java_InputStream_close(env, jobject_.obj());
}

bool InputStreamImpl::BytesAvailable(int* bytes_available) const {
  JNIEnv* env = AttachCurrentThread();
  int bytes = Java_InputStream_available(env, jobject_.obj());
  if (ClearException(env))
    return false;
  *bytes_available = bytes;
  return true;
}

bool InputStreamImpl::Skip(int64_t n, int64_t* bytes_skipped) {
  JNIEnv* env = AttachCurrentThread();
  int bytes = Java_InputStream_skip(env, jobject_.obj(), n);
  if (ClearException(env))
    return false;
  if (bytes > n)
    return false;
  *bytes_skipped = bytes;
  return true;
}

bool InputStreamImpl::Read(net::IOBuffer* dest, int length, int* bytes_read) {
  JNIEnv* env = AttachCurrentThread();
  if (!buffer_.obj()) {
    // Allocate transfer buffer.
    base::android::ScopedJavaLocalRef<jbyteArray> temp(
        env, env->NewByteArray(kBufferSize));
    buffer_.Reset(temp);
    if (ClearException(env))
      return false;
  }

  int remaining_length = length;
  char* dest_write_ptr = dest->data();
  jbyteArray buffer = buffer_.obj();
  *bytes_read = 0;

  while (remaining_length > 0) {
    const int max_transfer_length = std::min(remaining_length, kBufferSize);
    const int transfer_length = Java_InputStream_readI_AB_I_I(
        env, jobject_.obj(), buffer, 0, max_transfer_length);
    if (ClearException(env))
      return false;

    if (transfer_length < 0)  // EOF
      break;

    // Note: it is possible, yet unlikely, that the Java InputStream returns
    // a transfer_length == 0 from time to time. In such cases we just continue
    // the read until we get either valid data or reach EOF.
    if (transfer_length == 0)
      continue;

    DCHECK_GE(max_transfer_length, transfer_length);
    DCHECK_GE(env->GetArrayLength(buffer), transfer_length);

    // This check is to prevent a malicious InputStream implementation from
    // overrunning the |dest| buffer.
    if (transfer_length > max_transfer_length)
      return false;

    // Copy the data over to the provided C++ IOBuffer.
    DCHECK_GE(remaining_length, transfer_length);
    env->GetByteArrayRegion(buffer, 0, transfer_length,
        reinterpret_cast<jbyte*>(dest_write_ptr));
    if (ClearException(env))
      return false;

    remaining_length -= transfer_length;
    dest_write_ptr += transfer_length;
  }
  // bytes_read can be strictly less than the req. length if EOF is encountered.
  DCHECK(remaining_length >= 0 && remaining_length <= length);
  *bytes_read = length - remaining_length;
  return true;
}

} // namespace android_webview
