1 /*
   2  * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 package com.sun.hotspot.tools.compiler;
  26 
  27 import java.io.*;
  28 import java.util.regex.*;
  29 
  30 /**
  31  * This class is a filter class to deal with malformed XML that used
  32  * to be produced by the JVM when generating LogCompilation.  In 1.6
  33  * and later releases it shouldn't be required.
  34  * @author never
  35  */
  36 
  37 class LogCleanupReader extends Reader {
  38     private Reader reader;
  39 
  40     private char[] buffer = new char[4096];
  41 
  42     private int bufferCount;
  43 
  44     private int bufferOffset;
  45 
  46     private char[] line = new char[1024];
  47 
  48     private int index;
  49 
  50     private int length;
  51 
  52     private char[] one = new char[1];
  53 
  54     LogCleanupReader(Reader r) {
  55         reader = r;
  56     }
  57 
  58     static final private Matcher pattern = Pattern.compile(".+ compile_id='[0-9]+'.*( compile_id='[0-9]+)").matcher("");
  59     static final private Matcher pattern2 = Pattern.compile("' (C[12]) compile_id=").matcher("");
  60     static final private Matcher pattern3 = Pattern.compile("'(destroy_vm)/").matcher("");
  61 
  62     private void fill() throws IOException {
  63         rawFill();
  64         if (length != -1) {
  65             boolean changed = false;
  66             String s = new String(line, 0, length);
  67             String orig = s;
  68 
  69             pattern2.reset(s);
  70             if (pattern2.find()) {
  71                 s = s.substring(0, pattern2.start(1)) + s.substring(pattern2.end(1) + 1);
  72                 changed = true;
  73             }
  74 
  75             pattern.reset(s);
  76             if (pattern.lookingAt()) {
  77                 s = s.substring(0, pattern.start(1)) + s.substring(pattern.end(1) + 1);
  78                 changed = true;
  79             }
  80 
  81             pattern3.reset(s);
  82             if (pattern3.find()) {
  83                 s = s.substring(0, pattern3.start(1)) + s.substring(pattern3.end(1));
  84                 changed = true;
  85             }
  86 
  87             if (changed) {
  88                 s.getChars(0, s.length(), line, 0);
  89                 length = s.length();
  90             }
  91         }
  92     }
  93 
  94     private void rawFill() throws IOException {
  95         if (bufferCount == -1) {
  96             length = -1;
  97             return;
  98         }
  99 
 100         int i = 0;
 101         boolean fillNonEOL = true;
 102         outer:
 103         while (true) {
 104             if (fillNonEOL) {
 105                 int p;
 106                 for (p = bufferOffset; p < bufferCount; p++) {
 107                     char c = buffer[p];
 108                     if (c == '\r' || c == '\n') {
 109                         bufferOffset = p;
 110                         fillNonEOL = false;
 111                         continue outer;
 112                     }
 113                     if (i >= line.length) {
 114                         // copy and enlarge the line array
 115                         char[] newLine = new char[line.length * 2];
 116                         System.arraycopy(line, 0, newLine, 0, line.length);
 117                         line = newLine;
 118                     }
 119                     line[i++] = c;
 120                 }
 121                 bufferOffset = p;
 122             } else {
 123                 int p;
 124                 for (p = bufferOffset; p < bufferCount; p++) {
 125                     char c = buffer[p];
 126                     if (c != '\r' && c != '\n') {
 127                         bufferOffset = p;
 128                         length = i;
 129                         index = 0;
 130                         return;
 131                     }
 132                     line[i++] = c;
 133                 }
 134                 bufferOffset = p;
 135             }
 136             if (bufferCount == -1) {
 137                 if (i == 0) {
 138                     length = -1;
 139                 } else {
 140                     length = i;
 141                 }
 142                 index = 0;
 143                 return;
 144             }
 145             if (bufferOffset != bufferCount) {
 146                 System.out.println(bufferOffset);
 147                 System.out.println(bufferCount);
 148                 throw new InternalError("how did we get here");
 149             }
 150             // load more data and try again.
 151             bufferCount = reader.read(buffer, 0, buffer.length);
 152             bufferOffset = 0;
 153         }
 154     }
 155 
 156     public int read() throws java.io.IOException {
 157         read(one, 0, 1);
 158         return one[0];
 159     }
 160 
 161     public int read(char[] buffer) throws java.io.IOException {
 162         return read(buffer, 0, buffer.length);
 163     }
 164 
 165     public int read(char[] b, int off, int len) throws java.io.IOException {
 166         if (length == -1) {
 167             return -1;
 168         }
 169 
 170         if (index == length) {
 171             fill();
 172             if (length == -1) {
 173                 return -1;
 174             }
 175         }
 176         int n = Math.min(length - index, Math.min(b.length - off, len));
 177         // System.out.printf("%d %d %d %d %d\n", index, length, off, len, n);
 178         System.arraycopy(line, index, b, off, n);
 179         index += n;
 180         return n;
 181     }
 182 
 183     public long skip(long n) throws java.io.IOException {
 184         long result = n;
 185         while (n-- > 0) read();
 186         return result;
 187     }
 188 
 189     public boolean ready() throws java.io.IOException {
 190         return reader.ready() || (line != null && length > 0);
 191     }
 192 
 193     public boolean markSupported() {
 194         return false;
 195     }
 196 
 197     public void mark(int unused) throws java.io.IOException {
 198         throw new UnsupportedOperationException("mark not supported");
 199     }
 200 
 201     public void reset() throws java.io.IOException {
 202         reader.reset();
 203         line = null;
 204         index = 0;
 205     }
 206 
 207     public void close() throws java.io.IOException {
 208         reader.close();
 209         line = null;
 210         index = 0;
 211     }
 212 }