27 #include <string.h>
28 #include <stddef.h>
29
30 #include "jni.h"
31 #include "jni_util.h"
32 #include "jvm.h"
33 #include "io_util.h"
34 #include "io_util_md.h"
35
36 /* IO helper functions */
37
38 jint
39 readSingle(JNIEnv *env, jobject this, jfieldID fid) {
40 jint nread;
41 char ret;
42 FD fd = GET_FD(this, fid);
43 if (fd == -1) {
44 JNU_ThrowIOException(env, "Stream Closed");
45 return -1;
46 }
47 nread = (jint)IO_Read(fd, &ret, 1);
48 if (nread == 0) { /* EOF */
49 return -1;
50 } else if (nread == JVM_IO_ERR) { /* error */
51 JNU_ThrowIOExceptionWithLastError(env, "Read error");
52 } else if (nread == JVM_IO_INTR) {
53 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
54 }
55 return ret & 0xFF;
56 }
57
58 /* The maximum size of a stack-allocated buffer.
59 */
60 #define BUF_SIZE 8192
61
62 /*
63 * Returns true if the array slice defined by the given offset and length
64 * is out of bounds.
65 */
66 static int
67 outOfBounds(JNIEnv *env, jint off, jint len, jbyteArray array) {
91 return -1;
92 }
93
94 if (len == 0) {
95 return 0;
96 } else if (len > BUF_SIZE) {
97 buf = malloc(len);
98 if (buf == NULL) {
99 JNU_ThrowOutOfMemoryError(env, NULL);
100 return 0;
101 }
102 } else {
103 buf = stackBuf;
104 }
105
106 fd = GET_FD(this, fid);
107 if (fd == -1) {
108 JNU_ThrowIOException(env, "Stream Closed");
109 nread = -1;
110 } else {
111 nread = (jint)IO_Read(fd, buf, len);
112 if (nread > 0) {
113 (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
114 } else if (nread == JVM_IO_ERR) {
115 JNU_ThrowIOExceptionWithLastError(env, "Read error");
116 } else if (nread == JVM_IO_INTR) {
117 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
118 } else { /* EOF */
119 nread = -1;
120 }
121 }
122
123 if (buf != stackBuf) {
124 free(buf);
125 }
126 return nread;
127 }
128
129 void
130 writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) {
131 // Discard the 24 high-order bits of byte. See OutputStream#write(int)
132 char c = (char) byte;
133 jint n;
134 FD fd = GET_FD(this, fid);
135 if (fd == -1) {
136 JNU_ThrowIOException(env, "Stream Closed");
137 return;
138 }
139 if (append == JNI_TRUE) {
140 n = (jint)IO_Append(fd, &c, 1);
141 } else {
142 n = (jint)IO_Write(fd, &c, 1);
143 }
144 if (n == JVM_IO_ERR) {
145 JNU_ThrowIOExceptionWithLastError(env, "Write error");
146 } else if (n == JVM_IO_INTR) {
147 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
148 }
149 }
150
151 void
152 writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
153 jint off, jint len, jboolean append, jfieldID fid)
154 {
155 jint n;
156 char stackBuf[BUF_SIZE];
157 char *buf = NULL;
158 FD fd;
159
160 if (IS_NULL(bytes)) {
161 JNU_ThrowNullPointerException(env, NULL);
162 return;
173 buf = malloc(len);
174 if (buf == NULL) {
175 JNU_ThrowOutOfMemoryError(env, NULL);
176 return;
177 }
178 } else {
179 buf = stackBuf;
180 }
181
182 (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
183
184 if (!(*env)->ExceptionOccurred(env)) {
185 off = 0;
186 while (len > 0) {
187 fd = GET_FD(this, fid);
188 if (fd == -1) {
189 JNU_ThrowIOException(env, "Stream Closed");
190 break;
191 }
192 if (append == JNI_TRUE) {
193 n = (jint)IO_Append(fd, buf+off, len);
194 } else {
195 n = (jint)IO_Write(fd, buf+off, len);
196 }
197 if (n == JVM_IO_ERR) {
198 JNU_ThrowIOExceptionWithLastError(env, "Write error");
199 break;
200 } else if (n == JVM_IO_INTR) {
201 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
202 break;
203 }
204 off += n;
205 len -= n;
206 }
207 }
208 if (buf != stackBuf) {
209 free(buf);
210 }
211 }
212
213 void
214 throwFileNotFoundException(JNIEnv *env, jstring path)
215 {
|
27 #include <string.h>
28 #include <stddef.h>
29
30 #include "jni.h"
31 #include "jni_util.h"
32 #include "jvm.h"
33 #include "io_util.h"
34 #include "io_util_md.h"
35
36 /* IO helper functions */
37
38 jint
39 readSingle(JNIEnv *env, jobject this, jfieldID fid) {
40 jint nread;
41 char ret;
42 FD fd = GET_FD(this, fid);
43 if (fd == -1) {
44 JNU_ThrowIOException(env, "Stream Closed");
45 return -1;
46 }
47 nread = IO_Read(fd, &ret, 1);
48 if (nread == 0) { /* EOF */
49 return -1;
50 } else if (nread == JVM_IO_ERR) { /* error */
51 JNU_ThrowIOExceptionWithLastError(env, "Read error");
52 } else if (nread == JVM_IO_INTR) {
53 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
54 }
55 return ret & 0xFF;
56 }
57
58 /* The maximum size of a stack-allocated buffer.
59 */
60 #define BUF_SIZE 8192
61
62 /*
63 * Returns true if the array slice defined by the given offset and length
64 * is out of bounds.
65 */
66 static int
67 outOfBounds(JNIEnv *env, jint off, jint len, jbyteArray array) {
91 return -1;
92 }
93
94 if (len == 0) {
95 return 0;
96 } else if (len > BUF_SIZE) {
97 buf = malloc(len);
98 if (buf == NULL) {
99 JNU_ThrowOutOfMemoryError(env, NULL);
100 return 0;
101 }
102 } else {
103 buf = stackBuf;
104 }
105
106 fd = GET_FD(this, fid);
107 if (fd == -1) {
108 JNU_ThrowIOException(env, "Stream Closed");
109 nread = -1;
110 } else {
111 nread = IO_Read(fd, buf, len);
112 if (nread > 0) {
113 (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
114 } else if (nread == JVM_IO_ERR) {
115 JNU_ThrowIOExceptionWithLastError(env, "Read error");
116 } else if (nread == JVM_IO_INTR) {
117 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
118 } else { /* EOF */
119 nread = -1;
120 }
121 }
122
123 if (buf != stackBuf) {
124 free(buf);
125 }
126 return nread;
127 }
128
129 void
130 writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) {
131 // Discard the 24 high-order bits of byte. See OutputStream#write(int)
132 char c = (char) byte;
133 jint n;
134 FD fd = GET_FD(this, fid);
135 if (fd == -1) {
136 JNU_ThrowIOException(env, "Stream Closed");
137 return;
138 }
139 if (append == JNI_TRUE) {
140 n = IO_Append(fd, &c, 1);
141 } else {
142 n = IO_Write(fd, &c, 1);
143 }
144 if (n == JVM_IO_ERR) {
145 JNU_ThrowIOExceptionWithLastError(env, "Write error");
146 } else if (n == JVM_IO_INTR) {
147 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
148 }
149 }
150
151 void
152 writeBytes(JNIEnv *env, jobject this, jbyteArray bytes,
153 jint off, jint len, jboolean append, jfieldID fid)
154 {
155 jint n;
156 char stackBuf[BUF_SIZE];
157 char *buf = NULL;
158 FD fd;
159
160 if (IS_NULL(bytes)) {
161 JNU_ThrowNullPointerException(env, NULL);
162 return;
173 buf = malloc(len);
174 if (buf == NULL) {
175 JNU_ThrowOutOfMemoryError(env, NULL);
176 return;
177 }
178 } else {
179 buf = stackBuf;
180 }
181
182 (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
183
184 if (!(*env)->ExceptionOccurred(env)) {
185 off = 0;
186 while (len > 0) {
187 fd = GET_FD(this, fid);
188 if (fd == -1) {
189 JNU_ThrowIOException(env, "Stream Closed");
190 break;
191 }
192 if (append == JNI_TRUE) {
193 n = IO_Append(fd, buf+off, len);
194 } else {
195 n = IO_Write(fd, buf+off, len);
196 }
197 if (n == JVM_IO_ERR) {
198 JNU_ThrowIOExceptionWithLastError(env, "Write error");
199 break;
200 } else if (n == JVM_IO_INTR) {
201 JNU_ThrowByName(env, "java/io/InterruptedIOException", NULL);
202 break;
203 }
204 off += n;
205 len -= n;
206 }
207 }
208 if (buf != stackBuf) {
209 free(buf);
210 }
211 }
212
213 void
214 throwFileNotFoundException(JNIEnv *env, jstring path)
215 {
|