001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package com.tctest;
005:
006: import org.apache.commons.io.IOUtils;
007:
008: import com.tc.asm.ClassAdapter;
009: import com.tc.asm.ClassReader;
010: import com.tc.asm.ClassVisitor;
011: import com.tc.asm.MethodAdapter;
012: import com.tc.asm.MethodVisitor;
013: import com.tc.asm.Opcodes;
014: import com.tc.asm.commons.EmptyVisitor;
015: import com.tc.object.bytecode.hook.impl.JavaLangArrayHelpers;
016: import com.tc.test.TCTestCase;
017:
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.util.HashSet;
021: import java.util.Set;
022:
023: public class InstrumentedJavaLangStringTest extends TCTestCase {
024:
025: public InstrumentedJavaLangStringTest() {
026: //
027: }
028:
029: public void testGetBytes() {
030: String s = "Timmy Teck";
031: byte[] b = new byte[4];
032: s.getBytes(6, 10, b, 0);
033: assertEquals((byte) 'T', b[0]);
034: assertEquals((byte) 'e', b[1]);
035: assertEquals((byte) 'c', b[2]);
036: assertEquals((byte) 'k', b[3]);
037: }
038:
039: public void testGetChars() {
040: String s = "Timmy Teck";
041: char[] c = new char[s.length() + 1];
042: s.getChars(0, 5, c, 2);
043: assertEquals((char) 0, c[0]);
044: assertEquals((char) 0, c[1]);
045: assertEquals('T', c[2]);
046: assertEquals('i', c[3]);
047: assertEquals('m', c[4]);
048: assertEquals('m', c[5]);
049: assertEquals('y', c[6]);
050:
051: try {
052: s.getChars(0, 15, c, 0);
053: fail();
054: } catch (StringIndexOutOfBoundsException e) {
055: // expected
056: }
057:
058: try {
059: s.getChars(-1, 3, c, 0);
060: fail();
061: } catch (StringIndexOutOfBoundsException e) {
062: // expected
063: }
064:
065: try {
066: s.getChars(3, 1, c, 0);
067: fail();
068: } catch (StringIndexOutOfBoundsException e) {
069: // expected
070: }
071:
072: }
073:
074: public void testStringIsInstrumented() throws IOException {
075: ClassReader reader = new ClassReader(getStringBytes());
076: StringVisitor visitor = new StringVisitor(new EmptyVisitor());
077: reader.accept(visitor, ClassReader.SKIP_FRAMES);
078:
079: assertEquals(visitor.verified.toString(), 2, visitor.verified
080: .size());
081: assertTrue(visitor.verified.contains("getBytes"));
082: assertTrue(visitor.verified.contains("getChars"));
083: }
084:
085: private byte[] getStringBytes() throws IOException {
086: InputStream is = ClassLoader.getSystemClassLoader()
087: .getResourceAsStream(
088: String.class.getName().replace('.', '/')
089: .concat(".class"));
090: return IOUtils.toByteArray(is);
091: }
092:
093: private static class StringVisitor extends ClassAdapter {
094:
095: private final Set verified = new HashSet();
096:
097: public StringVisitor(ClassVisitor cv) {
098: super (cv);
099: }
100:
101: public MethodVisitor visitMethod(int access, String name,
102: String desc, String signature, String[] exceptions) {
103: if ((name.equals("getChars") && "(II[CI)V".equals(desc))
104: || (name.equals("getBytes") && desc
105: .equals("(II[BI)V"))) {
106: // make formatter sane
107: return new VerifyArrayManagerAccess(super .visitMethod(
108: access, name, desc, signature, exceptions),
109: name);
110: }
111: return null;
112: }
113:
114: private class VerifyArrayManagerAccess extends MethodAdapter {
115:
116: private final String method;
117:
118: public VerifyArrayManagerAccess(MethodVisitor mv,
119: String method) {
120: super (mv);
121: this .method = method;
122: }
123:
124: public void visitMethodInsn(int opcode, String owner,
125: String name, String desc) {
126: if ((opcode == Opcodes.INVOKESTATIC)
127: && JavaLangArrayHelpers.CLASS.equals(owner)) {
128: verified.add(method);
129: }
130: }
131:
132: }
133:
134: }
135:
136: }
|