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