1 /********************* */
2 /*! \file java_stream_adapters.h
4 ** Original author: mdeters
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009-2012 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** 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
{
46 std::stringstream d_ss
;
49 JavaOutputStreamAdapter() { }
51 std::string
toString() { return d_ss
.str(); }
53 };/* class JavaOutputStreamAdapter */
55 class JavaInputStreamAdapter
: public std::stringstream
{
56 static std::set
<JavaInputStreamAdapter
*> s_adapters
;
59 JavaInputStreamAdapter
& operator=(const JavaInputStreamAdapter
&);
60 JavaInputStreamAdapter(const JavaInputStreamAdapter
&);
63 JavaInputStreamAdapter(jobject inputStream
) : inputStream(inputStream
) {
64 s_adapters
.insert(this);
67 ~JavaInputStreamAdapter() {
68 s_adapters
.erase(this);
71 static void pullAdapters(JNIEnv
* jenv
) {
72 for(std::set
<JavaInputStreamAdapter
*>::iterator i
= s_adapters
.begin();
73 i
!= s_adapters
.end();
79 jobject
getInputStream() const {
83 void pull(JNIEnv
* jenv
) {
87 jclass clazz
= jenv
->FindClass("java/io/InputStream");
88 assert(clazz
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
89 jmethodID method
= jenv
->GetMethodID(clazz
, "available", "()I");
90 assert(method
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
91 jint available
= jenv
->CallIntMethod(inputStream
, method
);
92 assert(jenv
->ExceptionOccurred() == NULL
);
93 jbyteArray bytes
= jenv
->NewByteArray(available
);
94 assert(bytes
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
95 method
= jenv
->GetMethodID(clazz
, "read", "([B)I");
96 assert(method
!= NULL
&& jenv
->ExceptionOccurred() == NULL
);
97 jint nread
= jenv
->CallIntMethod(inputStream
, method
, bytes
);
98 assert(jenv
->ExceptionOccurred() == NULL
);
99 jbyte
* bptr
= jenv
->GetByteArrayElements(bytes
, NULL
);
100 assert(jenv
->ExceptionOccurred() == NULL
);
101 std::copy(bptr
, bptr
+ nread
, std::ostream_iterator
<char>(*this));
103 jenv
->ReleaseByteArrayElements(bytes
, bptr
, 0);
104 assert(jenv
->ExceptionOccurred() == NULL
);
109 };/* class JavaInputStreamAdapter */
111 }/* CVC4 namespace */
113 #endif /* __CVC4__BINDINGS__JAVA_STREAM_ADAPTERS_H */