test/jdk/java/lang/instrument/NamedBuffer.java
changeset 53924 09cba396916f
parent 47216 71c04702a3d5
--- a/test/jdk/java/lang/instrument/NamedBuffer.java	Wed Feb 13 12:01:09 2019 +0100
+++ b/test/jdk/java/lang/instrument/NamedBuffer.java	Tue Feb 26 08:01:20 2019 -0500
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,7 @@
     public static byte[]
     loadBufferFromStream(InputStream stream)
         throws IOException
-        {
+    {
         // hack for now, just assume the stream will fit in our reasonable size buffer.
         // if not, panic
         int bufferLimit = 200 * 1024;
@@ -83,5 +83,60 @@
                             0,
                             actualSize);
         return resultBuffer;
+    }
+
+    static final String DEST = System.getProperty("test.classes");
+    static final boolean VERBOSE = false;
+
+    static boolean checkMatch(byte[] buf, byte[] name, int begIdx) {
+        if (buf.length < name.length + begIdx) {
+            return false;
         }
+        for (int i = 0; i < name.length; i++) {
+            if (buf[i + begIdx] != name[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // This function reads a class file from disk and replaces the first character of
+    // the name with the one passed as "replace".  Then goes through the bytecodes to
+    // replace all instances of the name of the class with the new name.  The
+    // redefinition tests use this to redefine Host$ classes with precompiled class files
+    // Xost.java, Yost.java and Zost.java.
+    static byte[]
+    bytesForHostClass(char replace, String className) throws Throwable {
+        String tail = className.substring(1);
+        String origClassName = "" + replace + tail;
+        File clsfile = new File(DEST + "/" + origClassName + ".class");
+
+        if (VERBOSE) {
+            System.out.println("   Reading bytes from " + clsfile);
+        }
+        byte[] buf = null;
+        try (FileInputStream str = new FileInputStream(clsfile)) {
+            buf = loadBufferFromStream(str);
+        }
+
+        boolean found = false;
+        int dollarSignIdx = className.indexOf('$');
+        int ptrnLen = (dollarSignIdx == -1) ? className.length() : dollarSignIdx;
+        byte[] ptrnBytes = origClassName.substring(0, ptrnLen).getBytes();
+        byte firstByte = className.getBytes()[0];
+
+        for (int i = 0; i < buf.length - ptrnLen; i++) {
+            if (checkMatch(buf, ptrnBytes, i)) {
+                if (VERBOSE) {
+                    System.out.println("Appear to have found " + origClassName + " starting at " + i);
+                }
+                buf[i] = firstByte;
+                found = true;
+            }
+        }
+        if (!found) {
+            throw new Error("Could not locate '" + ptrnBytes + "' name in byte array");
+        }
+        return buf;
+    }
 }