string.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 613 行 · 第 1/2 页
C
613 行
/* * @(#)String.c 1.19 06/10/10 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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 program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */#include "jvm.h"#include "javavm/include/indirectmem.h"#include "javavm/include/common_exceptions.h"#include "generated/offsets/java_lang_String.h"#undef MIN#define MIN(x,y) ((x) < (y) ? (x) : (y))#undef FIELD_READ_COUNT#define FIELD_READ_COUNT(obj, val) \ CVMD_fieldReadInt(obj, \ CVMoffsetOfjava_lang_String_count, val)#undef FIELD_READ_VALUE#define FIELD_READ_VALUE(obj, val) \ CVMD_fieldReadRef(obj, \ CVMoffsetOfjava_lang_String_value, val)#undef FIELD_READ_OFFSET#define FIELD_READ_OFFSET(obj, val) \ CVMD_fieldReadInt(obj, \ CVMoffsetOfjava_lang_String_offset, val)/* * Note: String is a final class. It uses a private * array as character storage. String constructors * record the first index of character and the number * of total characters in the storage, and throw * StringIndexOutOfBoundsException if necessary. * Theoretically we are safe when accessing String * characters as long as we don't exceed the 'count'. * So we can eliminate array bounds checking for * some cases. *//* * Class: java/lang/String * Method: charAt * Signature: (I)C */CNIEXPORT CNIResultCodeCNIjava_lang_String_charAt(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ CVMObject *thisStringObject; CVMJavaInt index = arguments[1].j.i; CVMJavaInt count; CVMJavaInt offset; CVMObject *valueObject; CVMArrayOfChar *value; CVMJavaChar c; /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {}); thisStringObject = CVMID_icellDirect(ee, &arguments[0].j.r); FIELD_READ_COUNT(thisStringObject, count); /* The following also checks for (index < 0) by casting index into a CVMUint32 before comparing against count: */ if (((CVMUint32)index) >= count) { goto errorCase; } FIELD_READ_VALUE(thisStringObject, valueObject); FIELD_READ_OFFSET(thisStringObject, offset); value = (CVMArrayOfChar *)valueObject; CVMD_arrayReadChar(value, index+offset, c); arguments[0].j.i = c; return CNI_SINGLE; errorCase: CVMthrowStringIndexOutOfBoundsException( ee, "String index out of range: %d", index); return CNI_EXCEPTION;}/* * Class: java/lang/String * Method: getChars * Signature: (II[CI)V */CNIEXPORT CNIResultCodeCNIjava_lang_String_getChars(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ CVMObject *thisStringObject; CVMJavaInt srcBegin = arguments[1].j.i; CVMJavaInt srcEnd = arguments[2].j.i; CVMArrayOfChar *dst; CVMJavaInt dstBegin = arguments[4].j.i; CVMJavaInt count; CVMJavaInt offset; CVMJavaInt dstLen; CVMObject *valueObject; CVMArrayOfChar *value; CVMClassBlock *dstCb; /* CNI policy: offer a gc-safe checkpoint */ CVMD_gcSafeCheckPoint(ee, {}, {}); thisStringObject = CVMID_icellDirect(ee, &arguments[0].j.r); dst = (CVMArrayOfChar *)CVMID_icellDirect(ee, &arguments[3].j.r); /* Copy from the Java version of String.getChars*/ if (srcBegin < 0) { CVMthrowStringIndexOutOfBoundsException( ee, "String index out of range: %d", srcBegin); return CNI_EXCEPTION; } FIELD_READ_COUNT(thisStringObject, count); if (srcEnd > count) { CVMthrowStringIndexOutOfBoundsException( ee, "String index out of range: %d", srcEnd); return CNI_EXCEPTION; } if (srcBegin > srcEnd) { CVMthrowStringIndexOutOfBoundsException( ee, "String index out of range: %d", srcEnd - srcBegin); return CNI_EXCEPTION; } /* Check NULL for dstObject */ if (dst == NULL) { CVMthrowNullPointerException(ee, NULL); return CNI_EXCEPTION; } /* Check whether dst is a char array */ dstCb = CVMobjectGetClass(dst); if (!CVMisArrayClass(dstCb) || CVMarrayBaseType(dstCb) != CVM_T_CHAR) { CVMthrowArrayStoreException(ee, NULL); return CNI_EXCEPTION; } /* Array bounds checking for dst*/ dstLen = CVMD_arrayGetLength(dst); if (dstBegin < 0 || dstBegin > dstLen || dstBegin + srcEnd - srcBegin > dstLen) { CVMthrowArrayIndexOutOfBoundsException(ee, NULL); return CNI_EXCEPTION; } FIELD_READ_VALUE(thisStringObject, valueObject); FIELD_READ_OFFSET(thisStringObject, offset); value = (CVMArrayOfChar *)valueObject; CVMD_arrayCopyChar(value, offset + srcBegin, dst, dstBegin, srcEnd - srcBegin); return CNI_VOID; } /* * Class: java/lang/String * Method: equals * Signature: (Ljava/lang/Object;)Z */CNIEXPORT CNIResultCodeCNIjava_lang_String_equals(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb){ CVMObjectICell *thisStringICell = &arguments[0].j.r; CVMObjectICell *anObjectICell = &arguments[1].j.r; CVMObject *thisStringObject = CVMID_icellDirect(ee, thisStringICell); CVMObject *anObject = CVMID_icellDirect(ee, anObjectICell); if (thisStringObject == anObject) { /* Same object, return true directly. */ arguments[0].j.i = CVM_TRUE; return CNI_SINGLE; } else if (anObject == NULL) { /* * If anObject is null, the Java version * always returns False, unless this String * is also null, in which case a NullPointerException * is already thrown by the interpreter. */ arguments[0].j.i = CVM_FALSE; return CNI_SINGLE; } if (CVMobjectGetClass(anObject) == CVMsystemClass(java_lang_String)) { CVMJavaInt count1; CVMJavaInt count2; /* The argument anObject is a String. So compare. */ FIELD_READ_COUNT(thisStringObject, count1); FIELD_READ_COUNT(anObject, count2); if (count1 == count2) { CVMObject *valueObject1; CVMObject *valueObject2; CVMArrayOfChar *v1; CVMArrayOfChar *v2; CVMJavaInt i; CVMJavaInt j; CVMJavaChar c1; CVMJavaChar c2; FIELD_READ_VALUE(thisStringObject, valueObject1); FIELD_READ_VALUE(anObject, valueObject2); v1 = (CVMArrayOfChar *)valueObject1; v2 = (CVMArrayOfChar *)valueObject2; FIELD_READ_OFFSET(thisStringObject, i); FIELD_READ_OFFSET(anObject, j); while (count1-- > 0) { CVMD_arrayReadChar(v1, i, c1); CVMD_arrayReadChar(v2, j, c2); if (c1 != c2) { arguments[0].j.i = CVM_FALSE; return CNI_SINGLE; } i++; j++; } arguments[0].j.i = CVM_TRUE; return CNI_SINGLE; } } arguments[0].j.i = CVM_FALSE; return CNI_SINGLE;}/* * Class: java/lang/String * Method: compareTo * Signature: (Ljava/lang/String;)I */CNIEXPORT CNIResultCodeCNIjava_lang_String_compareTo(CVMExecEnv* ee, CVMStackVal32 *arguments, CVMMethodBlock **p_mb) { CVMObjectICell *thisStringICell = &arguments[0].j.r; CVMObjectICell *anotherStringICell = &arguments[1].j.r; CVMObject* thisStringObject = CVMID_icellDirect(ee, thisStringICell); CVMObject* anotherStringObject = CVMID_icellDirect(ee, anotherStringICell); CVMJavaInt len1; CVMJavaInt len2; CVMJavaInt n; CVMObject *valueObject1; CVMObject *valueObject2; CVMArrayOfChar *v1; CVMArrayOfChar *v2; CVMJavaInt i; CVMJavaInt j; CVMJavaChar c1; CVMJavaChar c2; /* * If anObject is null, a NullPointerException * should be thrown. The interpreter already * did CHECK_NULL for this String. */ if (anotherStringObject == NULL) { CVMthrowNullPointerException(ee, NULL); return CNI_EXCEPTION; } /* Get count, value, and offset */ FIELD_READ_COUNT(thisStringObject, len1); FIELD_READ_COUNT(anotherStringObject, len2); n = MIN(len1, len2); FIELD_READ_VALUE(thisStringObject, valueObject1); FIELD_READ_VALUE(anotherStringObject, valueObject2); v1 = (CVMArrayOfChar *)valueObject1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?