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 + -
显示快捷键?