diff options
Diffstat (limited to 'subversion/bindings/javahl/native/NativeStream.cpp')
-rw-r--r-- | subversion/bindings/javahl/native/NativeStream.cpp | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/subversion/bindings/javahl/native/NativeStream.cpp b/subversion/bindings/javahl/native/NativeStream.cpp new file mode 100644 index 0000000..193c36f --- /dev/null +++ b/subversion/bindings/javahl/native/NativeStream.cpp @@ -0,0 +1,381 @@ +/** + * @copyright + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * @endcopyright + */ + +#include "NativeStream.hpp" + +#include "jniwrapper/jni_stack.hpp" +#include "jniwrapper/jni_exception.hpp" + +#include "svn_private_config.h" + +namespace JavaHL { + +// Class JavaHL::NativeInputStream + +const char* const NativeInputStream::m_class_name = + JAVAHL_CLASS("/types/NativeInputStream"); + +NativeInputStream::~NativeInputStream() {} + +void NativeInputStream::set_stream(svn_stream_t* stream) +{ + if (m_stream) + throw std::logic_error(_("Native input stream is already bound")); + m_stream = stream; +} + +NativeInputStream* +NativeInputStream::get_self_unsafe(::Java::Env env, jobject jthis) +{ + jfieldID fid_cppaddr = NULL; + const jlong cppaddr = + findCppAddrForJObject(jthis, &fid_cppaddr, m_class_name); + return reinterpret_cast<NativeInputStream*>(cppaddr); +} + +NativeInputStream* +NativeInputStream::get_self(::Java::Env env, jobject jthis) +{ + NativeInputStream* self = get_self_unsafe(env, jthis); + if (!self) + ::Java::NullPointerException(env).raise(_("this [C++]")); + return self; +} + +void NativeInputStream::close(::Java::Env env, jobject jthis) +{ + SVN_JAVAHL_CHECK(env, svn_stream_close(m_stream)); + dispose(jthis); +} + +bool NativeInputStream::mark_supported(::Java::Env env) const +{ + return svn_stream_supports_mark(m_stream); +} + +void NativeInputStream::mark(::Java::Env env) +{ + if (!svn_stream_supports_mark(m_stream)) + return; + SVN_JAVAHL_CHECK(env, svn_stream_mark(m_stream, &m_mark, pool.getPool())); +} + +void NativeInputStream::reset(::Java::Env env) +{ + if (!svn_stream_supports_mark(m_stream)) + return; + if (m_mark) + SVN_JAVAHL_CHECK(env, svn_stream_seek(m_stream, m_mark)); + else + ::Java::IOException(env).raise(_("Invalid seek on native stream")); + } + +jint NativeInputStream::read(::Java::Env env) +{ + apr_size_t len = 1; + char byte; + SVN_JAVAHL_CHECK(env, svn_stream_read_full(m_stream, &byte, &len)); + if (len == 0) + return -1; // EOF + if (len == 1) + return jint(byte & 0xff); + ::Java::IOException(env).raise(_("Read from native stream failed")); + return -1; +} + +jint NativeInputStream::read(::Java::Env env, + ::Java::ByteArray::MutableContents& dst, + jint offset, jint length) +{ + if (offset < 0 || length < 0 || offset + length > dst.length()) + ::Java::IndexOutOfBoundsException(env).raise(); + if (!dst.data()) + ::Java::NullPointerException(env).raise(); + + apr_size_t len = length; + if (svn_stream_supports_partial_read(m_stream)) + SVN_JAVAHL_CHECK(env, svn_stream_read2(m_stream, + dst.data() + offset, &len)); + else + SVN_JAVAHL_CHECK(env, svn_stream_read_full(m_stream, + dst.data() + offset, &len)); + if (len == 0) + return -1; // EOF + if (len <= length) + return jint(len); + ::Java::IOException(env).raise(_("Read from native stream failed")); + return -1; +} + +jlong NativeInputStream::skip(::Java::Env env, jlong count) +{ + const apr_size_t len = count; + SVN_JAVAHL_CHECK(env, svn_stream_skip(m_stream, len)); + return count; +} + +void NativeInputStream::dispose(jobject jthis) +{ + jfieldID fid_cppaddr = NULL; + SVNBase::dispose(jthis, &fid_cppaddr, m_class_name); +} + + +// Class JavaHL::NativeOutputStream + +const char* const NativeOutputStream::m_class_name = + JAVAHL_CLASS("/types/NativeOutputStream"); + +NativeOutputStream::~NativeOutputStream() {} + +void NativeOutputStream::set_stream(svn_stream_t* stream) +{ + if (m_stream) + throw std::logic_error(_("Native output stream is already bound")); + m_stream = stream; +} + +NativeOutputStream* +NativeOutputStream::get_self_unsafe(::Java::Env env, jobject jthis) +{ + jfieldID fid_cppaddr = NULL; + const jlong cppaddr = + findCppAddrForJObject(jthis, &fid_cppaddr, m_class_name); + return reinterpret_cast<NativeOutputStream*>(cppaddr); +} + +NativeOutputStream* +NativeOutputStream::get_self(::Java::Env env, jobject jthis) +{ + NativeOutputStream* self = get_self_unsafe(env, jthis); + if (!self) + ::Java::NullPointerException(env).raise(_("this [C++]")); + return self; +} + +void NativeOutputStream::close(::Java::Env env, jobject jthis) +{ + SVN_JAVAHL_CHECK(env, svn_stream_close(m_stream)); + dispose(jthis); +} + +void NativeOutputStream::write(::Java::Env env, jint byte) +{ + const char data = char(byte & 0xff); + apr_size_t len = 1; + SVN_JAVAHL_CHECK(env, svn_stream_write(m_stream, &data, &len)); + if (len != 1) + ::Java::IOException(env).raise(_("Write to native stream failed")); +} + +void NativeOutputStream::write(::Java::Env env, + const ::Java::ByteArray::Contents& src, + jint offset, jint length) +{ + if (offset < 0 || length < 0 || offset + length > src.length()) + ::Java::IndexOutOfBoundsException(env).raise(); + if (!src.data()) + ::Java::NullPointerException(env).raise(); + + apr_size_t len = length; + SVN_JAVAHL_CHECK(env, svn_stream_write(m_stream, src.data() + offset, &len)); + if (len != length) + ::Java::IOException(env).raise(_("Write to native stream failed")); +} + +void NativeOutputStream::dispose(jobject jthis) +{ + jfieldID fid_cppaddr = NULL; + SVNBase::dispose(jthis, &fid_cppaddr, m_class_name); +} + +} // namespace JavaHL + + +// Class JavaHL::NativeInputStream native method implementation +#include "../include/org_apache_subversion_javahl_types_NativeInputStream.h" + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_close( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, close) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + self->close(Java::Env(jenv), jthis); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT jboolean JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_markSupported( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, markSupported) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + self->mark_supported(Java::Env(jenv)); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); + return false; +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_mark( + JNIEnv* jenv, jobject jthis, jint) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, mark) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + self->mark(Java::Env(jenv)); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_reset( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, reset) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + self->reset(Java::Env(jenv)); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT jint JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_read__( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, read) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + return self->read(Java::Env(jenv)); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); + return 0; +} + +JNIEXPORT jint JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_read___3BII( + JNIEnv* jenv, jobject jthis, jbyteArray jdst, jint joffset, jint jlength) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, read) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + + const Java::Env env(jenv); + Java::ByteArray dst(env, jdst); + Java::ByteArray::MutableContents dst_contents(dst); + + return self->read(env, dst_contents, joffset, jlength); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); + return 0; +} + +JNIEXPORT jlong JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_skip( + JNIEnv* jenv, jobject jthis, jlong jcount) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, skip) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeInputStream, self); + return self->skip(Java::Env(jenv), jcount); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); + return 0; +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeInputStream_finalize( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeInputStream, finalize) + { + JavaHL::NativeInputStream* native = + JavaHL::NativeInputStream::get_self_unsafe(Java::Env(jenv), jthis); + if (native != NULL) + native->finalize(); + } + SVN_JAVAHL_JNI_CATCH; +} + + +// Class JavaHL::NativeOutputStream native method implementation +#include "../include/org_apache_subversion_javahl_types_NativeOutputStream.h" + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeOutputStream_close( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeOutputStream, close) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeOutputStream, self); + self->close(Java::Env(jenv), jthis); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeOutputStream_write__I( + JNIEnv* jenv, jobject jthis, jint byte) +{ + SVN_JAVAHL_JNI_TRY(NativeOutputStream, write) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeOutputStream, self); + self->write(Java::Env(jenv), byte); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeOutputStream_write___3BII( + JNIEnv* jenv, jobject jthis, jbyteArray jsrc, jint joffset, jint jlength) +{ + SVN_JAVAHL_JNI_TRY(NativeOutputStream, write) + { + SVN_JAVAHL_GET_BOUND_OBJECT(JavaHL::NativeOutputStream, self); + + const Java::Env env(jenv); + const Java::ByteArray src(env, jsrc); + + self->write(env, Java::ByteArray::Contents(src), joffset, jlength); + } + SVN_JAVAHL_JNI_CATCH_TO_EXCEPTION(Java::IOException); +} + +JNIEXPORT void JNICALL +Java_org_apache_subversion_javahl_types_NativeOutputStream_finalize( + JNIEnv* jenv, jobject jthis) +{ + SVN_JAVAHL_JNI_TRY(NativeOutputStream, finalize) + { + JavaHL::NativeOutputStream* native = + JavaHL::NativeOutputStream::get_self_unsafe(Java::Env(jenv), jthis); + if (native != NULL) + native->finalize(); + } + SVN_JAVAHL_JNI_CATCH; +} |