summaryrefslogtreecommitdiff
path: root/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm
diff options
context:
space:
mode:
Diffstat (limited to 'xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm')
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java472
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java180
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java236
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java199
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java165
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java108
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java219
-rw-r--r--xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/package.html146
8 files changed, 1725 insertions, 0 deletions
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java
new file mode 100644
index 000000000000..00f0f91a1691
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDB.java
@@ -0,0 +1,472 @@
+/*************************************************************************
+ *
+ * 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: PalmDB.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+/**
+ * <p>This class contains data for a single Palm database for use during
+ * a conversion process.</p>
+ *
+ * <p>It contains zero or more <code>Record</code> objects stored in an
+ * array. The index of the <code>Record</code> object in the array is
+ * the <code>Record</code> id or number for that specific <code>Record</code> object.
+ * Note that this class does not check for maximum number of Records
+ * allowable in an actual PDB.</p>
+ *
+ * <p>This class also contains the PDB name associated with the Palm
+ * database it represents. A PDB name consists of 32 bytes of a
+ * certain encoding (extended ASCII in this case).</p>
+ *
+ * <p>The non default constructors take in a name parameter which may not
+ * be the exact PDB name to be used. The name parameter in
+ * <code>String</code> or <code>byte</code> array are converted to an exact
+ * <code>NAME_LENGTH</code> byte array. If the length of the name is less
+ * than <code>NAME_LENGTH</code>, it is padded with '\0' characters. If it
+ * is more, it gets truncated. The last character in the resulting byte
+ * array is always a '\0' character. The resulting byte array is stored in
+ * <code>bName</code>, and a corresponding String object <code>sName</code>
+ * that contains characters without the '\0' characters.</p>
+ *
+ * <p>The {@link #write write} method is called within the
+ * {@link org.openoffice.xmerge.converter.palm.PalmDocument#write
+ * PalmDocument.write} method for writing out its data to the <code>OutputStream</code>
+ * object.</p>
+ *
+ * <p>The {@link #read read} method is called within the
+ * {@link org.openoffice.xmerge.converter.palm.PalmDocument#read
+ * PalmDocument.read} method for reading in its data from the <code>InputStream</code>
+ * object.</p>
+ *
+ * @author Akhil Arora, Herbie Ong
+ * @see PalmDocument
+ * @see Record
+ */
+
+public final class PalmDB {
+
+ /* Backup attribute for a PDB. This corresponds to dmHdrAttrBackup. */
+ public final static short PDB_HEADER_ATTR_BACKUP = 0x0008;
+
+ /** Number of bytes for the name field in the PDB. */
+ public final static int NAME_LENGTH = 32;
+
+ /** List of <code>Record</code> objects. */
+ private Record[] records;
+
+ /** PDB name in bytes. */
+ private byte[] bName = null;
+
+ /** PDB name in String. */
+ private String sName = null;
+
+ /** Creator ID. */
+ private int creatorID = 0;
+
+ /** Type ID */
+ private int typeID = 0;
+
+ /**
+ * PDB version. Palm UInt16.
+ * It is treated as a number here, since there is no unsigned 16 bit
+ * in Java, int is used instead, but only 2 bytes are written out or
+ * read in.
+ */
+ private int version = 0;
+
+ /**
+ * PDB attribute - flags for the database.
+ * Palm UInt16. Unsignedness should be irrelevant.
+ */
+ private short attribute = 0;
+
+
+ /**
+ * Default constructor.
+ *
+ * @param creatorID The PDB Creator ID.
+ * @param typeID The PDB Type ID.
+ * @param version The PDB header version.
+ * @param attribute The PDB header attribute.
+ */
+ public PalmDB(int creatorID, int typeID, int version, short attribute) {
+
+ records = new Record[0];
+ setAttributes(creatorID, typeID, version, attribute);
+ }
+
+
+ /**
+ * Constructor to create <code>PalmDB</code> object with
+ * <code>Record</code> objects. <code>recs.length</code>
+ * can be zero for an empty PDB.
+ *
+ * @param name Suggested PDB name in a <code>String</code>.
+ * @param creatorID The PDB Creator ID.
+ * @param typeID The PDB Type ID.
+ * @param version The PDB header version.
+ * @param attribute The PDB header attribute.
+ * @param recs Array of <code>Record</code> objects.
+ *
+ * @throws UnsupportedEncodingException If <code>name</code> is
+ * not properly encoded.
+ * @throws NullPointerException If <code>recs</code> is null.
+ */
+ public PalmDB(String name, int creatorID, int typeID, int version,
+ short attribute, Record[] recs)
+ throws UnsupportedEncodingException {
+
+ this(name.getBytes(PdbUtil.ENCODING), creatorID, typeID, version,
+ attribute, recs);
+ }
+
+
+ /**
+ * Constructor to create object with <code>Record</code>
+ * objects. <code>recs.length</code> can be zero for an
+ * empty PDB.
+ *
+ * @param name Suggested PDB name in a <code>byte</code>
+ * array.
+ * @param creatorID The PDB Creator ID.
+ * @param typeID The PDB Type ID.
+ * @param version The PDB header version.
+ * @param attribute The PDB header attribute.
+ * @param recs Array of <code>Record</code> objects.
+ *
+ * @throws UnsupportedEncodingException If <code>name</code> is
+ * not properly encoded.
+ * @throws NullPointerException If recs is null.
+ */
+ public PalmDB(byte[] name, int creatorID, int typeID, int version,
+ short attribute, Record[] recs) throws UnsupportedEncodingException {
+
+ store(name);
+
+ records = new Record[recs.length];
+ System.arraycopy(recs, 0, records, 0, recs.length);
+ setAttributes(creatorID, typeID, version, attribute);
+ }
+
+
+ /**
+ * Set the attributes for the <code>PalmDB</code> object.
+ *
+ * @param creatorID The PDB Creator ID.
+ * @param typeID The PDB Type ID.
+ * @param version The PDB header version.
+ * @param attribute The PDB header attribute.
+ */
+ public void setAttributes (int creatorID, int typeID, int version, short attribute) {
+ this.creatorID = creatorID;
+ this.typeID = typeID;
+ this.version = version;
+ this.attribute = attribute;
+ }
+
+
+ /**
+ * This private method is mainly used by the constructors above.
+ * to store bytes into name and also create a <code>String</code>
+ * representation. and also by the <code>read</code> method.
+ *
+ * TODO: Note that this method assumes that the <code>byte</code>
+ * array parameter contains one character per <code>byte</code>,
+ * else it would truncate improperly.
+ *
+ * @param bytes PDB name in <code>byte</code> array.
+ *
+ * @throws UnsupportedEncodingException If ENCODING is
+ * not supported.
+ */
+ private void store(byte[] bytes) throws UnsupportedEncodingException {
+
+ // note that this will initialize all bytes in name to 0.
+ bName = new byte[NAME_LENGTH];
+
+ // determine minimum length to copy over from bytes to bName.
+ // Note that the last byte in bName has to be '\0'.
+
+ int lastIndex = NAME_LENGTH - 1;
+
+ int len = (bytes.length < lastIndex)? bytes.length: lastIndex;
+
+ int i;
+
+ for (i = 0; i < len; i++) {
+
+ if (bytes[i] == 0) {
+ break;
+ }
+
+ bName[i] = bytes[i];
+ }
+
+ // set sName, no need to include the '\0' character.
+ sName = new String(bName, 0, i, PdbUtil.ENCODING);
+ }
+
+
+ /**
+ * Returns creator ID.
+ *
+ * @return The creator ID.
+ */
+ public int getCreatorID() {
+
+ return creatorID;
+ }
+
+
+ /**
+ * Returns type ID.
+ *
+ * @return The type ID.
+ */
+ public int getTypeID() {
+
+ return typeID;
+ }
+
+
+ /**
+ * Returns attribute flag.
+ *
+ * @return The attribute flag.
+ */
+ public short getAttribute() {
+
+ return attribute;
+ }
+
+
+ /**
+ * Returns version.
+ *
+ * @return The version.
+ */
+ public int getVersion() {
+
+ return version;
+ }
+
+
+ /**
+ * Return the number of Records contained in this
+ * PDB <code>PalmDB</code> object.
+ *
+ * @return Number of <code>Record</code> objects.
+ */
+ public int getRecordCount() {
+
+ return records.length;
+ }
+
+
+ /**
+ * Return the specific <code>Record</code> object associated
+ * with the <code>Record</code> number.
+ *
+ * @param index <code>Record</code> index number.
+ *
+ * @return The <code>Record</code> object in the specified index
+ *
+ * @throws ArrayIndexOutOfBoundsException If index is out of bounds.
+ */
+ public Record getRecord(int index) {
+
+ return records[index];
+ }
+
+
+ /**
+ * Return the list of <code>Record</code> objects.
+ *
+ * @return The array of <code>Record</code> objects.
+ */
+ public Record[] getRecords() {
+
+ return records;
+ }
+
+ /**
+ * Return the PDB name associated with this object.
+ *
+ * @return The PDB name.
+ */
+ public String getPDBNameString() {
+
+ return sName;
+ }
+
+
+ /**
+ * Return the PDB name associated with this object in
+ * <code>byte</code> array of exact length of 32 bytes.
+ *
+ * @return The PDB name in <code>byte</code> array of
+ * length 32.
+ */
+ public byte[] getPDBNameBytes() {
+
+ return bName;
+ }
+
+
+ /**
+ * Write out the number of Records followed by what
+ * will be written out by each <code>Record</code> object.
+ *
+ * @param os The <code>OutputStream</code> to write the
+ * object.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void write(OutputStream os) throws IOException {
+
+ DataOutputStream out = new DataOutputStream(os);
+
+ // write out PDB name
+ out.write(bName);
+
+ // write out 2 bytes for number of records
+ out.writeShort(records.length);
+
+ // let each Record object write out its own info.
+ for (int i = 0; i < records.length; i++)
+ records[i].write(out);
+ }
+
+ /**
+ * Read the necessary data to create a PDB from
+ * the <code>InputStream</code>.
+ *
+ * @param is The <code>InputStream</code> to read data
+ * in order to restore the object.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void read(InputStream is) throws IOException {
+
+ DataInputStream in = new DataInputStream(is);
+
+ // read in the PDB name.
+ byte[] bytes = new byte[NAME_LENGTH];
+ in.readFully(bytes);
+ store(bytes);
+
+ // read in number of records
+ int nrec = in.readUnsignedShort();
+ records = new Record[nrec];
+
+ // read in the Record infos
+ for (int i = 0; i < nrec; i++) {
+
+ records[i] = new Record();
+ records[i].read(in);
+ }
+ }
+
+ /**
+ * Override equals method of <code>Object</code>.
+ *
+ * Two <code>PalmDB</code> objects are equal if they contain
+ * the same information, i.e. PDB name and Records.
+ *
+ * This is used primarily for testing purposes only for now.
+ *
+ * @param obj A <code>PalmDB</code> <code>Object</code> to
+ * compare.
+ *
+ * @return true if <code>obj</code> is equal to this, otherwise
+ * false.
+ */
+ public boolean equals(Object obj) {
+
+ boolean bool = false;
+
+ if (obj instanceof PalmDB) {
+
+ PalmDB pdb = (PalmDB) obj;
+
+ checkLabel: {
+
+ // compare sName
+
+ if (!sName.equals(pdb.sName)) {
+
+ break checkLabel;
+ }
+
+ // compare bName
+
+ if (bName.length != pdb.bName.length) {
+
+ break checkLabel;
+ }
+
+ for (int i = 0; i < bName.length; i++) {
+
+ if (bName[i] != pdb.bName[i]) {
+
+ break checkLabel;
+ }
+ }
+
+ // compare each Record
+
+ if (records.length != pdb.records.length) {
+
+ break checkLabel;
+ }
+
+ for (int i = 0; i < records.length; i++) {
+
+ if (!records[i].equals(pdb.records[i])) {
+
+ break checkLabel;
+ }
+ }
+
+ // all checks done
+ bool = true;
+ }
+ }
+
+ return bool;
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java
new file mode 100644
index 000000000000..f039dab382ee
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PalmDocument.java
@@ -0,0 +1,180 @@
+/*************************************************************************
+ *
+ * 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: PalmDocument.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+import org.openoffice.xmerge.Document;
+
+/**
+ * <p> A <code>PalmDocument</code> is palm implementaion of the
+ * <code>Docuemnt</code> interface.</p>
+ *
+ * <p>This implementation allows the Palm device format to be
+ * read via an <code>InputStream</code> and written via an
+ * <code>OutputStream</code>.</p>
+ *
+ * @author Martin Maher
+ */
+
+public class PalmDocument
+ implements Document {
+
+ /**
+ * The internal representation of a pdb.
+ */
+ private PalmDB pdb;
+
+ /**
+ * The file name.
+ */
+ private String fileName;
+
+ /**
+ * Constructor to create a <code>PalmDocument</code>
+ * from an <code>InputStream</code>.
+ *
+ * @param is <code>InputStream</code> containing a PDB.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public PalmDocument(InputStream is) throws IOException {
+ read(is);
+ }
+
+
+ /**
+ * Constructor to create a <code>PalmDocument</code> with
+ * <code>Record</code> objects. <code>recs.length</code>
+ * can be zero for an empty PDB.
+ *
+ * @param name Suggested PDB name in <code>String</code>.
+ * @param creatorID The PDB Creator ID.
+ * @param typeID The PDB Type ID.
+ * @param version The PDB header version.
+ * @param attribute The PDB header attribute.
+ * @param recs Array of <code>Record</code> objects.
+ *
+ * @throws NullPointerException If <code>recs</code> is null.
+ */
+ public PalmDocument(String name, int creatorID, int typeID, int version,
+ short attribute, Record[] recs)
+ throws UnsupportedEncodingException {
+ pdb = new PalmDB(name, creatorID, typeID, version, attribute, recs);
+ fileName = pdb.getPDBNameString();
+ }
+
+
+ /**
+ * Reads in a file from the <code>InputStream</code>.
+ *
+ * @param is <code>InputStream</code> to read in its content.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+
+ public void read(InputStream is) throws IOException {
+ PdbDecoder decoder = new PdbDecoder();
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte[] buf = new byte[4096];
+ int n = 0;
+ while ((n = is.read(buf)) > 0) {
+ baos.write(buf, 0, n);
+ }
+ byte[] bytearr = baos.toByteArray();
+ pdb = decoder.parse(bytearr);
+ fileName = pdb.getPDBNameString();
+ }
+
+
+ /**
+ * Writes the <code>PalmDocument</code> to an <code>OutputStream</code>.
+ *
+ * @param is The <code>OutputStream</code> to write the content.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void write(OutputStream os) throws IOException {
+ PdbEncoder encoder = new PdbEncoder(pdb);
+ encoder.write(os);
+ }
+
+
+ /**
+ * Returns the <code>PalmDB</code> contained in this object.
+ *
+ * @return The <code>PalmDB</code>.
+ */
+ public PalmDB getPdb() {
+ return pdb;
+ }
+
+
+ /**
+ * Sets the <code>PalmDocument</code> to a new <code>PalmDB</code>
+ * value.
+ *
+ * @param pdb The new <code>PalmDB</code> value.
+ */
+ public void setPdb(PalmDB pdb) {
+ this.pdb = pdb;
+
+ String name = pdb.getPDBNameString();
+ fileName = name;
+ }
+
+
+ /**
+ * Returns the name of the file.
+ *
+ * @return The name of the file represented in the
+ * <code>PalmDocument</code>.
+ */
+ public String getFileName() {
+ return fileName + ".pdb";
+ }
+
+
+ /**
+ * Returns the <code>Document</code> name.
+ *
+ * @return The <code>Document</code> name.
+ */
+ public String getName() {
+ return fileName;
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java
new file mode 100644
index 000000000000..f6df00664b27
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbDecoder.java
@@ -0,0 +1,236 @@
+/*************************************************************************
+ *
+ * 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.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.RandomAccessFile;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+
+/**
+ * <p>Provides functionality to decode a PDB formatted file into
+ * a <code>PalmDB</code> object given an <code>InputStream</code>.
+ * This class is only used by the <code>PalmDB</code> object.</p>
+ *
+ * <p>Sample usage:</p>
+ *
+ * <blockquote><pre><code>
+ * PdbDecoder decoder = new PdbDecoder("sample.pdb");
+ * PalmDB palmDB = decoder.parse();
+ * </code></pre></blockquote>
+ *
+ * <p>This decoder has the following assumptions on the PDB file:</p>
+ *
+ * <p><ol>
+ * <li>There is only one RecordList section in the PDB.</li>
+ * <li>The <code>Record</code> indices in the RecordList are sorted in
+ * order, i.e. the first <code>Record</code> index refers to
+ * <code>Record</code> 0, and so forth.</li>
+ * <li>The raw <code>Record</code> in the <code>Record</code> section
+ * are sorted as well in order, i.e. first <code>Record</code>
+ * comes ahead of second <code>Record</code>, etc.</li>
+ * </ol></p>
+ *
+ * <p>Other decoders assume these as well.</p>
+ *
+ * @author Herbie Ong
+ * @see PalmDB
+ * @see Record
+ */
+public final class PdbDecoder {
+
+
+ /**
+ * <p>This method decodes a PDB file into a <code>PalmDB</code>
+ * object.</p>
+ *
+ * <p>First, the header data is read using the <code>PdbHeader</code>
+ * <code>read</code> method. Next, the RecordList section is
+ * read and the <code>Record</code> offsets are stored for use when
+ * parsing the Records. Based on these offsets, the bytes
+ * corresponding to each <code>Record</code> are read and each is
+ * stored in a <code>Record</code> object. Lastly, the data is
+ * used to create a <code>PalmDB</code> object.</p>
+ *
+ * @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];
+ byte recAttrs[] = new byte[header.numRecords];
+
+ for (int i = 0; i < header.numRecords; i++) {
+
+ recOffset[i] = file.readInt();
+
+ // read in attributes (1 byte) + unique id (3 bytes)
+ // take away the unique id, store the attributes
+
+ int attr = file.readInt();
+ recAttrs[i] = (byte) (attr >>> 24);
+ }
+
+
+ // 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, recAttrs[i]);
+ }
+
+ // last record
+ file.seek(recOffset[lastIndex]);
+ len = (int) file.length() - recOffset[lastIndex];
+ bytes = new byte[len];
+ file.readFully(bytes);
+ recArray[lastIndex] = new Record(bytes, recAttrs[lastIndex]);
+
+ }
+
+ file.close();
+
+ // create PalmDB and return it
+ PalmDB pdb = new PalmDB(header.pdbName, header.creatorID,
+ header.typeID, header.version, header.attribute, recArray);
+
+ return pdb;
+ }
+
+ /**
+ * <p>This method decodes a PDB file into a <code>PalmDB</code>
+ * object.</p>
+ *
+ * <p>First, the header data is read using the <code>PdbHeader</code>
+ * <code>read</code> method. Next, the RecordList section is
+ * read and the <code>Record</code> offsets are stored for use when
+ * parsing the Records. Based on these offsets, the bytes
+ * corresponding to each <code>Record</code> are read and each is
+ * stored in a <code>Record</code> object. Lastly, the data is
+ * used to create a <code>PalmDB</code> object.</p>
+ *
+ * @param b <code>byte[]</code> containing PDB.
+ *
+ * @throws IOException If I/O error occurs.
+ */
+
+ public PalmDB parse(byte[] b) throws IOException {
+
+ ByteArrayInputStream bais = new ByteArrayInputStream(b);
+ DataInputStream dis = new DataInputStream(bais);
+
+ // read the PDB header
+
+ PdbHeader header = new PdbHeader();
+ header.read(dis);
+
+ Record recArray[] = new Record[header.numRecords];
+ if (header.numRecords != 0) {
+
+ // read in the record indices + offsets
+
+ int recOffset[] = new int[header.numRecords];
+ byte recAttrs[] = new byte[header.numRecords];
+
+ for (int i = 0; i < header.numRecords; i++) {
+
+ recOffset[i] = dis.readInt();
+
+ // read in attributes (1 byte) + unique id (3 bytes)
+ // take away the unique id, store the attributes
+
+ int attr = dis.readInt();
+ recAttrs[i] = (byte) (attr >>> 24);
+ }
+
+ // read the records
+
+ int len = 0;
+ byte[] bytes = null;
+
+ int lastIndex = header.numRecords - 1;
+
+ for (int i = 0; i < lastIndex; i++) {
+
+ //dis.seek(recOffset[i]);
+ dis.reset();
+ dis.skip(recOffset[i]);
+ len = recOffset[i+1] - recOffset[i];
+ bytes = new byte[len];
+ dis.readFully(bytes);
+ recArray[i] = new Record(bytes, recAttrs[i]);
+ }
+
+ // last record
+
+ dis.reset();
+ len = (int) dis.available() - recOffset[lastIndex];
+ dis.skip(recOffset[lastIndex]);
+ bytes = new byte[len];
+ dis.readFully(bytes);
+ recArray[lastIndex] = new Record(bytes, recAttrs[lastIndex]);
+ }
+
+
+
+ // create PalmDB and return it
+
+ PalmDB pdb = new PalmDB(header.pdbName, header.creatorID,
+ header.typeID, header.version, header.attribute, recArray);
+
+ return pdb;
+ }
+
+
+
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java
new file mode 100644
index 000000000000..2081290ccf47
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbEncoder.java
@@ -0,0 +1,199 @@
+/*************************************************************************
+ *
+ * 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: PdbEncoder.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.OutputStream;
+import java.io.BufferedOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * <p>Provides functionality to encode a <code>PalmDB</code> object
+ * into a PDB formatted file given a file <code>OutputStream</code>.
+ * This class is only used by the <code>PalmDB</code> object.</p>
+ *
+ * <p>One needs to create one <code>PdbEncoder</code> object per
+ * <code>PalmDB</code> object to be encoded. This class keeps
+ * the PDB header data and functionality in the <code>PdbHeader</code>
+ * class.</p>
+ *
+ * <p>Sample usage:</p>
+ *
+ * <blockquote><pre><code>
+ * PdbEncoder encoder = new PdbEncoder(palmDB, "STRW", "data");
+ * encoder.write(new FileOutputStream("sample.pdb"));
+ * </code></pre></blockquote>
+ *
+ * @author Herbie Ong
+ * @see PalmDB
+ * @see Record
+ */
+public final class PdbEncoder {
+
+ /** PDB header. */
+ private PdbHeader header = null;
+
+ /** the PalmDB object. */
+ private PalmDB db = null;
+
+ /**
+ * The pattern for unique_id=0x00BABE(start).
+ */
+ private final static int START_UNIQUE_ID = 0x00BABE;
+
+
+ /**
+ * Constructor.
+ *
+ * @param db The <code>PalmDB</code> to be encoded.
+ */
+ public PdbEncoder(PalmDB db) {
+
+ header = new PdbHeader();
+ header.version = db.getVersion();
+
+ header.attribute = db.getAttribute();
+
+ this.db = db;
+
+ header.pdbName = db.getPDBNameBytes();
+ header.creatorID = db.getCreatorID();
+ header.typeID = db.getTypeID();
+
+ // set the following dates to current date
+ Date date = new Date();
+ header.creationDate = (date.getTime() / 1000) + PdbUtil.TIME_DIFF;
+ header.modificationDate = header.creationDate;
+
+ header.numRecords = db.getRecordCount();
+ }
+
+
+ /**
+ * <p>Write out a PDB into the given <code>OutputStream</code>.</p>
+ *
+ * <p>First, write out the header data by using the
+ * <code>PdbHeader</code> <code>write</code> method. Next,
+ * calculate the RecordList section and write it out.
+ * Lastly, write out the bytes corresponding to each
+ * <code>Record</code>.</p>
+ *
+ * <p>The RecordList section contains a list of
+ * <code>Record</code> index info, where each <code>Record</code>
+ * index info contains:</p>
+ *
+ * <p><ul>
+ * <li>4 bytes local offset of the <code>Record</code> from the
+ * top of the PDB.</li>
+ * <li>1 byte of <code>Record</code> attribute.</li>
+ * <li>3 bytes unique <code>Record</code> ID.</li>
+ * </ul></p>
+ *
+ * <p>There should be a total of <code>header.numRecords</code>
+ * of <code>Record</code> index info</p>.
+ *
+ * @param os <code>OutputStream</code> to write out PDB.
+ *
+ * @throws IOException If I/O error occurs.
+ */
+ public void write(OutputStream os) throws IOException {
+
+ BufferedOutputStream bos = new BufferedOutputStream(os);
+ DataOutputStream dos = new DataOutputStream(bos);
+
+ // write out the PDB header
+ header.write(dos);
+
+ if (header.numRecords > 0) {
+
+ // compute for recOffset[]
+
+ int recOffset[] = new int[header.numRecords];
+ byte recAttr[] = new byte[header.numRecords];
+
+ // first recOffset will be at PdbUtil.HEADER_SIZE + all the
+ // record indices (@ 8 bytes each)
+ recOffset[0] = PdbUtil.HEADER_SIZE + (header.numRecords * 8);
+
+ int lastIndex = header.numRecords - 1;
+
+ for (int i = 0; i < lastIndex; i++) {
+
+ Record rec = db.getRecord(i);
+ int size = rec.getSize();
+ recAttr[i] = rec.getAttributes();
+
+ recOffset[i+1] = recOffset[i] + size;
+ }
+
+ // grab the last record's attribute.
+
+ Record lastRec = db.getRecord(lastIndex);
+ recAttr[lastIndex] = lastRec.getAttributes();
+
+
+ int uid = START_UNIQUE_ID;
+
+ for (int i = 0; i < header.numRecords; i++) {
+
+ // write out each record offset
+ dos.writeInt(recOffset[i]);
+
+ // write out record attribute (recAttr) and
+ // unique ID (uid) in 4 bytes (int) chunk.
+ // unique ID's have to be unique, thus
+ // increment each time.
+ int attr = (((int) recAttr[i]) << 24 );
+ attr |= uid;
+ dos.writeInt(attr);
+ uid++;
+ }
+
+ // write out the raw records
+
+ for (int i = 0; i < header.numRecords; i++) {
+
+ Record rec = db.getRecord(i);
+ byte bytes[] = rec.getBytes();
+ dos.write(bytes);
+ }
+
+ } else {
+
+ // placeholder bytes if there are no records in the list.
+ dos.writeShort(0);
+ }
+
+ dos.flush();
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java
new file mode 100644
index 000000000000..c79acf6d20bb
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbHeader.java
@@ -0,0 +1,165 @@
+/*************************************************************************
+ *
+ * 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: PdbHeader.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * <p>Class used only internally by <code>PdbEncoder</code> and
+ * <code>PdbDecoder</code> to store, read and write a PDB header.</p>
+ *
+ * <p>Note that fields are intended to be accessible only at the
+ * package level.</p>
+ *
+ * <p>Some of the fields are internally represented using a
+ * larger type since Java does not have unsigned types.
+ * Some are not since they are not relevant for now.
+ * The <code>read</code> and <code>write</code> methods should
+ * handle them properly.</p>
+ *
+ * @author Herbie Ong
+ * @see PalmDB
+ * @see Record
+ */
+final class PdbHeader {
+
+
+ /** Name of the database. 32 bytes. */
+ byte[] pdbName = null;
+
+ /**
+ * Flags for the database. Palm UInt16. Unsignedness should be
+ * irrelevant.
+ */
+ short attribute = 0;
+
+ /** Application-specific version for the database. Palm UInt16. */
+ int version = 0;
+
+ /** Date created. Palm UInt32. */
+ long creationDate = 0;
+
+ /** Date last modified. Palm UInt32. */
+ long modificationDate = 0;
+
+ /** Date last backup. Palm UInt32. */
+ long lastBackupDate = 0;
+
+ /**
+ * Incremented every time a <code>Record</code> is
+ * added, deleted or modified. Palm UInt32.
+ */
+ long modificationNumber = 0;
+
+ /** Optional field. Palm UInt32. Unsignedness should be irrelevant. */
+ int appInfoID = 0;
+
+ /** Optional field. Palm UInt32. Unsignedness should be irrelevant. */
+ int sortInfoID = 0;
+
+ /** Database type ID. Palm UInt32. Unsignedness should be irrelevant. */
+ int typeID = 0;
+
+ /** Database creator ID. Palm UInt32. Unsignedness should be irrelevant. */
+ int creatorID = 0;
+
+ /** ??? */
+ int uniqueIDSeed = 0;
+
+ /** See numRecords. 4 bytes. */
+ int nextRecordListID = 0;
+
+ /**
+ * Number of Records stored in the database header.
+ * If all the <code>Record</code> entries cannot fit in the header,
+ * then <code>nextRecordList</code> has the local ID of a
+ * RecordList that contains the next set of <code>Record</code>.
+ * Palm UInt16.
+ */
+ int numRecords = 0;
+
+
+ /**
+ * Read in the data for the PDB header. Need to
+ * preserve the unsigned value for some of the fields.
+ *
+ * @param di A <code>DataInput</code> object.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void read(DataInput in) throws IOException {
+
+ pdbName = new byte[PalmDB.NAME_LENGTH];
+ in.readFully(pdbName);
+ attribute = in.readShort();
+ version = in.readUnsignedShort();
+ creationDate = ((long) in.readInt()) & 0xffffffffL;
+ modificationDate = ((long) in.readInt()) & 0xffffffffL;
+ lastBackupDate = ((long) in.readInt()) & 0xffffffffL;
+ modificationNumber = ((long) in.readInt()) & 0xffffffffL;
+ appInfoID = in.readInt();
+ sortInfoID = in.readInt();
+ creatorID = in.readInt();
+ typeID = in.readInt();
+ uniqueIDSeed = in.readInt();
+ nextRecordListID = in.readInt();
+ numRecords = in.readUnsignedShort();
+ }
+
+
+ /**
+ * Write out PDB header data.
+ *
+ * @param out A <code>DataOutput</code> object.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void write(DataOutput out) throws IOException {
+
+ out.write(pdbName);
+ out.writeShort(attribute);
+ out.writeShort(version);
+ out.writeInt((int) creationDate);
+ out.writeInt((int) modificationDate);
+ out.writeInt((int) lastBackupDate);
+ out.writeInt((int) modificationNumber);
+ out.writeInt(appInfoID);
+ out.writeInt(sortInfoID);
+ out.writeInt(typeID);
+ out.writeInt(creatorID);
+ out.writeInt(uniqueIDSeed);
+ out.writeInt(nextRecordListID);
+ out.writeShort(numRecords);
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java
new file mode 100644
index 000000000000..cb50b9d7cb76
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/PdbUtil.java
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * 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: PdbUtil.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+/**
+ * Contains common static methods and constants for use within the package.
+ *
+ * @author Herbie Ong
+ */
+public final class PdbUtil {
+
+ /** Difference in seconds from Jan 01, 1904 to Jan 01, 1970. */
+ final static long TIME_DIFF = 2082844800;
+
+ /** Encoding scheme used. */
+ final static String ENCODING = "8859_1";
+
+ /** Size of a PDB header in bytes. */
+ final static int HEADER_SIZE = 78;
+
+
+ /**
+ * <p>This method converts a 4 letter string into the Palm ID
+ * integer.</p>
+ *
+ * <p>It is normally used to convert the Palm creator ID string into
+ * the integer version of it. Also use for data types, etc.</p>
+ *
+ * @param s Four character <code>String</code>.
+ *
+ * @return Palm ID representing the <code>String</code>.
+ *
+ * @throws ArrayIndexOutOfBoundsException If <code>String</code>
+ * parameter contains less than four characters.
+ */
+ public static int intID(String s) {
+
+ int id = -1;
+ int temp = 0;
+
+ // grab the first char and put it in the high bits
+ // note that we only want 8 lower bits of it.
+ temp = (int) s.charAt(0);
+ id = temp << 24;
+
+ // grab the second char and add it in.
+ temp = ((int) s.charAt(1)) & 0x00ff;
+ id += temp << 16;
+
+ // grab the second char and add it in.
+ temp = ((int) s.charAt(2)) & 0x00ff;
+ id += temp << 8;
+
+ // grab the last char and add it in
+ id += ((int) s.charAt(3)) & 0x00ff;
+
+ return id;
+ }
+
+
+ /**
+ * This method converts an integer into a <code>String</code>
+ * given the Palm ID format.
+ *
+ * @param i Palm ID.
+ *
+ * @return <code>String</code> representation.
+ */
+ public static String stringID(int i) {
+
+ char ch[] = new char[4];
+ ch[0] = (char) (i >>> 24);
+ ch[1] = (char) ((i >> 16) & 0x00ff);
+ ch[2] = (char) ((i >> 8) & 0x00ff);
+ ch[3] = (char) (i & 0x00ff);
+
+ return new String(ch);
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java
new file mode 100644
index 000000000000..6475fdbc9537
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/Record.java
@@ -0,0 +1,219 @@
+/*************************************************************************
+ *
+ * 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: Record.java,v $
+ * $Revision: 1.4 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+package org.openoffice.xmerge.converter.palm;
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+/**
+ * <p>Contains the raw bytes for a <code>Record</code> in a PDB.</p>
+ *
+ * <p>Note that it is not associated with a <code>Record</code> number
+ * or ID.</p>
+ *
+ * @author Akhil Arora, Herbie Ong
+ * @see PalmDocument
+ * @see PalmDB
+ */
+public final class Record {
+
+ /** <code>Record</code> <code>byte</code> array. */
+ private byte[] data;
+
+ /** <code>Record</code> attributes. */
+ private byte attributes = 0;
+
+
+ /**
+ * Default constructor.
+ */
+ public Record() {
+
+ data = new byte[0];
+ }
+
+
+ /**
+ * <p>Constructor to create a <code>Record</code> filled with
+ * bytes.</p>
+ *
+ * <p>Note that this does not check for 64k <code>Record</code>
+ * sizes. User of this class must check for that.</p>
+ *
+ * @param d <code>byte</code> array contents for this object.
+ */
+ public Record(byte[] d) {
+
+ this(d, (byte) 0);
+ }
+
+
+ /**
+ * <p>Constructor to create a <code>Record</code> filled with
+ * bytes and assign <code>Record</code> attributes.</p>
+ *
+ * <p>Note that this does not check for 64k <code>Record</code>
+ * sizes. User of this class must check for that.</p>
+ *
+ * @param d <code>byte</code> array contents for this object.
+ * @param attrs <code>Record</code> attributes.
+ */
+ public Record(byte[] d, byte attrs) {
+
+ data = new byte[d.length];
+ attributes = attrs;
+ System.arraycopy(d, 0, data, 0, d.length);
+ }
+
+
+ /**
+ * This method returns the number of bytes in this object.
+ *
+ * @return Number of bytes in this object.
+ */
+ public int getSize() {
+
+ return data.length;
+ }
+
+
+ /**
+ * This method returns the contents of this <code>Object</code>.
+ *
+ * @return Contents in <code>byte</code> array
+ */
+ public byte[] getBytes() {
+
+ return data;
+ }
+
+
+ /**
+ * <p>This method returns the <code>Record</code> attributes.</p>
+ *
+ * <blockquote><pre>
+ * <code>Record</code> attributes consists of (from high to low bit)
+ *
+ * delete (1) - dirty (1) - busy (1) - secret (1) - category (4)
+ * </pre></blockquote>
+ *
+ * @return <code>Record</code> attribute.
+ */
+ public byte getAttributes() {
+
+ return attributes;
+ }
+
+
+ /**
+ * Write out the <code>Record</code> attributes and
+ * <code>Record</code> length followed by the data in this
+ * <code>Record</code> object.
+ *
+ * @param out The <code>OutputStream</code> to write the object.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void write(OutputStream outs) throws IOException {
+
+ DataOutputStream out = new DataOutputStream(outs);
+ out.writeByte(attributes);
+ out.writeShort(data.length);
+ out.write(data);
+ }
+
+
+ /**
+ * Read the necessary data to create a PDB from
+ * the <code>InputStream</code>.
+ *
+ * @param in The <code>InputStream</code> to read data from
+ * in order to restore the <code>object</code>.
+ *
+ * @throws IOException If any I/O error occurs.
+ */
+ public void read(InputStream ins) throws IOException {
+
+ DataInputStream in = new DataInputStream(ins);
+ attributes = in.readByte();
+ int len = in.readUnsignedShort();
+ data = new byte[len];
+ in.readFully(data);
+ }
+
+
+ /**
+ * <p>Override equals method of <code>Object</code>.</p>
+ *
+ * <p>Two <code>Record</code> objects are equal if they contain
+ * the same bytes in the array and the same attributes.</p>
+ *
+ * <p>This is used primarily for testing purposes only for now.</p>
+ *
+ * @param obj A <code>Record</code> object to compare with
+ *
+ * @return true if obj is equal, otherwise false.
+ */
+ public boolean equals(Object obj) {
+
+ boolean bool = false;
+
+ if (obj instanceof Record) {
+
+ Record rec = (Record) obj;
+
+ checkLabel: {
+
+ if (rec.getAttributes() != attributes) {
+
+ break checkLabel;
+ }
+
+ if (rec.getSize() == data.length) {
+
+ for (int i = 0; i < data.length; i++) {
+
+ if (data[i] != rec.data[i]) {
+ break checkLabel;
+ }
+ }
+
+ bool = true;
+ }
+ }
+ }
+ return bool;
+ }
+}
+
diff --git a/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/package.html b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/package.html
new file mode 100644
index 000000000000..8f5159b23d6d
--- /dev/null
+++ b/xmerge/source/xmerge/java/org/openoffice/xmerge/converter/palm/package.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<!--
+ #*************************************************************************
+ #
+ 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: package.html,v $
+
+ $Revision: 1.4 $
+
+ 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.
+
+ #*************************************************************************
+ -->
+<html>
+<head>
+<title>org.openoffice.xmerge.converter.palm package</title>
+</head>
+
+<body bgcolor="white">
+
+<p>Provides classes for converting Palm database data to/from a
+<code>PalmDocument</code> object, which can be used by the framework.
+
+<p>This package provides classes that handle the writing of data to
+an <code>OutputStream</code> object for the
+{@link org.openoffice.xmerge.DocumentSerializer DocumentSerializer}
+interface for; as well as the reading of data from an <code>InputStream</code>
+object for the framework's
+{@link org.openoffice.xmerge.DocumentDeserializer DocumentDeserializer}
+interface. Both these framework interfaces are simply converters from
+server-side documents to device specific documents and vice-versa.
+Since all Palm databases have a general record oriented format, a Palm
+database converter specific I/O stream format is specified for the Palm
+sync client application to handle the byte stream in a generic way.
+This also means that Palm database converters should read and/or write
+using this I/O stream format as specified in the next section.</p>
+
+<a name="streamformat">
+<h2>Palm database converter specific I/O stream format</h2>
+</a>
+
+<p>Note that the format of the byte stream is not exactly that of a PDB
+file encoding. It does not need to contain the PDB header information
+nor record indices section. Instead, it contains the following ...</p>
+
+<pre>
+ set header
+ 4 bytes - creator id
+ 4 bytes - type id
+ 2 bytes - PDB header version
+ 2 bytes - PDB header attribute
+ unsigned 2 bytes - number of PDB data to follow
+
+ for each PDB,
+ 32 bytes - name of PDB i
+ unsigned 2 bytes - number of records in PDB i
+
+ for each record contained in PDB i,
+ 1 byte - record attributes
+ unsigned 2 bytes - size of record j in PDB i
+ x bytes - data
+</pre>
+
+<p>Note that each PDB section is appended by another if there is more
+than one.</p>
+
+<p>Since the <code>PalmDocument</code> class takes care of the writing
+and reading of this format through its <code>write</code> and
+<code>read</code> methods, respectively, this format shall also be
+referred to as the <b>PalmDocument stream format</b>.</p>
+
+<h2>Usage of the classes for the specified I/O stream</h2>
+
+<p>When converting from a server document to device document(s), the
+framework requires writing the device document(s) to an
+<code>OutputStream</code> object via the <code>DocumentSerializer</code>
+interface. Note that a single server document may be converted
+into multiple PDB's on the Palm device. Each worksheet in the document
+is converted into a <code>PalmDocument</code> . Thus, if there is more
+than one worksheet in the document, more than one <code>PalmDocument</code>
+will be produced by the <code>DocumentSerializer</code>.</p>
+
+<p>A <code>DocumentSerializer</code> creates a <code>ConvertData</code> object,
+which contains all of the <code>PalmDocuments</code>. The
+{@link org.openoffice.xmerge.converter.palm.PalmDocument#write write}
+method to write to the given <code>OutputStream</code>. The <code>PalmDocument</code>
+object will take care of writing the data in the
+<a href=#streamformat>specified format</a>.</p>
+
+<p>A <code>DocumentDeserializer</code> can use the <code>PalmDocument</code> object's
+{@link org.openoffice.xmerge.converter.palm.PalmDocument#read read}
+method to fill in all the <code>PalmDocument</code> object's data.</p>
+
+<h2>PDB file encoding/decoding</h2>
+
+<p>The <code>PalmDocument</code> object's read and write functions are provided
+by the <code>PdbDecoder</code> and <code>PdbEncoder</code> objects. The
+<code>PdbEncoder</code> class provides the functionality of encoding a
+<code>PalmDB</code> object into an <code>InputStream</code>, while the
+<code>PdbDecoder</code> class provides the functionality of decoding a
+PDB file into an <code>OutputStream</code>.</p>
+
+<p>Refer to the class description of each for usage.</p>
+
+<h2>Important Note</h2>
+
+<p>Methods in these classes are not thread safe for performance reasons.
+Users of these classes will have to make sure that the usage of these classes
+are done in a proper manner. Possibly more on this later.</p>
+
+<h2>TODO list</h2>
+
+<p><ol>
+<li>Merge the PalmDB, PdbDecoder and PdbEncoder classes into the
+ PalmDocument class.</li>
+<li>After reading more on the palm file format spec, I realized
+ that there are certain optional fields that may need to be addressed
+ still, like the appInfo block and sortInfo block.</li>
+<li>The current PdbDecoder only returns a PalmDB object. There are other
+ information that we may want to expose from the PDB decoding process.</li>
+<li>Investigate on different language encoding on the Palm and how that
+ affects the PDB name.</li>
+</ol></p>
+
+</body>
+</html>