]> gerrit.simantics Code Review - simantics/3d.git/blob - org.jcae.opencascade/src/jnistream.cxx
Merge "Fix NPE in branch point synchronization"
[simantics/3d.git] / org.jcae.opencascade / src / jnistream.cxx
1 #include "jnistream.hxx"
2
3 //#define DEBUG
4 using namespace std;
5
6 static void jthrow(JNIEnv *env, const char *name, const char *msg)
7 {
8         jclass cls = env->FindClass(name);
9         /* if cls is NULL, an exception has already been thrown => remove it because it's from the JVM*/
10         if (cls == NULL)
11         {
12                 env->ExceptionClear();
13                 jthrow(env,name,msg);
14         }
15         else
16         {
17                 if(env->ThrowNew(cls, msg)<0)
18                 {
19                         //the throw exception failled
20                         std::cout<<"#JNI throw exception failled !"<<std::endl;
21                         std::cout<<name<<"\t : "<<msg<<std::endl;
22                 }
23                 /* free the local ref */
24                 env->DeleteLocalRef(cls);
25         }
26 }
27
28 jnistreambuf::~jnistreambuf()
29 {
30         delete[] nativeBuffer;
31 }
32
33 jnistreambuf::jnistreambuf(JNIEnv * env, jobject jstream, int bufferSize):
34         env(env), jstream(jstream)
35 {
36 #ifdef DEBUG
37         cerr << "jnistreambuf::jnistreambuf [start]" << endl;
38 #endif
39         nativeBuffer = new char[bufferSize];
40         fullNioBuffer=env->NewDirectByteBuffer(nativeBuffer, bufferSize);
41
42         jclass inputStreamClass = env->FindClass("java/nio/channels/ReadableByteChannel");
43         jclass outputStreamClass = env->FindClass("java/nio/channels/WritableByteChannel");
44  
45         readMID = env->GetMethodID(inputStreamClass, "read","(Ljava/nio/ByteBuffer;)I");  
46         writeMID = env->GetMethodID(outputStreamClass, "write","(Ljava/nio/ByteBuffer;)I");  
47         
48         bool in=env->IsInstanceOf(jstream, inputStreamClass)!=0;
49         bool out=env->IsInstanceOf(jstream, outputStreamClass)!=0;
50
51         if(in)
52         {
53 #ifdef DEBUG
54         cerr << "jnistreambuf::jnistreambuf: init reading buffer" << endl;
55 #endif
56                 setg(nativeBuffer,     // beginning of putback area
57                          nativeBuffer,     // read position
58                          nativeBuffer);    // end position      
59         }
60
61         if(out)
62         {
63 #ifdef DEBUG
64         cerr << "jnistreambuf::jnistreambuf: init writting buffer [start]" << endl;
65 #endif
66                 setp( nativeBuffer, nativeBuffer + bufferSize );
67
68 #ifdef DEBUG
69         cerr << "jnistreambuf::jnistreambuf: init writting buffer [done]" << endl;
70 #endif
71         }
72
73         if(!out && !in)
74         {
75                 jthrow(env, "java/lang/ClassCastException", "InputStream or OutputStream expected");
76         }
77
78 #ifdef DEBUG
79         cerr << "jnistreambuf::jnistreambuf [done]" << endl;
80 #endif
81 }
82
83 int jnistreambuf::underflow()
84 {
85 #ifdef DEBUG
86         cerr << "jnistreambuf::underflow" << endl;
87 #endif
88         // used for input buffer only
89     if ( gptr() && ( gptr() < egptr()))
90         return * reinterpret_cast<unsigned char *>( gptr());
91
92         //read the java bytes
93     int num = env->CallIntMethod(jstream, readMID, fullNioBuffer);
94
95     if (num <= 0) // ERROR or EOF
96         return EOF;
97
98     // reset buffer pointers
99     setg( eback(),   // beginning of putback area
100           eback(),                 // read position
101           eback() + num);          // end of buffer
102
103     // return next character
104     return * reinterpret_cast<unsigned char *>( gptr());    
105 }
106
107 int jnistreambuf::overflow( int c)
108 {
109 #ifdef DEBUG
110         cerr << "jnistreambuf::overflow" << endl;
111 #endif
112         // used for output buffer only
113     if (c != EOF) {
114         *pptr() = c;
115         pbump(1);
116     }
117
118     if ( flush_buffer() == EOF)
119         return EOF;
120     return c;
121 }
122
123 int jnistreambuf::sync()
124 {
125 #ifdef DEBUG
126         cerr << "jnistreambuf::sync()" << endl;
127 #endif
128     // Changed to use flush_buffer() instead of overflow( EOF)
129     // which caused improper behavior with std::endl and flush(),
130     // bug reported by Vincent Ricard.
131     if ( pptr() && pptr() > pbase()) {
132         if ( flush_buffer() == EOF)
133             return -1;
134     }
135     return 0;
136 }
137
138 int jnistreambuf::flush_buffer()
139 {
140 #ifdef DEBUG
141         cerr << "jnistreambuf::flush_buffer" << endl;
142         //for(char * p=pbase(); p!=pptr(); p++) cerr << *p;
143 #endif
144     // Separate the writing of the buffer from overflow() and
145     // sync() operation.
146     int w = pptr() - pbase();
147
148         //write the c chars
149         jobject nioBuffer;
150         
151         if(pptr()==epptr())
152                 nioBuffer=fullNioBuffer;
153         else
154                 nioBuffer=env->NewDirectByteBuffer(pbase(), w);
155
156     env->CallIntMethod(jstream, writeMID, nioBuffer);
157
158     pbump( -w);
159     return w;
160 }
161