1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 25 import java.io.RandomAccessFile; 26 import java.io.IOException; 27 28 29 /** 30 * <p>Provides functionality to decode a pdb formatted file into 31 * a <code>PalmDB</code> object given a file input stream</p> 32 * 33 * <p>Sample usage:</p> 34 * 35 * <p><blockquote><pre> 36 * PDBDecoder decoder = new PDBDecoder("sample.pdb"); 37 * PalmDB palmDB = decoder.parse(); 38 * </pre></blockquote></p> 39 * 40 * <p>Refer to the 41 * <a href="http://starlite.eng/zensync/eng/converters/palmfileformats.pdf"> 42 * Palm file format specification</a> for details on the pdb format.</p> 43 * 44 * <p>This decoder has the following assumptions on the pdb file ...</p> 45 * <ol> 46 * <li><p>There is only one RecordList section in the pdb.</p></li> 47 * <li><p>The record indices in the RecordList are sorted in order, i.e. the 48 * first record index refers to record 0, and so forth.</p></li> 49 * <li><p>The raw records in the record section are sorted as well in order, 50 * i.e. first record comes ahead of second record, etc.</p></li> 51 * </ol> 52 * 53 * Other decoders assume these as well. 54 * 55 * @author Herbie Ong 56 * @see PalmDB 57 * @see PDBHeader 58 * 59 * @author Herbie Ong 60 */ 61 62 public final class PDBDecoder { 63 64 /** 65 * <p>This method decodes a pdb file into a PalmDB object.</p> 66 * 67 * <p>First, read in the header data using <code>PDBHeader</code>'s 68 * <code>read</code> method</p>. Next, read in the record list 69 * section. Store the record offsets for use when parsing the records. 70 * Based on these offsets, read in each record's bytes and store 71 * each in a <code>Record</code> object. Lastly, create a 72 * <code>PalmDB</code> object with the read in <code>Record</code>s. 73 * 74 * @param fileName pdb file name 75 * @throws IOException if I/O error occurs 76 */ 77 parse(String fileName)78 public PalmDB parse(String fileName) throws IOException { 79 80 RandomAccessFile file = new RandomAccessFile(fileName, "r"); 81 82 // read the pdb header 83 PDBHeader header = new PDBHeader(); 84 header.read(file); 85 86 Record recArray[] = new Record[header.numRecords]; 87 88 if (header.numRecords != 0) { 89 90 // read in the record indices + offsets 91 92 int recOffset[] = new int[header.numRecords]; 93 94 for (int i = 0; i < header.numRecords; i++) { 95 96 recOffset[i] = file.readInt(); 97 int attr = file.readInt(); // read in attribute. 98 } 99 100 // read the records 101 102 int len = 0; 103 byte[] bytes = null; 104 105 int lastIndex = header.numRecords - 1; 106 107 for (int i = 0; i < lastIndex; i++) { 108 109 file.seek(recOffset[i]); 110 len = recOffset[i+1] - recOffset[i]; 111 bytes = new byte[len]; 112 file.readFully(bytes); 113 recArray[i] = new Record(bytes); 114 } 115 116 // last record 117 file.seek(recOffset[lastIndex]); 118 len = (int) file.length() - recOffset[lastIndex]; 119 bytes = new byte[len]; 120 file.readFully(bytes); 121 recArray[lastIndex] = new Record(bytes); 122 } 123 124 file.close(); 125 126 // create PalmDB and return it 127 PalmDB pdb = new PalmDB(header.pdbName, recArray); 128 return pdb; 129 } 130 } 131 132