1 /********************* */
2 /*! \file java_stream_adapters.h
4 ** Top contributors (to current version):
5 ** Morgan Deters, Tim King
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2016 by the authors listed in the file AUTHORS
8 ** in the top-level source directory) and their institutional affiliations.
9 ** All rights reserved. See the file COPYING in the top-level source
10 ** directory for licensing information.\endverbatim
12 ** \brief An OutputStream adapter for the Java bindings
14 ** An OutputStream adapter for the Java bindings. This works with a lot
15 ** of help from SWIG, and custom typemaps in the ".i" SWIG interface files
16 ** for CVC4. The basic idea is that, when a CVC4 function with a
17 ** std::ostream& parameter is called, a Java-side binding is generated
18 ** taking a java.io.OutputStream. Now, the problem is that std::ostream
19 ** has no Java equivalent, and java.io.OutputStream has no C++ equivalent,
20 ** so we use this class (which exists on both sides) as the go-between.
21 ** The wrapper connecting the Java function (taking an OutputStream) and
22 ** the C++ function (taking an ostream) creates a JavaOutputStreamAdapter,
23 ** and call the C++ function with the stringstream inside. After the call,
24 ** the generated stream material is collected and output to the Java-side
28 // private to the bindings layer
30 # error This should only be included from the Java bindings layer.
40 #ifndef __CVC4__BINDINGS__JAVA_STREAM_ADAPTERS_H
41 #define __CVC4__BINDINGS__JAVA_STREAM_ADAPTERS_H
45 class JavaOutputStreamAdapter
: public std::ostringstream
{
47 std::string
toString() { return str(); }
48 };/* class JavaOutputStreamAdapter */
50 class JavaInputStreamAdapter
: public std::stringstream
{
51 static std::set
<JavaInputStreamAdapter
*> s_adapters
;
54 JavaInputStreamAdapter
& operator=(const JavaInputStreamAdapter
&);
55 JavaInputStreamAdapter(const JavaInputStreamAdapter
&);
58 JavaInputStreamAdapter(jobject inputStream
) : inputStream(inputStream
) {
59 s_adapters
.insert(this);
62 ~JavaInputStreamAdapter() {
63 s_adapters
.erase(this);
66 static void pullAdapters(JNIEnv
* jenv
) {
67 for(std::set
<JavaInputStreamAdapter
*>::iterator i
= s_adapters
.begin();
68 i
!= s_adapters
.end();
74 jobject
getInputStream() const {
78 void pull(JNIEnv
* jenv
) {
82 jclass clazz
= jenv
->FindClass("java/io/InputStream");
83 assert(clazz
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
84 jmethodID method
= jenv
->GetMethodID(clazz
, "available", "()I");
85 assert(method
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
86 jint available
= jenv
->CallIntMethod(inputStream
, method
);
87 assert(jenv
->ExceptionOccurred() == NULL
);
88 jbyteArray bytes
= jenv
->NewByteArray(available
);
89 assert(bytes
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
90 method
= jenv
->GetMethodID(clazz
, "read", "([B)I");
91 assert(method
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
92 jint nread
= jenv
->CallIntMethod(inputStream
, method
, bytes
);
93 assert(jenv
->ExceptionOccurred() == NULL
);
94 jbyte
* bptr
= jenv
->GetByteArrayElements(bytes
, NULL
);
95 assert(jenv
->ExceptionOccurred() == NULL
);
96 std::copy(bptr
, bptr
+ nread
, std::ostream_iterator
<char>(*this));
98 jenv
->ReleaseByteArrayElements(bytes
, bptr
, 0);
99 assert(jenv
->ExceptionOccurred() == NULL
);
104 };/* class JavaInputStreamAdapter */
106 }/* CVC4 namespace */
108 #endif /* __CVC4__BINDINGS__JAVA_STREAM_ADAPTERS_H */