summaryrefslogtreecommitdiff
path: root/xmerge/java/org/openoffice/xmerge/converter/palm/palmtests/qa/comparator/PDBDecoder.java
blob: 417d886cecea0e6d0b26f8d8e0da6e032137006c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: PDBDecoder.java,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/


import java.io.RandomAccessFile;
import java.io.IOException;


/**
 *  <p>Provides functionality to decode a pdb formatted file into
 *  a <code>PalmDB</code> object given a file input stream</p>
 *
 *  <p>Sample usage:</p>
 *
 *  <p><blockquote><pre>
 *     PDBDecoder decoder = new PDBDecoder("sample.pdb");
 *     PalmDB palmDB = decoder.parse();
 *  </pre></blockquote></p>
 *
 *  <p>Refer to the
 *  <a href="http://starlite.eng/zensync/eng/converters/palmfileformats.pdf">
 *  Palm file format specification</a> for details on the pdb format.</p>
 *
 *  <p>This decoder has the following assumptions on the pdb file ...</p>
 *  <ol>
 *  <li><p>There is only one RecordList section in the pdb.</p></li>
 *  <li><p>The record indices in the RecordList are sorted in order, i.e. the
 *      first record index refers to record 0, and so forth.</p></li>
 *  <li><p>The raw records in the record section are sorted as well in order,
 *      i.e. first record comes ahead of second record, etc.</p></li>
 *  </ol>
 *
 *  Other decoders assume these as well.
 *
 *  @author    Herbie Ong
 *  @see    PalmDB
 *  @see    PDBHeader
 *
 *  @author    Herbie Ong
 */

public final class PDBDecoder {

    /**
     *  <p>This method decodes a pdb file into a PalmDB object.</p>
     *
     *  <p>First, read in the header data using <code>PDBHeader</code>'s
     *  <code>read</code> method</p>.  Next, read in the record list
     *  section.  Store the record offsets for use when parsing the records.
     *  Based on these offsets, read in each record's bytes and store
     *  each in a <code>Record</code> object.  Lastly, create a
     *  <code>PalmDB</code> object with the read in <code>Record</code>s.
     *
     *  @param   fileName    pdb file name
     *  @throws   IOException    if I/O error occurs
     */

    public PalmDB parse(String fileName) throws IOException {

        RandomAccessFile file = new RandomAccessFile(fileName, "r");

        // read the pdb header
        PDBHeader header = new PDBHeader();
        header.read(file);

        Record recArray[] = new Record[header.numRecords];

        if (header.numRecords != 0) {

            // read in the record indices + offsets

            int recOffset[] = new int[header.numRecords];

            for (int i = 0; i < header.numRecords; i++) {

                recOffset[i] = file.readInt();
                int attr = file.readInt();    // read in attribute.
            }

            // read the records

            int len = 0;
            byte[] bytes = null;

            int lastIndex = header.numRecords - 1;

            for (int i = 0; i < lastIndex; i++) {

                file.seek(recOffset[i]);
                len = recOffset[i+1] - recOffset[i];
                bytes = new byte[len];
                file.readFully(bytes);
                recArray[i] = new Record(bytes);
            }

            // last record
            file.seek(recOffset[lastIndex]);
            len = (int) file.length() - recOffset[lastIndex];
            bytes = new byte[len];
            file.readFully(bytes);
            recArray[lastIndex] = new Record(bytes);
        }

        file.close();

        // create PalmDB and return it
        PalmDB pdb = new PalmDB(header.pdbName, recArray);
        return pdb;
    }
}