Package totalcross.io

Class PDBFile

  • All Implemented Interfaces:
    java.io.Closeable, java.lang.AutoCloseable
    Direct Known Subclasses:
    HighScores, ObjectPDBFile

    public class PDBFile
    extends Stream
    PDBFile is a collection of records commonly referred to as a database on small devices.

    Here is an example showing data being read from records in a PDBFile:

     try
     {
        PDBFile pdbFile = new PDBFile("MyPDBFile.CRTR.TYPE", PDBFile.READ_WRITE);
        DataStream ds = new DataStream(pdbFile);
        int count = pdbFile.getRecordCount();
        for (int i = 0; i < count; i++)
        {
           pdbFile.setRecordPos(i);
           String name = ds.readString();
           double salary = ds.readDouble();
           // ...
        }
        pdbFile.close();
        pdbFile = null; // just make sure we won't use it again.
     }
     // since the exceptions are being treated the same way, we could just catch the IOException instead,
     // but for the purpose of this example, we'll treat them individually.
     catch (IllegalArgumentIOException e)
     {
        MessageBox.showException(e, false);
     }
     catch (FileNotFoundException e)
     {
        MessageBox.showException(e, false);
     }
     catch (IOException e)
     {
        MessageBox.showException(e, false);
     }
     

    Note: a PDBFile cannot be opened twice. You must close one instance before opening the other or share the same instance.

    In Windows, you can specify the path of the pdb file, either absolute ("\\My Documents\\Test") or relative ("..\\..\\Test"). Note that the Settings.dataPath, if set, is also used as the path to the PDBFile.

    • Field Summary

      Fields 
      Modifier and Type Field Description
      static int CREATE
      Non-destructive create open mode.
      static int CREATE_EMPTY
      Destructive-create open mode.
      static int DB_ATTR_APPINFODIRTY
      Set if Application Info block is dirty.
      static int DB_ATTR_BACKUP
      Set if database should be backed up to PC if no app-specific synchronization conduit has been supplied.
      static int DB_ATTR_COPY_PREVENTION
      This database should not be copied to
      static int DB_ATTR_OK_TO_INSTALL_NEWER
      This tells the backup conduit that it's OK for it to install a newer version of this database with a different name if the current database is open.
      static int DB_ATTR_READ_ONLY
      Read Only database
      static int DB_ATTR_RESET_AFTER_INSTALL
      Device requires a reset after this database is installed.
      static int DB_ATTR_STREAM
      This database is used for file stream implementation.
      static int READ_WRITE
      Read-write open mode.
      static byte REC_ATTR_DELETE
      Record atribute: Deleted.
      static byte REC_ATTR_DIRTY
      Record atribute: Dirty (has been modified since last sync)
      static byte REC_ATTR_SECRET
      Record atribute: Private
      static byte REC_RELEASE
      Use this in order to explicitly release a record through the setRecordAttributes method.
    • Constructor Summary

      Constructors 
      Constructor Description
      PDBFile​(java.lang.String name, int mode)
      Opens a PDBFile with the given name and mode.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void addRecord​(int size)
      Adds a record to the end of the PDBFile.
      void addRecord​(int size, int pos)
      Insert a record to the given position of the PDBFile.
      void close()
      Closes the PDBFile.
      void delete()
      Delete and close the PDBFile.
      void deleteRecord()
      Deletes the current record and sets the current record position to -1.
      protected void finalize()  
      int getAttributes()
      Retrieves this PDBFile's attributes.
      java.lang.String getName()
      Returns the name passed on the constructor.
      byte getRecordAttributes​(int recordPos)
      Retrieves the attributes of the given record.
      int getRecordCount()
      Returns the number of records in the PDBFile.
      int getRecordOffset()
      Returns the internal record offset used to read and write data.
      int getRecordPos()
      Returns the current record position or -1 if there is no current record.
      int getRecordSize()
      Returns the size of the current record in bytes.
      int inspectRecord​(byte[] buf, int recordPos, int offsetInRec)
      Inspects a record, even if its locked.
      static java.lang.String[] listPDBs()
      Returns the complete list of existing PDBFiles.
      static java.lang.String[] listPDBs​(int creatorIdWild, int typeWild)
      Returns the list of existing PDBFiles with the given creator id and/or type.
      int readBytes​(byte[] buf, int start, int count)
      Reads bytes from the current record into a byte array.
      void rename​(java.lang.String newName)
      Renames the currently open PDBFile to the given name.
      void resizeRecord​(int size)
      Resizes a record.
      int searchBytes​(byte[] toSearch, int length, int offsetInRec)
      Searches the underlying PDBFile for the given byte array.
      void setAttributes​(int i)
      Sets this PDBFile's attributes.
      void setRecordAttributes​(int recordPos, byte attr)
      Sets the attributes of the given record.
      void setRecordOffset​(int ofs)
      Set the cursor on the given position.
      void setRecordPos​(int pos)
      Sets the current record position and locks the given record.
      int skipBytes​(int count)
      Changes the internal read/write cursor of the current record in a number of bytes.
      int writeBytes​(byte[] buf, int start, int count)
      Writes to the current record.
      • Methods inherited from class java.lang.Object

        clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • CREATE

        public static final int CREATE
        Non-destructive create open mode. If the database doesn't exist, it is created and stays in READ_WRITE mode. Otherwise, if it does exists, it is not erased; it just stays in READ_WRITE mode.
        See Also:
        PDBFile(String, int), Constant Field Values
      • CREATE_EMPTY

        public static final int CREATE_EMPTY
        Destructive-create open mode. If the file exists, it is deleted, then a new file is created, and the mode is changed to READ_WRITE.
        See Also:
        PDBFile(String, int), Constant Field Values
      • DB_ATTR_APPINFODIRTY

        public static final int DB_ATTR_APPINFODIRTY
        Set if Application Info block is dirty. Optionally supported by an App's conduit
        See Also:
        setAttributes(int), Constant Field Values
      • DB_ATTR_BACKUP

        public static final int DB_ATTR_BACKUP
        Set if database should be backed up to PC if no app-specific synchronization conduit has been supplied.
        See Also:
        setAttributes(int), Constant Field Values
      • DB_ATTR_OK_TO_INSTALL_NEWER

        public static final int DB_ATTR_OK_TO_INSTALL_NEWER
        This tells the backup conduit that it's OK for it to install a newer version of this database with a different name if the current database is open. This mechanism is used to update the Graffiti Shortcuts database, for example.
        See Also:
        setAttributes(int), Constant Field Values
      • REC_RELEASE

        public static final byte REC_RELEASE
        Use this in order to explicitly release a record through the setRecordAttributes method. This is a hack for a bug in the NVFS of Palm OS 5.4.9, which does not release locked records during the boot (reset). You can use the following code in order to clear the locked records:
         int n = cat.getRecordCount();
         for (int i =0; i < n; i++)
         {
            cat.setRecordPos(i))
            cat.setRecordAttributes(i,REC_RELEASE);
         }
         
        Note that this code assume that the PDBFile was NOT being used previously and that there are no records being used. You must also close the PDBFile after and open it again. Ignoring these restrictions will likely reset the device.
        Since:
        SuperWaba 5.66
        See Also:
        setRecordAttributes(int, byte), Constant Field Values
    • Constructor Detail

      • PDBFile

        public PDBFile​(java.lang.String name,
                       int mode)
                throws IllegalArgumentIOException,
                       FileNotFoundException,
                       IOException
        Opens a PDBFile with the given name and mode.

        A PalmOS creator id and type must be specified by appending a 4 character creator id and 4 character type to the name separated by periods. For example:

         PDBFile c = new PDBFile("MyPDBFile.CRTR.TYPE", PDBFile.CREATE);
         
        Will create a PalmOS database with the name "MyPDBFile", creator id of "CRTR" and type of "TYPE".

        The name of the PDBFile must be 31 characters or less, not including the creator id and type. Every time the database is modified the backup attribute is set.

        Note that some file types are blocked from opening on Palm OS. These types are appl, psys and rsrc ones, and also the resource databases. Hacking the system to allow it to access these files may simply reboot the device.

        Parameters:
        name - PDBFile name, allowing only letters, digits and '_'. Must contain the creator id and type.
        mode - one of READ_WRITE, CREATE, CREATE_EMPTY.
        Throws:
        IllegalArgumentIOException
        FileNotFoundException
        IOException
        See Also:
        READ_WRITE, CREATE, CREATE_EMPTY
    • Method Detail

      • getName

        public java.lang.String getName()
        Returns the name passed on the constructor.
        Since:
        SuperWaba 5.5
      • rename

        public final void rename​(java.lang.String newName)
                          throws IllegalArgumentIOException,
                                 IOException
        Renames the currently open PDBFile to the given name. The name must be in the form "MyNewPDBFileName.CRTR.TYPE". Note: in desktop only, the old file may remain if its deletion is not possible (in other words, in desktop the rename operation may work like a "copy oldName newName").

        Here is an example of use:

         PDBFile c = new PDBFile("guich.Crtr.Type", PDBFile.READ_WRITE);
         c.rename("flor.CrTr.TyPe");
         
        Throws:
        IOException
        IllegalArgumentIOException
      • addRecord

        public final void addRecord​(int size,
                                    int pos)
                             throws IllegalArgumentIOException,
                                    IOException
        Insert a record to the given position of the PDBFile.

        Historic notes: this was the first change implemented by Guich in Waba in 06/30/2000.

        Parameters:
        size - The size in bytes of the record to add
        pos - The position where to add the record. You can specify getRecordCount() to add it to the end. Cannot be lower than 0.
        Throws:
        IOException - If the operation could not be completed.
        IllegalArgumentIOException - If size or pos have invalid values.
      • resizeRecord

        public final void resizeRecord​(int size)
                                throws IllegalArgumentIOException,
                                       IOException
        Resizes a record. This method changes the size (in bytes) of the current record, which is specified using setRecordPos. The contents of the existing record are preserved if the new size is larger than the existing size. If the new size is less than the existing size, the contents of the record are also preserved but truncated to the new size.
        Parameters:
        size - the new size of the record
        Throws:
        IOException - When the method fails.
        IllegalArgumentIOException
      • close

        public void close()
                   throws IOException
        Closes the PDBFile. If you don't close the PDBFile, it will be closed when it gets garbage collected. Note that in desktop the PDBFile is written to disk only after it is closed; during the program's execution, it is held in main memory.
        Specified by:
        close in interface java.lang.AutoCloseable
        Specified by:
        close in interface java.io.Closeable
        Throws:
        IOException - If the PDBFile was already closed.
      • delete

        public final void delete()
                          throws IOException
        Delete and close the PDBFile.
        Throws:
        IOException - When the method fails.
      • listPDBs

        public static java.lang.String[] listPDBs()
        Returns the complete list of existing PDBFiles. If no PDBFiles exist, this method returns null. In the desktop, it searches in the already opened files and also the pdb files in the current "." folder or at Settings.dataPath folder, if it was set.
        Returns:
        A String array with the names
      • listPDBs

        public static final java.lang.String[] listPDBs​(int creatorIdWild,
                                                        int typeWild)
        Returns the list of existing PDBFiles with the given creator id and/or type. If no PDBFiles exist, this method returns null. In the desktop, it searches in the already opened files and also the pdb files in the current "." directory. To convert the four characters of a creator id or type into an int, use, you can use the function Convert.chars2int.
        Parameters:
        creatorIdWild - The creator id wild card, or 0 to recover all types
        typeWild - The type wild card, or 0 to recover all types
        Returns:
        A String array with the names or null if no matches were found.
        Since:
        SuperWaba 3.3
        See Also:
        Convert.chars2int(String)
      • deleteRecord

        public final void deleteRecord()
                                throws IOException
        Deletes the current record and sets the current record position to -1. The record is immediately removed from the PDBFile and all subsequent records are moved up one position.
        Throws:
        IOException - When the method fails.
      • getRecordCount

        public final int getRecordCount()
                                 throws IOException
        Returns the number of records in the PDBFile.
        Throws:
        IOException - If the PDBFile is not open.
      • getRecordSize

        public final int getRecordSize()
                                throws IOException
        Returns the size of the current record in bytes.
        Throws:
        IOException - When the method fails.
      • setRecordPos

        public final void setRecordPos​(int pos)
                                throws IllegalArgumentIOException,
                                       IOException
        Sets the current record position and locks the given record. The value -1 can be passed to unset and unlock the current record. If the operation is succesful, the read/write cursor is set to the beggining of the given record.
        Parameters:
        pos - Record to be locked for use. Must be between 0 and the current number of records, or -1.
        Throws:
        IllegalArgumentIOException - If the argument pos has an invalid value.
        IOException - If the method fails
      • readBytes

        public final int readBytes​(byte[] buf,
                                   int start,
                                   int count)
                            throws IOException
        Reads bytes from the current record into a byte array. Returns the number of bytes actually read or -1 if an error prevented the read operation from occurring. After the read is complete, the location of the cursor in the current record (where read and write operations start from) is advanced by the number of bytes read.
        Specified by:
        readBytes in class Stream
        Parameters:
        buf - the byte array to read data into
        start - the start position in the buf array
        count - the number of bytes to read
        Returns:
        The number of bytes read
        Throws:
        IOException - If you request more bytes than available or if the PDBFile is closed.
      • skipBytes

        public int skipBytes​(int count)
                      throws IllegalArgumentIOException,
                             IOException
        Changes the internal read/write cursor of the current record in a number of bytes. It can be negative but cannot underflow neither overflow the record's size.
        Overrides:
        skipBytes in class Stream
        Parameters:
        count - the number of bytes to skip.
        Returns:
        the actual number of bytes skipped.
        Throws:
        IOException - if the stream does not support skip, or if some other I/O error occurs.
        IllegalArgumentIOException
      • setRecordOffset

        public void setRecordOffset​(int ofs)
                             throws IllegalArgumentIOException,
                                    IOException
        Set the cursor on the given position. This is equivalent to skipBytes(-getRecordOffset()+ofs). If the offset is already this one, nothing is changed.
        Parameters:
        ofs - The new read/write cursor offset value.
        Throws:
        IllegalArgumentIOException
        IOException
        Since:
        SuperWaba 5.5
      • writeBytes

        public final int writeBytes​(byte[] buf,
                                    int start,
                                    int count)
                             throws IOException
        Writes to the current record. After the write is complete, the location of the cursor in the current record (where read and write operations start from) is advanced by the number of bytes written.
        Specified by:
        writeBytes in class Stream
        Parameters:
        buf - the byte array to write data from
        start - the start position in the byte array
        count - the number of bytes to write
        Returns:
        The number of bytes written.
        Throws:
        IOException
      • inspectRecord

        public final int inspectRecord​(byte[] buf,
                                       int recordPos,
                                       int offsetInRec)
                                throws IllegalArgumentIOException,
                                       IOException
        Inspects a record, even if its locked. The cursor is not advanced, neither the current record position. This method can be used to load a locked record. The number of bytes read will be buf.length or the record's size, which is smaller.
        Parameters:
        buf - The buffer where the data will be read into.
        recordPos - The record to be read
        offsetInRec - The offset in the record from where to start reading.
        Returns:
        the number of bytes read, which can be different of buf.length if buf.length is greater than the record size.
        Throws:
        IOException - When the method fails.
        IllegalArgumentIOException
        Since:
        SuperWaba 1.1
      • getRecordPos

        public final int getRecordPos()
                               throws IOException
        Returns the current record position or -1 if there is no current record.
        Throws:
        IOException - If the PDBFile is closed
      • getRecordOffset

        public int getRecordOffset()
                            throws IOException
        Returns the internal record offset used to read and write data. You may use this value in conjunction with the skipBytes method. Note that setRecordPos resets the offset to 0.
        Throws:
        IOException
        Since:
        SuperWaba 4.0
      • searchBytes

        public final int searchBytes​(byte[] toSearch,
                                     int length,
                                     int offsetInRec)
                              throws IllegalArgumentIOException,
                                     IOException
        Searches the underlying PDBFile for the given byte array. Note that its not possible to search using case insensitive, due to the obvious reason that the byte array may not represent a String.
        Parameters:
        toSearch - The byte array used to compare with the contents of each record.
        length - How many bytes will be searched inside toSearch (may be smaller than oSearch.length)
        offsetInRec - How many bytes to skip from the record start.
        Returns:
        the record index if found, or -1 if toSearch is null, or the PDBFile is null or closed or empty, or length <= 0, or length > toSearch.length.
        Throws:
        IOException - If the method fails
        IllegalArgumentIOException
      • finalize

        protected void finalize()
        Overrides:
        finalize in class java.lang.Object