chartobyteiso8859_1.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 363 行

C
363
字号
/* * @(#)CharToByteISO8859_1.c	1.11 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 "javavm/include/interpreter.h"#include "javavm/include/directmem.h"#include "javavm/include/indirectmem.h"#include "javavm/include/common_exceptions.h"#include "generated/offsets/sun_io_CharToByteConverter.h"#include "generated/offsets/sun_io_CharToByteISO8859_1.h"#undef MIN#define MIN(x,y) ((x) < (y) ? (x) : (y))#undef FIELD_WRITE_BADINPUTLENGTH#define FIELD_WRITE_BADINPUTLENGTH(value)                     \    CVMD_fieldWriteInt(                                       \        converterObject,                                      \        CVMoffsetOfsun_io_CharToByteConverter_badInputLength, \        value)#undef FIELD_WRITE_CHAROFF#define FIELD_WRITE_CHAROFF(value)                     \    CVMD_fieldWriteInt(                                \        converterObject,                               \        CVMoffsetOfsun_io_CharToByteConverter_charOff, \        value)#undef FIELD_WRITE_BYTEOFF#define FIELD_WRITE_BYTEOFF(value)                     \    CVMD_fieldWriteInt(                                \        converterObject,                               \        CVMoffsetOfsun_io_CharToByteConverter_byteOff, \        value)#undef FIELD_WRITE_HIGHHALFZONECODE#define FIELD_WRITE_HIGHHALFZONECODE(value)                     \    CVMD_fieldWriteInt(                                         \        converterObject,                                        \        CVMoffsetOfsun_io_CharToByteISO8859_1_highHalfZoneCode, \        value);CNIEXPORT CNIResultCodeCNIsun_io_CharToByteISO8859_11_convert(CVMExecEnv* ee, CVMStackVal32 *arguments,                                       CVMMethodBlock **p_mb) {    CVMObjectICell *conObjICell = &arguments[0].j.r;    CVMObjectICell *input = &arguments[1].j.r;    CVMJavaInt inOff = arguments[2].j.i;    CVMJavaInt inEnd = arguments[3].j.i;    CVMObjectICell *output = &arguments[4].j.r;    CVMJavaInt outOff = arguments[5].j.i;    CVMJavaInt outEnd = arguments[6].j.i;    CVMObject *converterObject = CVMID_icellDirect(ee, conObjICell);    CVMArrayOfChar *inArr = (CVMArrayOfChar *)CVMID_icellDirect(ee, input);    CVMArrayOfByte *outArr = (CVMArrayOfByte *)CVMID_icellDirect(ee, output);    CVMJavaChar inElem;    CVMBool subMode;    CVMJavaChar highHalfZoneCode;    CVMObject *subBytesObject;    CVMArrayOfByte *subBytes;    CVMJavaInt subBytesSize;    CVMJavaInt inBound;    CVMJavaInt outBound;    CVMJavaInt inLen = (inArr)->length;    CVMJavaInt outLen = (outArr)->length;    CVMJavaInt inLimit = MIN(inEnd, inLen);    CVMJavaInt outLimit = MIN(outEnd, outLen);    CVMJavaInt bound;    CVMJavaInt outStart = outOff;    /*      * We need to check bounds in the following order so that     * we can throw the right exception that is compatible     * with the original Java version.     */    if (inOff >= inEnd) {        FIELD_WRITE_CHAROFF(inOff);        FIELD_WRITE_BYTEOFF(outOff);        arguments[0].j.i = 0;        return CNI_SINGLE;    } else if (inOff < 0 || inOff >= inLen) {        FIELD_WRITE_CHAROFF(inOff);        FIELD_WRITE_BYTEOFF(outOff);        CVMthrowArrayIndexOutOfBoundsException(ee, NULL);        return CNI_EXCEPTION;    } else if (outOff >= outEnd) {        FIELD_WRITE_CHAROFF(inOff);        FIELD_WRITE_BYTEOFF(outOff);        CVMthrowConversionBufferFullException(ee, NULL);        return CNI_EXCEPTION;    } else if (outOff < 0 || outOff >= outLen) {        FIELD_WRITE_CHAROFF(inOff);        FIELD_WRITE_BYTEOFF(outOff);        CVMthrowArrayIndexOutOfBoundsException(ee, NULL);        return CNI_EXCEPTION;    }    CVMD_fieldReadInt(converterObject,                      CVMoffsetOfsun_io_CharToByteConverter_subMode,                      subMode);    CVMD_fieldReadInt(converterObject,                      CVMoffsetOfsun_io_CharToByteISO8859_1_highHalfZoneCode,                      highHalfZoneCode);     CVMD_fieldReadRef(converterObject,                      CVMoffsetOfsun_io_CharToByteConverter_subBytes,                      subBytesObject);    subBytes = (CVMArrayOfByte *)subBytesObject;    subBytesSize = (subBytes)->length;    /*      * Check if previous converted string ends      * with highHalfZoneCode.      */    if (highHalfZoneCode != 0) {        /* Reset highHalfZoneCode */         FIELD_WRITE_HIGHHALFZONECODE(0);        /*          * We already checked input array bounds.          */        CVMD_arrayReadChar(inArr, inOff, inElem);        if (inElem >= 0xdc00 && inElem <= 0xdfff) {            /* This is a legal UTF16 sequence. */            if (subMode) {                if (outOff + subBytesSize > outLimit) {                    goto finish;                }                /* Copy subBytes into the output array */                 CVMD_arrayCopyByte(subBytes, 0, outArr, outOff, subBytesSize);                 inOff += 1;                outOff += subBytesSize;            } else {                FIELD_WRITE_BADINPUTLENGTH(1);                FIELD_WRITE_CHAROFF(inOff);                FIELD_WRITE_BYTEOFF(outOff);                CVMthrowUnknownCharacterException(ee, NULL);                return CNI_EXCEPTION;            }        } else {            /* This is illegal UTF16 sqeuence. */            FIELD_WRITE_BADINPUTLENGTH(0);            FIELD_WRITE_CHAROFF(inOff);            FIELD_WRITE_BYTEOFF(outOff);            CVMthrowMalformedInputException(                ee, "Previous converted string ends with"                " <High Half Zone Code> of UTF16, but this string does"                " not begin with <Low Half Zone>");             return CNI_EXCEPTION;        }    }    /* Calculate bound */    inBound = inLimit - inOff;    outBound = outLimit - outOff;    bound = inOff + MIN(inBound, outBound);    /* Loop until we hit the bound */    while (inOff < bound) {        CVMJavaInt newInBound;        CVMJavaInt newOutBound;	/* Get the input character */	CVMD_arrayReadChar(inArr, inOff, inElem);		/* Is this character mappable? */	if (inElem <= 0x00FF) {	    CVMD_arrayWriteByte(outArr, outOff, (CVMJavaByte)inElem);	    inOff ++;	    outOff ++;	}	/* Is this a high surrogate? */	else if (inElem >= 0xD800 && inElem <= 0xDBFF) {	    	    /* Is this the last character in the input? */	    if (inOff + 1 == inEnd) {		FIELD_WRITE_HIGHHALFZONECODE(inElem);		inOff ++;		goto finish;	    }	    	    /* 	     * Is there a low surrogate following? 	     * Don't forget the array bounds check. 	     */	    if (inOff + 1 >= inLen) {		FIELD_WRITE_CHAROFF(inOff);		FIELD_WRITE_BYTEOFF(outOff);		CVMthrowArrayIndexOutOfBoundsException(ee, NULL);		return CNI_EXCEPTION;	    }	    CVMD_arrayReadChar(inArr, inOff+1, inElem);	    if (inElem >= 0xDC00 && inElem <= 0xDFFF) {		/* 		 * We have a valid surrogate pair. Too bad we don't map		 * surrogates. Is subsititution enable?		 */		if (subMode) {		    		    /* Check bound */		    if (outOff + subBytesSize > outLimit) {			goto finish;		    }		    		    CVMD_arrayCopyByte(subBytes, 0, outArr, 				       outOff, subBytesSize);		    inOff += 2;		    outOff += subBytesSize;		    		    /* Recalculate bound */		    if (subBytesSize != 2) {			newInBound = inLimit - inOff;			newOutBound = outLimit - outOff;			bound = inOff + MIN(newInBound, newOutBound);		    }		} else {		    FIELD_WRITE_BADINPUTLENGTH(2);		    FIELD_WRITE_CHAROFF(inOff);		    FIELD_WRITE_BYTEOFF(outOff);		    CVMthrowUnknownCharacterException(ee, NULL);		    return CNI_EXCEPTION;		}	    } else {		/* We have a malformed surrogate pair */		FIELD_WRITE_BADINPUTLENGTH(1);		FIELD_WRITE_CHAROFF(inOff);		FIELD_WRITE_BYTEOFF(outOff);		CVMthrowMalformedInputException(ee, NULL);		return CNI_EXCEPTION;	    } 	}	/* Is this an unaccompanied low surrogate? */	else if (inElem >= 0xDC00 && inElem <= 0xDFFF) {	    FIELD_WRITE_BADINPUTLENGTH(1);	    FIELD_WRITE_CHAROFF(inOff);	    FIELD_WRITE_BYTEOFF(outOff);	    CVMthrowMalformedInputException(ee, NULL);	    return CNI_EXCEPTION;	}	/* Unmappable and not part of a surrogate */	else {	    /* Is subsititution enabled? */	    if (subMode) {		/* Check bound */		if (outOff + subBytesSize > outLimit) {		    goto finish;		}				CVMD_arrayCopyByte(subBytes, 0, outArr, 				   outOff, subBytesSize);		inOff += 1;		outOff += subBytesSize; 				/* Recalculate bound */		if (subBytesSize != 1) {		    newInBound = inLimit - inOff;		    newOutBound = outLimit - outOff;		    bound = inOff + MIN(newInBound, newOutBound);		}	    } else {		FIELD_WRITE_BADINPUTLENGTH(1);		FIELD_WRITE_CHAROFF(inOff);		FIELD_WRITE_BYTEOFF(outOff);		CVMthrowUnknownCharacterException(ee, NULL);		return CNI_EXCEPTION;	    }	}    }    finish:     /* Don't forget to write back inOff and outOff. */    FIELD_WRITE_CHAROFF(inOff);    FIELD_WRITE_BYTEOFF(outOff);    /* Check array bounds and throw appropriate exception. */    if (inOff < inEnd) { /* we didn't copy everything */        if (inOff >= inLen || outEnd > outLen) {            CVMthrowArrayIndexOutOfBoundsException(ee, NULL);            return CNI_EXCEPTION;        }        while (inOff < inEnd) {            CVMD_arrayReadChar(inArr, inOff, inElem);            if (inElem <= 0x00FF) {                CVMthrowConversionBufferFullException(ee, NULL);                return CNI_EXCEPTION;            } else if (inElem >= 0xD800 && inElem <= 0xDBFF) {                if (inOff+1 == inEnd) {                    inOff++;                    FIELD_WRITE_HIGHHALFZONECODE(inElem);                } else {                    CVMD_arrayReadChar(inArr, inOff+1, inElem);                    if (inElem >= 0xDC00 && inElem <= 0xDFFF) {                        if (subMode) {                            if (subBytesSize > 0) {                                CVMthrowConversionBufferFullException(ee, NULL);                                return CNI_EXCEPTION;                            }                            inOff += 2;                        } else {                            FIELD_WRITE_BADINPUTLENGTH(2);                            CVMthrowUnknownCharacterException(ee, NULL);                            return CNI_EXCEPTION;                        }                    } else {                        FIELD_WRITE_BADINPUTLENGTH(1);                        CVMthrowMalformedInputException(ee, NULL);                        return CNI_EXCEPTION;                   }                }            } else if (inElem >= 0xDC00 && inElem <= 0xDFFF) {                FIELD_WRITE_BADINPUTLENGTH(1);                CVMthrowMalformedInputException(ee, NULL);                return CNI_EXCEPTION;            } else {                if (subMode) {                    if (subBytesSize > 0) {                        CVMthrowConversionBufferFullException(ee, NULL);                        return CNI_EXCEPTION;                    }                    inOff++;                } else {                    FIELD_WRITE_BADINPUTLENGTH(1);                    CVMthrowUnknownCharacterException(ee, NULL);                    return CNI_EXCEPTION;                }            }        }        FIELD_WRITE_CHAROFF(inOff);    }    arguments[0].j.i = outOff - outStart;    return CNI_SINGLE; }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?