001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package gov.nasa.jpf.jvm;
020:
021: import gov.nasa.jpf.jvm.MJIEnv;
022:
023: /**
024: * MJI NativePeer class for java.lang.StringBuffer library abstraction
025: */
026: public class JPF_java_lang_StringBuffer {
027:
028: static boolean hasSharedField = false; // Java 1.4 has, 1.5 doesn't
029:
030: public static void $clinit(MJIEnv env, int clsObjRef) {
031: // apparently, Java 1.5 has changed the implementation of class
032: // StringBuffer so that it doesn't use the 'shared' state anymore
033: // (which was a performance hack to avoid copying the char array
034: // data when creating String objects from subsequently unmodified
035: // StringBuffers
036: // adding this little extra logic here also serves the purpose of
037: // avoiding a native ObjectStreamClass method which is called during
038: // the static StringBuffer init
039: ClassInfo ci = env.getClassInfo();
040: if (ci.getInstanceField("shared") != null) {
041: hasSharedField = true;
042: }
043: }
044:
045: static int appendString(MJIEnv env, int objref, String s) {
046: int slen = s.length();
047: int aref = env.getReferenceField(objref, "value");
048: int alen = env.getArrayLength(aref);
049: int count = env.getIntField(objref, "count");
050: int i, j;
051: int n = count + slen;
052:
053: if (n < alen) {
054: for (i = count, j = 0; i < n; i++, j++) {
055: env.setCharArrayElement(aref, i, s.charAt(j));
056: }
057: } else {
058: int m = 3 * alen / 2;
059: if (m < n) {
060: m = n;
061: }
062: int arefNew = env.newCharArray(m);
063: for (i = 0; i < count; i++) {
064: env.setCharArrayElement(arefNew, i, env
065: .getCharArrayElement(aref, i));
066: }
067: for (j = 0; i < n; i++, j++) {
068: env.setCharArrayElement(arefNew, i, s.charAt(j));
069: }
070: env.setReferenceField(objref, "value", arefNew);
071: }
072:
073: if (hasSharedField) {
074: env.setBooleanField(objref, "shared", false);
075: }
076: env.setIntField(objref, "count", n);
077:
078: return objref;
079: }
080:
081: public static int append__Ljava_lang_StringBuffer_2(MJIEnv env,
082: int objref, int sbref) {
083: int vref = env.getReferenceField(sbref, "value");
084: int sbCount = env.getIntField(sbref, "count");
085:
086: // how braindead, how lazy
087: char[] b = env.getCharArrayObject(vref);
088: String s = new String(b, 0, sbCount);
089:
090: return appendString(env, objref, s);
091: }
092:
093: public static int append__Ljava_lang_String_2(MJIEnv env,
094: int objref, int sref) {
095: String s = env.getStringObject(sref);
096:
097: return appendString(env, objref, s);
098: }
099:
100: public static int append__I(MJIEnv env, int objref, int i) {
101: String s = Integer.toString(i);
102:
103: return appendString(env, objref, s);
104: }
105:
106: public static int append__F(MJIEnv env, int objref, float f) {
107: String s = Float.toString(f);
108:
109: return appendString(env, objref, s);
110: }
111:
112: public static int append__D(MJIEnv env, int objref, double d) {
113: String s = Double.toString(d);
114:
115: return appendString(env, objref, s);
116: }
117:
118: public static int append__J(MJIEnv env, int objref, long l) {
119: String s = Long.toString(l);
120:
121: return appendString(env, objref, s);
122: }
123:
124: public static int append__Z(MJIEnv env, int objref, boolean b) {
125: String s = b ? "true" : "false";
126:
127: return appendString(env, objref, s);
128: }
129:
130: public static int append__B(MJIEnv env, int objref, byte b) {
131: return append__C(env, objref, (char) b);
132: }
133:
134: public static int append__C(MJIEnv env, int objref, char c) {
135: int aref = env.getReferenceField(objref, "value");
136: int alen = env.getArrayLength(aref);
137: int count = env.getIntField(objref, "count");
138: int i, j;
139: int n = count + 1;
140:
141: if (n < alen) {
142: env.setCharArrayElement(aref, count, c);
143: } else {
144: int m = 3 * alen / 2;
145: int arefNew = env.newCharArray(m);
146: for (i = 0; i < count; i++) {
147: env.setCharArrayElement(arefNew, i, env
148: .getCharArrayElement(aref, i));
149: }
150: env.setCharArrayElement(arefNew, count, c);
151: env.setReferenceField(objref, "value", arefNew);
152: }
153:
154: if (hasSharedField) {
155: env.setBooleanField(objref, "shared", false);
156: }
157: env.setIntField(objref, "count", n);
158:
159: return objref;
160:
161: }
162: }
|