105 if (fd == -1) { 106 JNU_ThrowIOException(env, "Stream Closed"); 107 nread = -1; 108 } else { 109 nread = IO_Read(fd, buf, len); 110 if (nread > 0) { 111 (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf); 112 } else if (nread == -1) { 113 JNU_ThrowIOExceptionWithLastError(env, "Read error"); 114 } else { /* EOF */ 115 nread = -1; 116 } 117 } 118 119 if (buf != stackBuf) { 120 free(buf); 121 } 122 return nread; 123 } 124 125 void 126 writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) { 127 // Discard the 24 high-order bits of byte. See OutputStream#write(int) 128 char c = (char) byte; 129 jint n; 130 FD fd = GET_FD(this, fid); 131 if (fd == -1) { 132 JNU_ThrowIOException(env, "Stream Closed"); 133 return; 134 } 135 if (append == JNI_TRUE) { 136 n = IO_Append(fd, &c, 1); 137 } else { 138 n = IO_Write(fd, &c, 1); 139 } 140 if (n == -1) { 141 JNU_ThrowIOExceptionWithLastError(env, "Write error"); 142 } 143 } 144 182 if (fd == -1) { 183 JNU_ThrowIOException(env, "Stream Closed"); 184 break; 185 } 186 if (append == JNI_TRUE) { 187 n = IO_Append(fd, buf+off, len); 188 } else { 189 n = IO_Write(fd, buf+off, len); 190 } 191 if (n == -1) { 192 JNU_ThrowIOExceptionWithLastError(env, "Write error"); 193 break; 194 } 195 off += n; 196 len -= n; 197 } 198 } 199 if (buf != stackBuf) { 200 free(buf); 201 } 202 } 203 204 void 205 throwFileNotFoundException(JNIEnv *env, jstring path) 206 { 207 char buf[256]; 208 size_t n; 209 jobject x; 210 jstring why = NULL; 211 212 n = getLastErrorString(buf, sizeof(buf)); 213 if (n > 0) { 214 #ifdef WIN32 215 why = (*env)->NewStringUTF(env, buf); 216 #else 217 why = JNU_NewStringPlatform(env, buf); 218 #endif 219 CHECK_NULL(why); 220 } 221 x = JNU_NewObjectByName(env, | 105 if (fd == -1) { 106 JNU_ThrowIOException(env, "Stream Closed"); 107 nread = -1; 108 } else { 109 nread = IO_Read(fd, buf, len); 110 if (nread > 0) { 111 (*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf); 112 } else if (nread == -1) { 113 JNU_ThrowIOExceptionWithLastError(env, "Read error"); 114 } else { /* EOF */ 115 nread = -1; 116 } 117 } 118 119 if (buf != stackBuf) { 120 free(buf); 121 } 122 return nread; 123 } 124 125 jint 126 readBytesD(JNIEnv *env, jobject this, jbyteArray bytes, 127 jint off, jint len, jfieldID fid, jfieldID pgsz_id) 128 { 129 #ifdef _WIN32 130 JNU_ThrowIOException(env, "DirectIO is not supported on Windows platform!"); 131 #else 132 jint nread; 133 void *buf = NULL; 134 int delta = 0; 135 int gap = 0; 136 int newLen = 0; 137 long currentLocation; 138 long newStartLocation; 139 FD fd; 140 int pageSize; 141 if (IS_NULL(bytes)) { 142 JNU_ThrowNullPointerException(env, NULL); 143 return -1; 144 } 145 146 if (outOfBounds(env, off, len, bytes)) { 147 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL); 148 return -1; 149 } 150 151 if (len == 0) { 152 return 0; 153 } 154 155 fd = GET_FD(this, fid); 156 pageSize = GET_PG_SIZE(this, pgsz_id); 157 158 if (fd == -1) { 159 JNU_ThrowIOException(env, "Stream Closed"); 160 return -1; 161 } else if (pageSize == -1) { 162 JNU_ThrowIOException(env, "Error getting kernel pageSize for DirectIO alligment"); 163 return -1; 164 } else { 165 currentLocation = IO_Lseek(fd, 0, SEEK_CUR); 166 167 if ((currentLocation % pageSize) != 0) { 168 newStartLocation = currentLocation / pageSize * pageSize; 169 gap = currentLocation - newStartLocation; 170 } else { 171 newStartLocation = currentLocation; 172 gap = 0; 173 } 174 IO_Lseek(fd, newStartLocation, SEEK_SET); 175 if ((len % pageSize) != 0) { 176 newLen = (len / pageSize + 1) * pageSize; 177 } else { 178 newLen = len; 179 } 180 if ((newLen - gap) < len) { 181 newLen = newLen + pageSize; 182 } 183 184 delta = newLen - len; 185 if (newLen == 0) { 186 return 0; 187 } else { 188 posix_memalign(&buf, pageSize, newLen); 189 if (buf == NULL) { 190 JNU_ThrowOutOfMemoryError(env, NULL); 191 return 0; 192 } 193 } 194 nread = IO_Read(fd, buf, newLen); 195 if (nread > 0) { 196 if (nread >= len) { 197 (*env)->SetByteArrayRegion(env, bytes, off, len, ((jbyte *)(buf) + gap)); //read in the middle of a file 198 } else { 199 (*env)->SetByteArrayRegion(env, bytes, off, (nread-gap), ((jbyte *)(buf) + gap)); //reached the end of the file 200 } 201 } else if (nread == -1) { 202 JNU_ThrowIOExceptionWithLastError(env, "Read error"); 203 } else { /*EOF*/ 204 nread = -1; 205 } 206 IO_Lseek(fd, (currentLocation + len), SEEK_SET); 207 208 free(buf); 209 if (nread != -1) { 210 if (nread >= len) { 211 return len; 212 } else { 213 return (nread - gap); 214 } 215 } else { 216 return -1; 217 } 218 } 219 #endif 220 } 221 222 void 223 writeSingle(JNIEnv *env, jobject this, jint byte, jboolean append, jfieldID fid) { 224 // Discard the 24 high-order bits of byte. See OutputStream#write(int) 225 char c = (char) byte; 226 jint n; 227 FD fd = GET_FD(this, fid); 228 if (fd == -1) { 229 JNU_ThrowIOException(env, "Stream Closed"); 230 return; 231 } 232 if (append == JNI_TRUE) { 233 n = IO_Append(fd, &c, 1); 234 } else { 235 n = IO_Write(fd, &c, 1); 236 } 237 if (n == -1) { 238 JNU_ThrowIOExceptionWithLastError(env, "Write error"); 239 } 240 } 241 279 if (fd == -1) { 280 JNU_ThrowIOException(env, "Stream Closed"); 281 break; 282 } 283 if (append == JNI_TRUE) { 284 n = IO_Append(fd, buf+off, len); 285 } else { 286 n = IO_Write(fd, buf+off, len); 287 } 288 if (n == -1) { 289 JNU_ThrowIOExceptionWithLastError(env, "Write error"); 290 break; 291 } 292 off += n; 293 len -= n; 294 } 295 } 296 if (buf != stackBuf) { 297 free(buf); 298 } 299 } 300 301 void 302 writeBytesD(JNIEnv *env, jobject this, jbyteArray bytes, 303 jint off, jint len, jboolean append, jfieldID fid, jfieldID pgsz_id) 304 { 305 #ifdef _WIN32 306 JNU_ThrowIOException(env, "DirectIO is not supported on Windows platform!"); 307 #else 308 jint n; 309 void *buf = NULL; 310 FD fd; 311 int pageSize; 312 long currentLocation; 313 314 fd = GET_FD(this, fid); 315 if (fd == -1) { 316 JNU_ThrowIOException(env, "Stream Closed"); 317 } 318 319 pageSize = GET_PG_SIZE(this, pgsz_id); 320 if (pageSize == -1) { 321 JNU_ThrowIOException(env, "Error getting kernel pageSize for DirectIO alligment"); 322 } 323 324 currentLocation = IO_Lseek(fd, 0, SEEK_CUR); 325 326 if ((len % pageSize != 0) || (currentLocation % pageSize != 0)) { 327 JNU_ThrowIOException(env, 328 "In DirectIO mode, the IO size and currentLocation must be aligned with kernel page size!"); 329 } 330 331 if (IS_NULL(bytes)) { 332 JNU_ThrowNullPointerException(env, NULL); 333 return; 334 } 335 336 if (outOfBounds(env, off, len, bytes)) { 337 JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException", NULL); 338 return; 339 } 340 341 if (len == 0) { 342 return; 343 } else { 344 posix_memalign(&buf, pageSize, len); 345 if (buf == NULL) { 346 JNU_ThrowOutOfMemoryError(env, NULL); 347 return; 348 } 349 } 350 351 (*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf); 352 353 if (!(*env)->ExceptionOccurred(env)) { 354 off = 0; 355 while (len > 0) { 356 if (append == JNI_TRUE) { 357 n = IO_Append(fd, buf+off, len); 358 } else { 359 n = IO_Write(fd, buf+off, len); 360 } 361 if (n == -1) { 362 JNU_ThrowIOExceptionWithLastError(env, "Write error"); 363 break; 364 } 365 off += n; 366 len -= n; 367 } 368 } 369 free(buf); 370 #endif 371 } 372 373 void 374 throwFileNotFoundException(JNIEnv *env, jstring path) 375 { 376 char buf[256]; 377 size_t n; 378 jobject x; 379 jstring why = NULL; 380 381 n = getLastErrorString(buf, sizeof(buf)); 382 if (n > 0) { 383 #ifdef WIN32 384 why = (*env)->NewStringUTF(env, buf); 385 #else 386 why = JNU_NewStringPlatform(env, buf); 387 #endif 388 CHECK_NULL(why); 389 } 390 x = JNU_NewObjectByName(env, |