| Index: third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseReader.java
|
| diff --git a/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseReader.java b/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseReader.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..e75e2064181db45a066bfa7dafe71a2295f7b227
|
| --- /dev/null
|
| +++ b/third_party/jmake/src/org/pantsbuild/jmake/BinaryProjectDatabaseReader.java
|
| @@ -0,0 +1,281 @@
|
| +/* Copyright (c) 2002-2008 Sun Microsystems, Inc. All rights reserved
|
| + *
|
| + * This program is distributed under the terms of
|
| + * the GNU General Public License Version 2. See the LICENSE file
|
| + * at the top of the source tree.
|
| + */
|
| +package org.pantsbuild.jmake;
|
| +
|
| +import java.io.File;
|
| +import java.util.LinkedHashMap;
|
| +import java.util.Map;
|
| +
|
| +/**
|
| + * This class creates the internal representation of the project database from a byte array.
|
| + *
|
| + * @author Misha Dmitriev
|
| + * 2 March 2005
|
| + */
|
| +public class BinaryProjectDatabaseReader extends BinaryFileReader {
|
| +
|
| + private String stringTable[];
|
| + private Map<String,PCDEntry> pcd;
|
| + private int nOfEntries;
|
| + private int pdbFormat; // Currently supported values: 0x01030300 (jmake 1.3.3 and newer versions); 1 (all older versions)
|
| + // These are defined in Utils as PDB_FORMAT_CODE_LATEST and PDB_FORMAT_CODE_OLD
|
| +
|
| + public Map<String,PCDEntry> readProjectDatabaseFromFile(File infile) {
|
| + byte buf[] = Utils.readFileIntoBuffer(infile);
|
| + return readProjectDatabase(buf, infile.toString());
|
| + }
|
| +
|
| + public Map<String,PCDEntry> readProjectDatabase(byte[] pdbFile,
|
| + String pdbFileFullPath) {
|
| + initBuf(pdbFile, pdbFileFullPath);
|
| +
|
| + readPreamble();
|
| + readStringTable();
|
| + pcd = new LinkedHashMap<String,PCDEntry>(nOfEntries * 4 / 3);
|
| +
|
| + for (int i = 0; i < nOfEntries; i++) {
|
| + PCDEntry entry = readPCDEntry();
|
| + pcd.put(entry.className, entry);
|
| + }
|
| +
|
| + stringTable = null; // Help the GC
|
| + return pcd;
|
| + }
|
| +
|
| + private void readPreamble() {
|
| + if (buf.length < Utils.magicLength + 8) {
|
| + pdbCorruptedException("file too short");
|
| + }
|
| +
|
| + for (int i = 0; i < Utils.magicLength; i++) {
|
| + if (buf[i] != Utils.MAGIC[i]) {
|
| + pdbCorruptedException("wrong project database header");
|
| + }
|
| + }
|
| +
|
| + curBufPos += Utils.magicLength;
|
| + pdbFormat = nextInt();
|
| + if (pdbFormat != Utils.PDB_FORMAT_CODE_OLD && pdbFormat != Utils.PDB_FORMAT_CODE_LATEST) {
|
| + pdbCorruptedException("wrong version number");
|
| + }
|
| +
|
| + int pdbSize = nextInt();
|
| + if (buf.length != Utils.MAGIC.length + 8 + pdbSize) {
|
| + pdbCorruptedException("file size does not match stored value");
|
| + }
|
| +
|
| + nOfEntries = nextInt();
|
| + }
|
| +
|
| + private void readStringTable() {
|
| + int size = nextInt();
|
| + stringTable = new String[size];
|
| + for (int i = 0; i < size; i++) {
|
| + stringTable[i] = nextString();
|
| + }
|
| + }
|
| +
|
| + private PCDEntry readPCDEntry() {
|
| + String className = nextStringRef();
|
| + String javaFileFullPath = nextStringRef();
|
| + long classFileLastModified = nextLong();
|
| + long classFileFingerprint = nextLong();
|
| + ClassInfo classInfo = readClassInfo();
|
| +
|
| + return new PCDEntry(className, javaFileFullPath, classFileLastModified, classFileFingerprint, classInfo);
|
| + }
|
| +
|
| + private ClassInfo readClassInfo() {
|
| + int i, j, len;
|
| + ClassInfo res = new ClassInfo();
|
| +
|
| + res.name = nextStringRef();
|
| + if (pdbFormat >= Utils.PDB_FORMAT_CODE_133) {
|
| + res.javacTargetRelease = nextInt();
|
| + } else {
|
| + res.javacTargetRelease = Utils.JAVAC_TARGET_RELEASE_OLDEST;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String cpoolRefsToClasses[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToClasses[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToClasses = cpoolRefsToClasses;
|
| + boolean isRefClassArray[] = new boolean[len];
|
| + for (i = 0; i < len; i++) {
|
| + isRefClassArray[i] = (buf[curBufPos++] != 0);
|
| + }
|
| + res.isRefClassArray = isRefClassArray;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String cpoolRefsToFieldClasses[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToFieldClasses[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToFieldClasses = cpoolRefsToFieldClasses;
|
| + String cpoolRefsToFieldNames[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToFieldNames[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToFieldNames = cpoolRefsToFieldNames;
|
| + String cpoolRefsToFieldSignatures[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToFieldSignatures[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToFieldSignatures = cpoolRefsToFieldSignatures;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String cpoolRefsToMethodClasses[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToMethodClasses[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToMethodClasses = cpoolRefsToMethodClasses;
|
| + String cpoolRefsToMethodNames[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToMethodNames[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToMethodNames = cpoolRefsToMethodNames;
|
| + String cpoolRefsToMethodSignatures[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + cpoolRefsToMethodSignatures[i] = nextStringRef();
|
| + }
|
| + res.cpoolRefsToMethodSignatures = cpoolRefsToMethodSignatures;
|
| + }
|
| +
|
| + res.accessFlags = nextChar();
|
| + res.isNonMemberNestedClass = (buf[curBufPos++] != 0);
|
| + if (!"java/lang/Object".equals(res.name)) {
|
| + res.superName = nextStringRef();
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String interfaces[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + interfaces[i] = nextStringRef();
|
| + }
|
| + res.interfaces = interfaces;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String fieldNames[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + fieldNames[i] = nextStringRef();
|
| + }
|
| + res.fieldNames = fieldNames;
|
| + String fieldSignatures[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + fieldSignatures[i] = nextStringRef();
|
| + }
|
| + res.fieldSignatures = fieldSignatures;
|
| + char fieldAccessFlags[] = new char[len];
|
| + for (i = 0; i < len; i++) {
|
| + fieldAccessFlags[i] = nextChar();
|
| + }
|
| + res.fieldAccessFlags = fieldAccessFlags;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + Object primitiveConstantInitValues[] = new Object[len];
|
| + for (i = 0; i < len; i++) {
|
| + byte code = buf[curBufPos++];
|
| + switch (code) {
|
| + case 1:
|
| + primitiveConstantInitValues[i] = nextStringRef();
|
| + break;
|
| + case 2:
|
| + primitiveConstantInitValues[i] = Integer.valueOf(nextInt());
|
| + break;
|
| + case 3:
|
| + primitiveConstantInitValues[i] = Long.valueOf(nextLong());
|
| + break;
|
| + case 4:
|
| + primitiveConstantInitValues[i] = Float.valueOf(nextFloat());
|
| + break;
|
| + case 5:
|
| + primitiveConstantInitValues[i] =
|
| + Double.valueOf(nextDouble());
|
| + break;
|
| + default: // Nothing to do
|
| + }
|
| + }
|
| + res.primitiveConstantInitValues = primitiveConstantInitValues;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String methodNames[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + methodNames[i] = nextStringRef();
|
| + }
|
| + res.methodNames = methodNames;
|
| + String methodSignatures[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + methodSignatures[i] = nextStringRef();
|
| + }
|
| + res.methodSignatures = methodSignatures;
|
| + char methodAccessFlags[] = new char[len];
|
| + for (i = 0; i < len; i++) {
|
| + methodAccessFlags[i] = nextChar();
|
| + }
|
| + res.methodAccessFlags = methodAccessFlags;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String checkedExceptions[][] = new String[len][];
|
| + for (i = 0; i < len; i++) {
|
| + int len1 = nextChar();
|
| + if (len1 > 0) {
|
| + checkedExceptions[i] = new String[len1];
|
| + for (j = 0; j < len1; j++) {
|
| + checkedExceptions[i][j] = nextStringRef();
|
| + }
|
| + }
|
| + }
|
| + res.checkedExceptions = checkedExceptions;
|
| + }
|
| +
|
| + len = nextChar();
|
| + if (len > 0) {
|
| + String nestedClasses[] = new String[len];
|
| + for (i = 0; i < len; i++) {
|
| + nestedClasses[i] = nextStringRef();
|
| + }
|
| + res.nestedClasses = nestedClasses;
|
| + }
|
| +
|
| + res.initializeImmediateTransientFields();
|
| + return res;
|
| + }
|
| +
|
| + private String nextString() {
|
| + int length = nextChar();
|
| + if (buf.length < curBufPos + length) {
|
| + pdbCorruptedException("data error");
|
| + }
|
| + String res = (new String(buf, curBufPos, length)).intern();
|
| + curBufPos += length;
|
| + return res;
|
| + }
|
| +
|
| + private String nextStringRef() {
|
| + return stringTable[nextInt()];
|
| + }
|
| +
|
| + private void pdbCorruptedException(String message) {
|
| + throw new PrivateException(new PublicExceptions.PDBCorruptedException(message));
|
| + }
|
| +}
|
|
|