/********************************************************************************* * TotalCross Software Development Kit * * Copyright (C) 2001 Rob Nielsen * * Copyright (C) 2001-2012 SuperWaba Ltda. * * All Rights Reserved * * * * This library and virtual machine 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. * * * * This file is covered by the GNU LESSER GENERAL PUBLIC LICENSE VERSION 3.0 * * A copy of this license is located in file license.txt at the root of this * * SDK or can be downloaded here: * * http://www.gnu.org/licenses/lgpl-3.0.txt * * * *********************************************************************************/ package totalcross.pim.palm.builtin; import totalcross.io.DataStream; import totalcross.io.ObjectPDBFile; import totalcross.io.PDBFile; import totalcross.io.Storable; /** * Provides a link to the standard Palm Mail database.. * * @author <A HREF="mailto:tines@ravnaandtines.com">Mr. Tines</A>, * @version 1.1.0 17 June 2001 */ public class Mail implements Storable { // record attributes for category as per PDBFile /** Indicates a message for the In box */ public static final int REC_ATTR_INBOX = 0x0; /** Indicates a message for the Out box */ public static final int REC_ATTR_OUTBOX = 0x1; /** Indicates a message for the Deleted category */ public static final int REC_ATTR_DELETED = 0x2; /** Indicates a message that has been filed */ public static final int REC_ATTR_FILED = 0x3; /** Indicates a message that has been saved as draft */ public static final int REC_ATTR_DRAFT = 0x4; private static final int READ = 1 << 7; private static final int SIGNATURE = 1 << 6; private static final int CONFIRM_READ = 1 << 5; private static final int CONFIRM_DELIVERY = 1 << 4; private static final int PRIORITY = 3 << 2; /** Indicates a high priority message */ public static final int PRIORITY_HIGH = 0; /** Indicates a normal priority message */ public static final int PRIORITY_NORMAL = 1; /** Indicates a low priority message */ public static final int PRIORITY_LOW = 2; private static final int PRIORITY_SHIFT = 2; private static final int ADDRESSING = 3; // no addressing values reverse engineered /** the mail PDBFile */ private static ObjectPDBFile mailCat; public static void initMail() throws totalcross.io.IOException { if (mailCat == null) mailCat = new ObjectPDBFile("MailDB.mail.DATA"); } /** * Gets the number of mails in the database * * @return the number of mails */ public static int mailCount() { return mailCat.getRecordCount(); } /** * Gets a Mail from the database * * @param i * the index to get * @return the retrieved mail */ public static Mail getMail(int i) { Mail mail = new Mail(); if (mailCat.loadObjectAt(mail, i)) return mail; return null; } /** * Gets a Mail from the database and places it into the given Mail. Any * previous data in the mail is erased. * * @param i * the index to get * @param mail * the mail object to place the mail into. */ public static boolean getMail(int i, Mail mail) { return mailCat.loadObjectAt(mail, i); } /** * Adds a new Mail to the database * * @param mail * the Mail to add * @return true if successful, false otherwise */ public static boolean addMail(Mail mail) { return addMail(mail, REC_ATTR_OUTBOX); } /** * Adds a new Mail to the database * * @param mail * the Mail to add * @param category * The mail folder REC_ATTR_* category to set. Defaults to OUTBOX * if invalid * @return true if successful, false otherwise */ public static boolean addMail(Mail mail, int category) { if (!mailCat.addObject(mail)) return false; int where = mailCount(); byte cat = mailCat.getRecordAttributes(where - 1); if (category < REC_ATTR_INBOX || category > REC_ATTR_DRAFT) category = REC_ATTR_OUTBOX; byte cat2 = (byte) ((cat & 0xF0) | (category & 0xF)); if (cat2 != cat) cat2 |= PDBFile.REC_ATTR_DIRTY; mailCat.setRecordAttributes(where - 1, cat2); return true; } // *************************** // // individual mail stuff below // // *************************** // /** Has this message been read */ public boolean read; /** Is there a .sig attached */ public boolean signature; /** Confirm read? */ public boolean confirmRead; /** Confirm Delivery? */ public boolean confirmDelivery; /** priority value 0-3 */ public byte priority = PRIORITY_NORMAL; /** addressing value 0-3 */ public byte addressing; /** Is there a date? */ public boolean dated; /** the date if any */ public totalcross.sys.Time date; /** the subject of the mail */ public String subject; /** the sender of the mail */ public String from; /** the recipient of the mail */ public String to; /** the cc list */ public String cc; /** the bcc list */ public String bcc; /** the author of the mail's preferred address */ public String replyTo; /** the actual recipient of the mail */ public String sentTo; /** the text */ public String body; /** * Constructs a new empty address */ public Mail() { } /** * Send the state information of this object to the given object PDBFile * using the given DataStream. If any Storable objects need to be saved as * part of the state, their saveState() method can be called too. * @throws totalcross.io.IOException */ public void saveState(DataStream ds) throws totalcross.io.IOException { // The date (if any) int d = 0; if (dated) { d = (date.year - 1904) << 9; d |= date.month << 5; d |= date.day; } ds.writeShort(d); int hold = dated ? date.hour : 0; ds.writeByte(hold); hold = dated ? date.minute : 0; ds.writeByte(hold); // flags hold = 0; if (read) hold |= READ; if (signature) hold |= SIGNATURE; if (confirmRead) hold |= CONFIRM_READ; if (confirmDelivery) hold |= CONFIRM_DELIVERY; // sanity check if (priority < PRIORITY_HIGH || priority > PRIORITY_LOW) priority = PRIORITY_NORMAL; hold |= ((priority << PRIORITY_SHIFT) & PRIORITY); //no known non-zero addressing value //hold |= (addressing & ADDRESSING); ds.writeByte(hold); ds.writeByte(0); // data ds.writeCString(subject); ds.writeCString(from); ds.writeCString(to); ds.writeCString(cc); ds.writeCString(bcc); ds.writeCString(replyTo); ds.writeCString(sentTo); ds.writeCString(body); } /** * Load state information from the given DataStream into this object If any * Storable objects need to be loaded as part of the state, their loadState() * method can be called too. * * @throws totalcross.io.IOException */ public void loadState(DataStream ds) throws totalcross.io.IOException { // The date (if any) int d = ds.readUnsignedShort(); if (d != 0) { dated = true; date = new totalcross.sys.Time(); date.year = (d >> 9) + 1904; date.month = (d >> 5) & 15; date.day = d & 31; } byte hold = ds.readByte(); if (dated) date.hour = hold; hold = ds.readByte(); if (dated) { date.minute = hold; date.second = 0; date.millis = 0; } // flags hold = ds.readByte(); read = (hold & READ) != 0; signature = (hold & SIGNATURE) != 0; confirmRead = (hold & CONFIRM_READ) != 0; confirmDelivery = (hold & CONFIRM_DELIVERY) != 0; priority = (byte) ((hold & PRIORITY) >> PRIORITY_SHIFT); addressing = (byte) (hold & ADDRESSING); hold = ds.readByte(); // data subject = ds.readCString(); from = ds.readCString(); to = ds.readCString(); cc = ds.readCString(); bcc = ds.readCString(); replyTo = ds.readCString(); sentTo = ds.readCString(); body = ds.readCString(); } /** * Gets a unique ID for this class. It is up to the user to ensure that the * ID of each class of Storable contained in a single ObjectPDBFile is unique * and the ID of each instance in a class is the same. */ public byte getID() { return 0; // not used } /** * Returns an object of the same class as this object. * * @return a class. Any data is irrelevent. */ public Storable getInstance() { return new Mail(); } }