1 4 5 package com.etymon.pjx; 6 7 import java.io.*; 8 import java.util.*; 9 10 15 public class XrefTable { 16 17 20 protected int[] _generation; 21 22 27 protected long[] _index; 28 29 34 protected long[] _index_sorted; 35 36 40 protected List _startxrefs; 41 42 46 protected PdfDictionary _trailer; 47 48 52 protected byte[] _usage; 53 54 57 public static final byte ENTRY_FREE = 1; 58 59 62 public static final byte ENTRY_IN_USE = 2; 63 64 67 public static final byte ENTRY_UNDEFINED = 0; 69 74 protected XrefTable() { 75 } 76 77 90 public XrefTable(long[] index, int[] generation, byte[] usage, 91 PdfDictionary trailerDictionary) throws PdfFormatException { 92 93 if ( (index.length != generation.length) && 94 (index.length != usage.length) ) { 95 throw new PdfFormatException("Xref arrays are not the same length."); 96 } 97 _index = new long[index.length]; 98 _generation = new int[generation.length]; 99 _usage = new byte[usage.length]; 100 System.arraycopy(index, 0, _index, 0, index.length); 101 System.arraycopy(generation, 0, _generation, 0, generation.length); 102 System.arraycopy(usage, 0, _usage, 0, usage.length); 103 _startxrefs = new ArrayList(); 104 createSortedIndexArray(); 105 106 _trailer = trailerDictionary; 107 } 108 109 113 public Object clone() throws CloneNotSupportedException { 114 return super.clone(); 115 } 116 117 protected void createSortedIndexArray() { 118 119 int size = 0; 121 for (int x = 0; x < _usage.length; x++) { 122 if (_usage[x] == ENTRY_IN_USE) { 123 size++; 124 } 125 } 126 127 _index_sorted = new long[size + _startxrefs.size()]; 128 int y = 0; 129 for (int x = 0; x < _usage.length; x++) { 131 if (_usage[x] == ENTRY_IN_USE) { 132 _index_sorted[y++] = _index[x]; 133 } 134 } 135 for (Iterator p = _startxrefs.iterator(); p.hasNext(); ) { 137 _index_sorted[y++] = ((Long )p.next()).longValue(); 138 } 139 140 Arrays.sort(_index_sorted); 141 142 } 143 144 154 public long estimateObjectEnd(int n) { 155 156 if (_usage[n] != ENTRY_IN_USE) { 157 return -1; 158 } 159 160 long start = _index[n]; 161 162 int x = Arrays.binarySearch(_index_sorted, start); 163 164 while ( (x < _index_sorted.length) && (_index_sorted[x] == start) ) { 165 x++; 166 } 167 168 if (x < _index_sorted.length) { 169 return _index_sorted[x]; 170 } else { 171 return -1; 172 } 173 174 } 175 176 181 public int getGeneration(int n) { 182 return _generation[n]; 183 } 184 185 192 public int[] getGenerationArray() { 193 int[] a = new int[_generation.length]; 194 System.arraycopy(_generation, 0, a, 0, _generation.length); 195 return a; 196 } 197 198 203 public long getIndex(int n) { 204 return _index[n]; 205 } 206 207 214 public long[] getIndexArray() { 215 long[] a = new long[_index.length]; 216 System.arraycopy(_index, 0, a, 0, _index.length); 217 return a; 218 } 219 220 229 protected List getStartxrefList() { 230 return _startxrefs; 231 } 232 233 238 public PdfDictionary getTrailerDictionary() { 239 return _trailer; 240 } 241 242 247 public byte getUsage(int n) { 248 return _usage[n]; 249 } 250 251 258 public byte[] getUsageArray() { 259 byte[] a = new byte[_usage.length]; 260 System.arraycopy(_usage, 0, a, 0, _usage.length); 261 return a; 262 } 263 264 269 public int size() { 270 return _usage.length; 271 } 272 273 279 public String toString() { 280 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 281 try { 282 PdfWriter w = new PdfWriter(baos); 283 writePdf(w, 0); 284 w.close(); 285 baos.close(); 286 } 287 catch (IOException e) { 288 return null; 289 } 290 return baos.toString(); 291 } 292 293 299 protected int[] unwrapGenerationArray() { 300 return _generation; 301 } 302 303 309 protected long[] unwrapIndexArray() { 310 return _index; 311 } 312 313 319 protected byte[] unwrapUsageArray() { 320 return _usage; 321 } 322 323 339 protected static XrefTable wrap(long[] index, int[] generation, byte[] usage, PdfDictionary trailerDictionary) { 340 XrefTable xt = new XrefTable(); 341 xt._index = index; 342 xt._generation = generation; 343 xt._usage = usage; 344 xt._trailer = trailerDictionary; 345 xt._startxrefs = new ArrayList(); 346 return xt; 347 } 348 349 361 protected int writePdf(PdfWriter w, long startxref) throws IOException { 362 363 xrefGenerateFreeList(); 364 365 DataOutputStream dos = w.getDataOutputStream(); 366 367 String s, t; 368 369 dos.writeBytes("xref\n"); 370 int count = 5; 371 372 int x, xx; 373 x = 0; 374 while (x < size()) { 375 376 if (_usage[x] != ENTRY_UNDEFINED) { 377 378 xx = x + 1; 379 while ( (xx < size()) && (_usage[xx] != ENTRY_UNDEFINED) ) { 380 xx++; 381 } 382 383 s = Integer.toString(x); 384 dos.writeBytes(s); 385 dos.write(' '); 386 t = Integer.toString(xx - x); 387 dos.writeBytes(t); 388 dos.write('\n'); 389 count += s.length() + t.length() + 2; 390 391 while (x < xx) { 392 s = Long.toString(_index[x]); 394 int y = s.length(); 395 for (int z = y; z < 10; z++) { 396 dos.write('0'); 397 } 398 dos.writeBytes(s); 399 dos.write(' '); 400 s = Integer.toString(_generation[x]); 402 y = s.length(); 403 for (int z = y; z < 5; z++) { 404 dos.write('0'); 405 } 406 dos.writeBytes(s); 407 dos.write(' '); 408 if (_usage[x] == ENTRY_IN_USE) { 409 dos.write('n'); 410 } else { 411 dos.write('f'); 412 } 413 dos.writeBytes(" \n"); 414 count += 20; 415 x++; 416 } 417 } 418 x++; 419 } 420 421 dos.writeBytes("trailer\n"); 422 count += 8; 423 424 count += _trailer.writePdf(w, false); 425 426 s = "\nstartxref\n" + Long.toString(startxref) + "\n%%EOF\n"; 427 dos.writeBytes(s); 428 return count + s.length(); 429 } 430 431 435 protected void xrefGenerateFreeList() { 436 int lastFree = 0; 437 long[] index = _index; 438 byte[] usage = _usage; 439 for (int x = usage.length - 1; x >= 0; x--) { 440 if (usage[x] == ENTRY_FREE) { 441 index[x] = lastFree; 442 lastFree = x; 443 } 444 } 445 } 446 447 } 448 | Popular Tags |