📄 recordstore.java
字号:
if (db.checkOwner() == false && db.dbAuthMode == AUTHMODE_PRIVATE) { db.closeRecordStore(); throw new SecurityException(); } else { return db; } } } /** * Authorization to allow access only to the current MIDlet * suite. AUTHMODE_PRIVATE has a value of 0. */ public final static int AUTHMODE_PRIVATE = 0; /** * Authorization to allow access to any MIDlet * suites. AUTHMODE_ANY has a value of 1. */ public final static int AUTHMODE_ANY = 1; /** * Internal indicator for AUTHMODE_ANY with read only access * AUTHMODE_ANY_RO has a value of 2. */ private final static int AUTHMODE_ANY_RO = 2; /** * Changes the access mode for this RecordStore. The authorization * mode choices are: * * <ul> * <li><code>AUTHMODE_PRIVATE</code> - Only allows the MIDlet * suite that created the RecordStore to access it. This * case behaves identically to * <code>openRecordStore(recordStoreName, * createIfNecessary)</code>.</li> * <li><code>AUTHMODE_ANY</code> - Allows any MIDlet to access the * RecordStore. Note that this makes your recordStore * accessible by any other MIDlet on the device. This * could have privacy and security issues depending on * the data being shared. Please use carefully.</li> * </ul> * * <p>The owning MIDlet suite may always access the RecordStore and * always has access to write and update the store. Only the * owning MIDlet suite can change the mode of a RecordStore.</p> * * @param authmode the mode under which to check or create access. * Must be one of AUTHMODE_PRIVATE or AUTHMODE_ANY. * @param writable true if the RecordStore is to be writable by * other MIDlet suites that are granted access * * @exception RecordStoreException if a record store-related * exception occurred * @exception SecurityException if this MIDlet Suite is not * allowed to change the mode of the RecordStore * @exception IllegalArgumentException if authmode is invalid * @since MIDP 2.0 */ public void setMode(int authmode, boolean writable) throws RecordStoreException { synchronized (rsLock) { if (checkOwner() == false) { throw new SecurityException(); } else if (authmode != AUTHMODE_PRIVATE && authmode != AUTHMODE_ANY) { throw new IllegalArgumentException(); } else { dbAuthMode = authmode; if ((authmode == AUTHMODE_ANY) && (writable == false)) { dbAuthMode = AUTHMODE_ANY_RO; } } // flush record store header here storeDBState(); } } /** * This method is called when the MIDlet requests to have the * record store closed. Note that the record store will not * actually be closed until closeRecordStore() is called as many * times as openRecordStore() was called. In other words, the * MIDlet needs to make a balanced number of close calls as open * calls before the record store is closed. * * <p>When the record store is closed, all listeners are removed * and all RecordEnumerations associated with it become invalid. * If the MIDlet attempts to perform * operations on the RecordStore object after it has been closed, * the methods will throw a RecordStoreNotOpenException. * * @exception RecordStoreNotOpenException if the record store is * not open * @exception RecordStoreException if a different record * store-related exception occurred */ public void closeRecordStore() throws RecordStoreNotOpenException, RecordStoreException { synchronized (rsLock) { synchronized (dbCacheLock) { checkOpen(); /* * Find the record store within the record store cache. * A linear seagrch is OK assuming there won't be many * concurrently open record stores. */ RecordStore db = null; for (int n = 0; n < dbCache.size(); n++) { db = (RecordStore)dbCache.elementAt(n); if (db == this) { db.opencount--; break; } } if (db.opencount <= 0) { // free stuff - final close dbCache.removeElement(db); try { // closing now...no need to listen if (!recordListener.isEmpty()) { recordListener.removeAllElements(); } // close native fd if (dbFirstFreeBlockOffset != 0) { compactRecords(); // compact before close // truncate file to compacted size dbraf.truncate(dbDataEnd); } dbraf.close(); } catch (java.io.IOException ioe) { throw new RecordStoreException("error closing .db " + "file"); } finally { dbraf = null; recHeadCache = null; } } } } } /** * Returns an array of the names of record stores owned by the * MIDlet suite. Note that if the MIDlet suite does not * have any record stores, this function will return null. * * The order of RecordStore names returned is implementation * dependent. * * @return array of the names of record stores owned by the * MIDlet suite. Note that if the MIDlet suite does not * have any record stores, this function will return null. */ public static String[] listRecordStores() { // static calls synchronize on dbCacheLock synchronized (dbCacheLock) { String[] returnstrings = RecordStoreFile.listRecordStores(); return returnstrings; } } /** * Returns the name of this RecordStore. * * @return the name of this RecordStore * * @exception RecordStoreNotOpenException if the record store is not open */ public String getName() throws RecordStoreNotOpenException { checkOpen(); return recordStoreName; } /** * Each time a record store is modified (by * <code>addRecord</code>, <code>setRecord</code>, or * <code>deleteRecord</code> methods) its <em>version</em> is * incremented. This can be used by MIDlets to quickly tell if * anything has been modified. * * The initial version number is implementation dependent. * The increment is a positive integer greater than 0. * The version number increases only when the RecordStore is updated. * * The increment value need not be constant and may vary with each * update. * * @return the current record store version * * @exception RecordStoreNotOpenException if the record store is * not open */ public int getVersion() throws RecordStoreNotOpenException { checkOpen(); return dbVersion; } /** * Returns the number of records currently in the record store. * * @return the number of records currently in the record store * * @exception RecordStoreNotOpenException if the record store is * not open */ public int getNumRecords() throws RecordStoreNotOpenException { checkOpen(); return dbNumLiveRecords; } /** * Returns the amount of space, in bytes, that the record store * occupies. The size returned includes any overhead associated * with the implementation, such as the data structures * used to hold the state of the record store, etc. * * @exception RecordStoreNotOpenException if the record store is * not open * * @return the size of the record store in bytes */ public int getSize() throws RecordStoreNotOpenException { checkOpen(); // return the file size of the record store file return dbDataEnd; } /** * Returns the amount of additional room (in bytes) available for * this record store to grow. Note that this is not necessarily * the amount of extra MIDlet-level data which can be stored, * as implementations may store additional data structures with * each record to support integration with native applications, * synchronization, etc. * * @exception RecordStoreNotOpenException if the record store is * not open * * @return the amount of additional room (in bytes) available for * this record store to grow */ public int getSizeAvailable() throws RecordStoreNotOpenException { checkOpen(); int rv = RecordStoreFile.spaceAvailable() - DB_BLOCK_SIZE - DB_RECORD_HEADER_LENGTH; return (rv < 0) ? 0 : rv; } /** * Returns the last time the record store was modified, in the * format used by System.currentTimeMillis(). * * @return the last time the record store was modified, in the * format used by System.currentTimeMillis() * * @exception RecordStoreNotOpenException if the record store is * not open */ public long getLastModified() throws RecordStoreNotOpenException { checkOpen(); return dbLastModified; } /** * Adds the specified RecordListener. If the specified listener * is already registered, it will not be added a second time. * When a record store is closed, all listeners are removed. * * @param listener the RecordChangedListener * @see #removeRecordListener */ public void addRecordListener(RecordListener listener) { synchronized (rsLock) { if (!recordListener.contains(listener)) { recordListener.addElement(listener); } } } /** * Removes the specified RecordListener. If the specified listener * is not registered, this method does nothing. * * @param listener the RecordChangedListener * @see #addRecordListener */ public void removeRecordListener(RecordListener listener) { synchronized (rsLock) { recordListener.removeElement(listener); } } /** * Returns the recordId of the next record to be added to the * record store. This can be useful for setting up pseudo-relational * relationships. That is, if you have two or more * record stores whose records need to refer to one another, you can * predetermine the recordIds of the records that will be created * in one record store, before populating the fields and allocating * the record in another record store. Note that the recordId returned * is only valid while the record store remains open and until a call * to <code>addRecord()</code>. * * @return the recordId of the next record to be added to the * record store * * @exception RecordStoreNotOpenException if the record store is * not open * @exception RecordStoreException if a different record * store-related exception occurred */ public int getNextRecordID() throws RecordStoreNotOpenException, RecordStoreException { checkOpen(); return dbNextRecordID; } /** * Adds a new record to the record store. The recordId for this * new record is returned. This is a blocking atomic operation. * The record is written to persistent storage before the * method returns. * * @param data the data to be stored in this record. If the record * is to have zero-length data (no data), this parameter may be * null. * @param offset the index into the data buffer of the first * relevant byte for this record * @param numBytes the number of bytes of the data buffer to use * for this record (may be zero) * * @return the recordId for the new record * * @exception RecordStoreNotOpenException if the record store is * not open * @exception RecordStoreException if a different record * store-related exception occurred * @exception RecordStoreFullException if the operation cannot be * completed because the record store has no more room * @exception SecurityException if the MIDlet has read-only access * to the RecordStore */ public int addRecord(byte[] data, int offset, int numBytes) throws RecordStoreNotOpenException, RecordStoreException, RecordStoreFullException { synchronized (rsLock) { checkOpen(); if (!checkWritable()) { throw new SecurityException(); } if ((data == null) && (numBytes > 0)) { throw new NullPointerException("illegal arguments: null " + "data, numBytes > 0"); } // get recordId for new record, update db's dbNextRecordID int id = dbNextRecordID++; /* * Find the offset where this record should be stored and * seek to that location in the file. allocateNewRecordStorage() * allocates the space for this record.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -