OLD | NEW |
(Empty) | |
| 1 /* Copyright (c) 2002-2008 Sun Microsystems, Inc. All rights reserved |
| 2 * |
| 3 * This program is distributed under the terms of |
| 4 * the GNU General Public License Version 2. See the LICENSE file |
| 5 * at the top of the source tree. |
| 6 */ |
| 7 package org.pantsbuild.jmake; |
| 8 |
| 9 import java.io.File; |
| 10 import java.util.LinkedHashMap; |
| 11 import java.util.Map; |
| 12 |
| 13 /** |
| 14 * This class creates the internal representation of the project database from a
byte array. |
| 15 * |
| 16 * @author Misha Dmitriev |
| 17 * 2 March 2005 |
| 18 */ |
| 19 public class BinaryProjectDatabaseReader extends BinaryFileReader { |
| 20 |
| 21 private String stringTable[]; |
| 22 private Map<String,PCDEntry> pcd; |
| 23 private int nOfEntries; |
| 24 private int pdbFormat; // Currently supported values: 0x01030300 (jmake 1.3
.3 and newer versions); 1 (all older versions) |
| 25 // These are defined in Utils as PDB_FORMAT_CODE_LATEST and PDB_FORMAT_CODE_
OLD |
| 26 |
| 27 public Map<String,PCDEntry> readProjectDatabaseFromFile(File infile) { |
| 28 byte buf[] = Utils.readFileIntoBuffer(infile); |
| 29 return readProjectDatabase(buf, infile.toString()); |
| 30 } |
| 31 |
| 32 public Map<String,PCDEntry> readProjectDatabase(byte[] pdbFile, |
| 33 String pdbFileFullPath) { |
| 34 initBuf(pdbFile, pdbFileFullPath); |
| 35 |
| 36 readPreamble(); |
| 37 readStringTable(); |
| 38 pcd = new LinkedHashMap<String,PCDEntry>(nOfEntries * 4 / 3); |
| 39 |
| 40 for (int i = 0; i < nOfEntries; i++) { |
| 41 PCDEntry entry = readPCDEntry(); |
| 42 pcd.put(entry.className, entry); |
| 43 } |
| 44 |
| 45 stringTable = null; // Help the GC |
| 46 return pcd; |
| 47 } |
| 48 |
| 49 private void readPreamble() { |
| 50 if (buf.length < Utils.magicLength + 8) { |
| 51 pdbCorruptedException("file too short"); |
| 52 } |
| 53 |
| 54 for (int i = 0; i < Utils.magicLength; i++) { |
| 55 if (buf[i] != Utils.MAGIC[i]) { |
| 56 pdbCorruptedException("wrong project database header"); |
| 57 } |
| 58 } |
| 59 |
| 60 curBufPos += Utils.magicLength; |
| 61 pdbFormat = nextInt(); |
| 62 if (pdbFormat != Utils.PDB_FORMAT_CODE_OLD && pdbFormat != Utils.PDB_FOR
MAT_CODE_LATEST) { |
| 63 pdbCorruptedException("wrong version number"); |
| 64 } |
| 65 |
| 66 int pdbSize = nextInt(); |
| 67 if (buf.length != Utils.MAGIC.length + 8 + pdbSize) { |
| 68 pdbCorruptedException("file size does not match stored value"); |
| 69 } |
| 70 |
| 71 nOfEntries = nextInt(); |
| 72 } |
| 73 |
| 74 private void readStringTable() { |
| 75 int size = nextInt(); |
| 76 stringTable = new String[size]; |
| 77 for (int i = 0; i < size; i++) { |
| 78 stringTable[i] = nextString(); |
| 79 } |
| 80 } |
| 81 |
| 82 private PCDEntry readPCDEntry() { |
| 83 String className = nextStringRef(); |
| 84 String javaFileFullPath = nextStringRef(); |
| 85 long classFileLastModified = nextLong(); |
| 86 long classFileFingerprint = nextLong(); |
| 87 ClassInfo classInfo = readClassInfo(); |
| 88 |
| 89 return new PCDEntry(className, javaFileFullPath, classFileLastModified,
classFileFingerprint, classInfo); |
| 90 } |
| 91 |
| 92 private ClassInfo readClassInfo() { |
| 93 int i, j, len; |
| 94 ClassInfo res = new ClassInfo(); |
| 95 |
| 96 res.name = nextStringRef(); |
| 97 if (pdbFormat >= Utils.PDB_FORMAT_CODE_133) { |
| 98 res.javacTargetRelease = nextInt(); |
| 99 } else { |
| 100 res.javacTargetRelease = Utils.JAVAC_TARGET_RELEASE_OLDEST; |
| 101 } |
| 102 |
| 103 len = nextChar(); |
| 104 if (len > 0) { |
| 105 String cpoolRefsToClasses[] = new String[len]; |
| 106 for (i = 0; i < len; i++) { |
| 107 cpoolRefsToClasses[i] = nextStringRef(); |
| 108 } |
| 109 res.cpoolRefsToClasses = cpoolRefsToClasses; |
| 110 boolean isRefClassArray[] = new boolean[len]; |
| 111 for (i = 0; i < len; i++) { |
| 112 isRefClassArray[i] = (buf[curBufPos++] != 0); |
| 113 } |
| 114 res.isRefClassArray = isRefClassArray; |
| 115 } |
| 116 |
| 117 len = nextChar(); |
| 118 if (len > 0) { |
| 119 String cpoolRefsToFieldClasses[] = new String[len]; |
| 120 for (i = 0; i < len; i++) { |
| 121 cpoolRefsToFieldClasses[i] = nextStringRef(); |
| 122 } |
| 123 res.cpoolRefsToFieldClasses = cpoolRefsToFieldClasses; |
| 124 String cpoolRefsToFieldNames[] = new String[len]; |
| 125 for (i = 0; i < len; i++) { |
| 126 cpoolRefsToFieldNames[i] = nextStringRef(); |
| 127 } |
| 128 res.cpoolRefsToFieldNames = cpoolRefsToFieldNames; |
| 129 String cpoolRefsToFieldSignatures[] = new String[len]; |
| 130 for (i = 0; i < len; i++) { |
| 131 cpoolRefsToFieldSignatures[i] = nextStringRef(); |
| 132 } |
| 133 res.cpoolRefsToFieldSignatures = cpoolRefsToFieldSignatures; |
| 134 } |
| 135 |
| 136 len = nextChar(); |
| 137 if (len > 0) { |
| 138 String cpoolRefsToMethodClasses[] = new String[len]; |
| 139 for (i = 0; i < len; i++) { |
| 140 cpoolRefsToMethodClasses[i] = nextStringRef(); |
| 141 } |
| 142 res.cpoolRefsToMethodClasses = cpoolRefsToMethodClasses; |
| 143 String cpoolRefsToMethodNames[] = new String[len]; |
| 144 for (i = 0; i < len; i++) { |
| 145 cpoolRefsToMethodNames[i] = nextStringRef(); |
| 146 } |
| 147 res.cpoolRefsToMethodNames = cpoolRefsToMethodNames; |
| 148 String cpoolRefsToMethodSignatures[] = new String[len]; |
| 149 for (i = 0; i < len; i++) { |
| 150 cpoolRefsToMethodSignatures[i] = nextStringRef(); |
| 151 } |
| 152 res.cpoolRefsToMethodSignatures = cpoolRefsToMethodSignatures; |
| 153 } |
| 154 |
| 155 res.accessFlags = nextChar(); |
| 156 res.isNonMemberNestedClass = (buf[curBufPos++] != 0); |
| 157 if (!"java/lang/Object".equals(res.name)) { |
| 158 res.superName = nextStringRef(); |
| 159 } |
| 160 |
| 161 len = nextChar(); |
| 162 if (len > 0) { |
| 163 String interfaces[] = new String[len]; |
| 164 for (i = 0; i < len; i++) { |
| 165 interfaces[i] = nextStringRef(); |
| 166 } |
| 167 res.interfaces = interfaces; |
| 168 } |
| 169 |
| 170 len = nextChar(); |
| 171 if (len > 0) { |
| 172 String fieldNames[] = new String[len]; |
| 173 for (i = 0; i < len; i++) { |
| 174 fieldNames[i] = nextStringRef(); |
| 175 } |
| 176 res.fieldNames = fieldNames; |
| 177 String fieldSignatures[] = new String[len]; |
| 178 for (i = 0; i < len; i++) { |
| 179 fieldSignatures[i] = nextStringRef(); |
| 180 } |
| 181 res.fieldSignatures = fieldSignatures; |
| 182 char fieldAccessFlags[] = new char[len]; |
| 183 for (i = 0; i < len; i++) { |
| 184 fieldAccessFlags[i] = nextChar(); |
| 185 } |
| 186 res.fieldAccessFlags = fieldAccessFlags; |
| 187 } |
| 188 |
| 189 len = nextChar(); |
| 190 if (len > 0) { |
| 191 Object primitiveConstantInitValues[] = new Object[len]; |
| 192 for (i = 0; i < len; i++) { |
| 193 byte code = buf[curBufPos++]; |
| 194 switch (code) { |
| 195 case 1: |
| 196 primitiveConstantInitValues[i] = nextStringRef(); |
| 197 break; |
| 198 case 2: |
| 199 primitiveConstantInitValues[i] = Integer.valueOf(nextInt
()); |
| 200 break; |
| 201 case 3: |
| 202 primitiveConstantInitValues[i] = Long.valueOf(nextLong()
); |
| 203 break; |
| 204 case 4: |
| 205 primitiveConstantInitValues[i] = Float.valueOf(nextFloat
()); |
| 206 break; |
| 207 case 5: |
| 208 primitiveConstantInitValues[i] = |
| 209 Double.valueOf(nextDouble()); |
| 210 break; |
| 211 default: // Nothing to do |
| 212 } |
| 213 } |
| 214 res.primitiveConstantInitValues = primitiveConstantInitValues; |
| 215 } |
| 216 |
| 217 len = nextChar(); |
| 218 if (len > 0) { |
| 219 String methodNames[] = new String[len]; |
| 220 for (i = 0; i < len; i++) { |
| 221 methodNames[i] = nextStringRef(); |
| 222 } |
| 223 res.methodNames = methodNames; |
| 224 String methodSignatures[] = new String[len]; |
| 225 for (i = 0; i < len; i++) { |
| 226 methodSignatures[i] = nextStringRef(); |
| 227 } |
| 228 res.methodSignatures = methodSignatures; |
| 229 char methodAccessFlags[] = new char[len]; |
| 230 for (i = 0; i < len; i++) { |
| 231 methodAccessFlags[i] = nextChar(); |
| 232 } |
| 233 res.methodAccessFlags = methodAccessFlags; |
| 234 } |
| 235 |
| 236 len = nextChar(); |
| 237 if (len > 0) { |
| 238 String checkedExceptions[][] = new String[len][]; |
| 239 for (i = 0; i < len; i++) { |
| 240 int len1 = nextChar(); |
| 241 if (len1 > 0) { |
| 242 checkedExceptions[i] = new String[len1]; |
| 243 for (j = 0; j < len1; j++) { |
| 244 checkedExceptions[i][j] = nextStringRef(); |
| 245 } |
| 246 } |
| 247 } |
| 248 res.checkedExceptions = checkedExceptions; |
| 249 } |
| 250 |
| 251 len = nextChar(); |
| 252 if (len > 0) { |
| 253 String nestedClasses[] = new String[len]; |
| 254 for (i = 0; i < len; i++) { |
| 255 nestedClasses[i] = nextStringRef(); |
| 256 } |
| 257 res.nestedClasses = nestedClasses; |
| 258 } |
| 259 |
| 260 res.initializeImmediateTransientFields(); |
| 261 return res; |
| 262 } |
| 263 |
| 264 private String nextString() { |
| 265 int length = nextChar(); |
| 266 if (buf.length < curBufPos + length) { |
| 267 pdbCorruptedException("data error"); |
| 268 } |
| 269 String res = (new String(buf, curBufPos, length)).intern(); |
| 270 curBufPos += length; |
| 271 return res; |
| 272 } |
| 273 |
| 274 private String nextStringRef() { |
| 275 return stringTable[nextInt()]; |
| 276 } |
| 277 |
| 278 private void pdbCorruptedException(String message) { |
| 279 throw new PrivateException(new PublicExceptions.PDBCorruptedException(me
ssage)); |
| 280 } |
| 281 } |
OLD | NEW |