/*
* Copyright ( c ) 1994 , 2020 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation . Oracle designates this
* particular file as subject to the " Classpath " exception as provided
* by Oracle in the LICENSE file that accompanied this code .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "io_util.h"
#include "io_util_md.h"
/* IO helper functions */
jint
readSingle(JNIEnv *env, jobject this , jfieldID fid) {
jint nread;
char ret;
FD fd = getFD(env, this , fid);
if (fd == -1 ) {
JNU_ThrowIOException(env, "Stream Closed" );
return -1 ;
}
nread = IO_Read(fd, &ret, 1 );
if (nread == 0 ) { /* EOF */
return -1 ;
} else if (nread == -1 ) { /* error */
JNU_ThrowIOExceptionWithLastError(env, "Read error" );
}
return ret & 0 xFF;
}
/* The maximum size of a stack-allocated buffer.
*/
#define BUF_SIZE 8192
/*
* Returns true if the array slice defined by the given offset and length
* is out of bounds .
*/
static int
outOfBounds(JNIEnv *env, jint off, jint len, jbyteArray array) {
return ((off < 0 ) ||
(len < 0 ) ||
// We are very careful to avoid signed integer overflow,
// the result of which is undefined in C.
((*env)->GetArrayLength(env, array) - off < len));
}
jint
readBytes(JNIEnv *env, jobject this , jbyteArray bytes,
jint off, jint len, jfieldID fid)
{
jint nread;
char stackBuf[BUF_SIZE];
char *buf = NULL;
FD fd;
if (IS_NULL(bytes)) {
JNU_ThrowNullPointerException(env, NULL);
return -1 ;
}
if (outOfBounds(env, off, len, bytes)) {
JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException" , NULL);
return -1 ;
}
if (len == 0 ) {
return 0 ;
} else if (len > BUF_SIZE) {
buf = malloc(len);
if (buf == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
return 0 ;
}
} else {
buf = stackBuf;
}
fd = getFD(env, this , fid);
if (fd == -1 ) {
JNU_ThrowIOException(env, "Stream Closed" );
nread = -1 ;
} else {
nread = IO_Read(fd, buf, len);
if (nread > 0 ) {
(*env)->SetByteArrayRegion(env, bytes, off, nread, (jbyte *)buf);
} else if (nread == -1 ) {
JNU_ThrowIOExceptionWithLastError(env, "Read error" );
} else { /* EOF */
nread = -1 ;
}
}
if (buf != stackBuf) {
free(buf);
}
return nread;
}
void
writeSingle(JNIEnv *env, jobject this , jint byte, jboolean append, jfieldID fid) {
// Discard the 24 high-order bits of byte. See OutputStream#write(int)
char c = (char ) byte;
jint n;
FD fd = getFD(env, this , fid);
if (fd == -1 ) {
JNU_ThrowIOException(env, "Stream Closed" );
return ;
}
if (append == JNI_TRUE) {
n = IO_Append(fd, &c, 1 );
} else {
n = IO_Write(fd, &c, 1 );
}
if (n == -1 ) {
JNU_ThrowIOExceptionWithLastError(env, "Write error" );
}
}
void
writeBytes(JNIEnv *env, jobject this , jbyteArray bytes,
jint off, jint len, jboolean append, jfieldID fid)
{
jint n;
char stackBuf[BUF_SIZE];
char *buf = NULL;
FD fd;
if (IS_NULL(bytes)) {
JNU_ThrowNullPointerException(env, NULL);
return ;
}
if (outOfBounds(env, off, len, bytes)) {
JNU_ThrowByName(env, "java/lang/IndexOutOfBoundsException" , NULL);
return ;
}
if (len == 0 ) {
return ;
} else if (len > BUF_SIZE) {
buf = malloc(len);
if (buf == NULL) {
JNU_ThrowOutOfMemoryError(env, NULL);
return ;
}
} else {
buf = stackBuf;
}
(*env)->GetByteArrayRegion(env, bytes, off, len, (jbyte *)buf);
if (!(*env)->ExceptionOccurred(env)) {
off = 0 ;
while (len > 0 ) {
fd = getFD(env, this , fid);
if (fd == -1 ) {
JNU_ThrowIOException(env, "Stream Closed" );
break ;
}
if (append == JNI_TRUE) {
n = IO_Append(fd, buf+off, len);
} else {
n = IO_Write(fd, buf+off, len);
}
if (n == -1 ) {
JNU_ThrowIOExceptionWithLastError(env, "Write error" );
break ;
}
off += n;
len -= n;
}
}
if (buf != stackBuf) {
free(buf);
}
}
void
throwFileNotFoundException(JNIEnv *env, jstring path)
{
char buf[256 ];
size_t n;
jobject x;
jstring why = NULL;
n = getLastErrorString(buf, sizeof (buf));
if (n > 0 ) {
why = JNU_NewStringPlatform(env, buf);
CHECK_NULL(why);
}
x = JNU_NewObjectByName(env,
"java/io/FileNotFoundException" ,
"(Ljava/lang/String;Ljava/lang/String;)V" ,
path, why);
if (x != NULL) {
(*env)->Throw (env, x);
}
}
Messung V0.5 in Prozent C=96 H=98 G=96
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-03)
¤
*© Formatika GbR, Deutschland