810daf8206
Reviewed-by: coleenp
254 lines
8.1 KiB
C++
254 lines
8.1 KiB
C++
/*
|
|
* Copyright (c) 2007, 2024, 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.
|
|
*
|
|
* 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 <jni.h>
|
|
#include <stdio.h>
|
|
/* Changed from strings.h to string.h for Windows. */
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "jnihelper.hpp"
|
|
|
|
extern "C" {
|
|
|
|
#define DIGESTLENGTH 16
|
|
|
|
typedef struct {
|
|
const char **str;
|
|
char **checkstr;
|
|
} CHAR_ARRAY;
|
|
|
|
typedef struct {
|
|
const jchar **str;
|
|
char **checkstr;
|
|
int *size;
|
|
} JCHAR_ARRAY;
|
|
|
|
JNIEXPORT jstring JNICALL
|
|
Java_nsk_stress_jni_JNIter001_jnistress (JNIEnv *env, jobject jobj, jstring jstr,
|
|
jint nstr, jint printperiod) {
|
|
|
|
int i, j;
|
|
size_t k;
|
|
static CHAR_ARRAY *element;
|
|
unsigned char digest[DIGESTLENGTH];
|
|
static int allocs = 0;
|
|
static size_t strsize = 0;
|
|
static unsigned int compared = 1;
|
|
|
|
const char *clsName = "nsk/stress/jni/JNIter001";
|
|
const char *name = "setpass";
|
|
const char *sig = "(Z)V";
|
|
const char *halt = "halt";
|
|
const char *haltSig = "()V";
|
|
jstring tmpstr;
|
|
jclass clazz;
|
|
jmethodID methodID;
|
|
|
|
CHECK(env->MonitorEnter(jobj));
|
|
|
|
if (!allocs) {
|
|
element = (CHAR_ARRAY *)c_malloc(env, sizeof(CHAR_ARRAY));
|
|
element->str = (const char **)c_malloc(env, nstr * sizeof(const char*));
|
|
element->checkstr = (char **)c_malloc(env, nstr * sizeof(char*));
|
|
for (j = 0; j < nstr; j++) {
|
|
element->checkstr[j] = (char *)c_malloc(env, DIGESTLENGTH * sizeof(char));
|
|
}
|
|
}
|
|
for (j = 0; j < DIGESTLENGTH; j++) {
|
|
digest[j] = 0;
|
|
}
|
|
element->str[allocs] = env->GetStringUTFChars(jstr, 0); CE
|
|
if (strlen(element->str[allocs]) != (size_t) env->GetStringUTFLength(jstr)) {
|
|
printf("Length is wrong in string No. %d\n", allocs);
|
|
} else {
|
|
strsize += strlen(element->str[allocs]) + 1;
|
|
}
|
|
for (k = 0; k < strlen(element->str[allocs]); k++) {
|
|
digest[k % DIGESTLENGTH] += element->str[allocs][k];
|
|
}
|
|
memcpy(element->checkstr[allocs], digest, DIGESTLENGTH);
|
|
allocs++;
|
|
if (allocs % printperiod == 0) {
|
|
printf("Check string for thread %s is ", element->str[allocs - 1]);
|
|
for (j = 0; j < DIGESTLENGTH; j++) {
|
|
printf("%02x", digest[j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
if (allocs == nstr) {
|
|
printf("JNI UTF8 strings memory = %zd\n", strsize);
|
|
tmpstr = env->NewStringUTF(element->str[allocs - 1]); CE
|
|
for (j = 0; j < nstr; j++) {
|
|
|
|
for (i = 0; i < DIGESTLENGTH; i++) {
|
|
digest[i] = 0;
|
|
}
|
|
for (k = 0; k < strlen(element->str[j]); k++) {
|
|
digest[k % DIGESTLENGTH] += element->str[j][k];
|
|
}
|
|
if (memcmp(digest, element->checkstr[j], DIGESTLENGTH) == 0) {
|
|
env->ReleaseStringUTFChars(jstr, element->str[j]); CE
|
|
element->str[j] = nullptr;
|
|
element->checkstr[j] = nullptr;
|
|
} else {
|
|
compared = 0;
|
|
printf("The element No. %d has been corrupted %s vs %s\n", j,
|
|
element->str[j], element->checkstr[j]);
|
|
printf("Digest string is %s [", element->str[j]);
|
|
for (i = 0; i < DIGESTLENGTH; i++) {
|
|
printf("ch[%d] = %02x", i, digest[i]);
|
|
}
|
|
printf("Digest end\n");
|
|
}
|
|
}
|
|
allocs = 0;
|
|
strsize = 0;
|
|
for (j = 0; j < nstr; j++) {
|
|
free(element->checkstr[j]);
|
|
}
|
|
free(element->checkstr);
|
|
free((void *)(element->str));
|
|
free(element);
|
|
clazz = env->FindClass(clsName); CE
|
|
if (!compared) {
|
|
methodID = env->GetStaticMethodID(clazz, name, sig); CE
|
|
env->CallStaticVoidMethod(clazz, methodID, JNI_FALSE); CE
|
|
}
|
|
//methodID = env->GetStaticMethodID(clazz, halt, haltSig); CE
|
|
//env->CallStaticVoidMethod(clazz, methodID); CE
|
|
return tmpstr;
|
|
}
|
|
CHECK(env->MonitorExit(jobj));
|
|
return (env->NewStringUTF(element->str[allocs - 1]));
|
|
}
|
|
|
|
JNIEXPORT jstring JNICALL
|
|
Java_nsk_stress_jni_JNIter001_jnistress1(JNIEnv *env, jobject jobj, jstring jstr,
|
|
jint nstr, jint printperiod) {
|
|
|
|
int i, j;
|
|
static JCHAR_ARRAY *javachars;
|
|
unsigned char digest[DIGESTLENGTH];
|
|
static int index = 0;
|
|
static long len = 0;
|
|
static unsigned int equal = 1;
|
|
char *elem;
|
|
int elem_len = -1;
|
|
|
|
const char *clsName = "nsk/stress/jni/JNIter001";
|
|
const char *name = "setpass";
|
|
const char *sig = "(Z)V";
|
|
const char *halt = "halt";
|
|
const char *haltSig = "()V";
|
|
jstring tmpstr;
|
|
jclass clazz;
|
|
jmethodID methodID;
|
|
|
|
CHECK(env->MonitorEnter(jobj));
|
|
if (!index) {
|
|
javachars = (JCHAR_ARRAY *)c_malloc(env, sizeof(JCHAR_ARRAY));
|
|
javachars->str = (const jchar **)c_malloc(env, nstr * sizeof(const jchar*));
|
|
javachars->checkstr = (char **)c_malloc(env, nstr * sizeof(char*));
|
|
javachars->size = (int *)c_malloc(env, nstr * sizeof(int));
|
|
for (j = 0; j < nstr; j++) {
|
|
javachars->checkstr[j] = (char *)c_malloc(env, DIGESTLENGTH * sizeof(char));
|
|
}
|
|
}
|
|
for (j = 0; j < DIGESTLENGTH; j++) {
|
|
digest[j] = 0;
|
|
}
|
|
javachars->str[index] = env->GetStringChars(jstr, 0); CE
|
|
javachars->size[index] = env->GetStringUTFLength(jstr); CE
|
|
elem_len = javachars->size[index];
|
|
len += elem_len;
|
|
elem = (char*) c_malloc(env, elem_len * sizeof(char));
|
|
for (j = 0; j < elem_len; j++) {
|
|
elem[j] = (char) javachars->str[index][j];
|
|
}
|
|
|
|
//memcpy(digest, elem, javachars->size[index]);
|
|
for (j = 0; j < elem_len; j++) {
|
|
digest[j % DIGESTLENGTH] += elem[j];
|
|
}
|
|
memcpy(javachars->checkstr[index++], digest, DIGESTLENGTH);
|
|
if (index % printperiod == 0) {
|
|
printf("Check string sum for thread %.*s is ", elem_len, elem);
|
|
for (j = 0; j < DIGESTLENGTH; j++) {
|
|
printf("%02x", digest[j]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
free(elem);
|
|
if (index == nstr) {
|
|
printf("JNI Unicode strings memory = %ld\n", len);
|
|
tmpstr = env->NewString(javachars->str[index - 1], elem_len); CE
|
|
for (j = 0; j < nstr; j++) {
|
|
elem = (char*) c_malloc(env, javachars->size[j] * sizeof(char));
|
|
for (i = 0; i < javachars->size[j]; i++) {
|
|
elem[i] = (char) javachars->str[j][i];
|
|
}
|
|
//memcpy(digest, elem, javachars->size[j]);
|
|
for (i = 0; i < DIGESTLENGTH; i++) {
|
|
digest[i] = 0;
|
|
}
|
|
for (i = 0; i < javachars->size[j]; i++) {
|
|
digest[i % DIGESTLENGTH] += elem[i];
|
|
}
|
|
free(elem);
|
|
if (memcmp(digest, javachars->checkstr[j], javachars->size[j]) == 0) {
|
|
env->ReleaseStringChars(jstr, javachars->str[j]); CE
|
|
javachars->str[j] = nullptr;
|
|
javachars->checkstr[j] = nullptr;
|
|
javachars->size[j] = 0;
|
|
} else {
|
|
equal = 0;
|
|
printf("The Unicode element No. %d has been corrupted\n", j);
|
|
for (i = 0; i < DIGESTLENGTH; i++) {
|
|
printf("digest[%d] = %02x checkstr[%d] = %02x\n", i, digest[i], i, javachars->checkstr[j][i]);
|
|
}
|
|
}
|
|
}
|
|
index = 0;
|
|
len = 0;
|
|
for (j = 0; j < nstr; j++) {
|
|
free(javachars->checkstr[j]);
|
|
}
|
|
free(javachars->checkstr);
|
|
free((void *)(javachars->str));
|
|
free(javachars->size);
|
|
free(javachars);
|
|
clazz = env->FindClass(clsName); CE
|
|
if (!equal) {
|
|
methodID = env->GetStaticMethodID(clazz, name, sig); CE
|
|
env->CallStaticVoidMethod(clazz, methodID, JNI_FALSE); CE
|
|
}
|
|
//methodID = env->GetStaticMethodID(clazz, halt, haltSig); CE
|
|
//env->CallStaticVoidMethod(clazz, methodID); CE
|
|
return tmpstr;
|
|
}
|
|
CHECK(env->MonitorExit(jobj));
|
|
return env->NewString(javachars->str[index - 1], elem_len);
|
|
}
|
|
|
|
}
|