//5.1.1  Record Storeķ
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordStoreTest extends MIDlet {
  public RecordStoreTest(){}
  public void startApp()throws MIDletStateChangeException {
    RecordStore rs=null;
    try {
      rs =RecordStore.openRecordStore("file1 ",true);
      System.out.println("Record Store file1 is opened.");
    }catch(Exception e){
    System.out.println("Error:"+e.getMessage());
    }finally{
    //close the Record Store
    try {
      rs.closeRecordStore();
      System.out.println("Record Store file1 is closed ");
    }catch (Exception e){
      System.out.println("Error:"+e.getMessage());
    }
  }
  destroyApp(true);
  notifyDestroyed();
  }
  public void pauseApp(){}
  public void destroyApp(boolean unconditional){}
}


//5.2.1  Ӽ¼
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordAdd extends MIDlet {
  public RecordAdd(){}
  public void startApp()throws MIDletStateChangeException{
    RecordStore rs=null;
    try{
      rs =RecordStore.openRecordStore("file1",true);  // RecordStore
      byte data []=new byte [4 ];
      for(int j=0;j<2;j++){
        int i=rs.getNextRecordID();   // ȡRecordID
        data [0 ] = (byte)((i >>24)&0xff);
        data [1 ] = (byte)((i >>16)&0xff);
        data [2 ] = (byte)((i >>8)&0xff);
        data [3 ] = (byte)(i &0xff);
        System.out.println("record"+rs.addRecord(data,0,4)+"is added..");
      }
     }catch(Exception e){}
     finally{
     // رRecordStore
     try {
       rs.closeRecordStore();
     }catch (Exception e){}
   }
   destroyApp(true);
   notifyDestroyed();
 }
  public void pauseApp(){}
  public void destroyApp(boolean unconditional){}
}


//5.2.2  ɾ¼
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordDel extends MIDlet{
  public RecordDel(){}
  public void startApp()throws MIDletStateChangeException {
    RecordStore rs=null;
    try {
      rs =RecordStore.openRecordStore("file1 ",true);  // RecordStore
      byte data []=new byte [4 ];
      for(int j=0;j<2;j++){
        int i=rs.getNextRecordID();
        data [0 ] =(byte)((i >>24)&0xff);
        data [1 ] =(byte)((i >>16)&0xff);
        data [2 ] =(byte)((i >>8)&0xff);
        data [3 ] =(byte)(i &0xff);
        System.out.println("record"+rs.addRecord(data,0,4)+"is added..");
      }
    try {
      rs.deleteRecord(2);  // ɾһ¼
      System.out.println("record 2 is deleted.");
    }catch(InvalidRecordIDException e){
    System.out.println("record 2 does not exist ");
  }
  }catch(Exception e){}
  finally{
    // رRecordStore
    try {
      rs.closeRecordStore();
    }catch (Exception e){}
  }
  destroyApp(true);
  notifyDestroyed();
}
public void pauseApp(){}
public void destroyApp(boolean unconditional){}
}


//5.2.3  ޸һ¼
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class TestStore extends MIDlet {
    static final String DBNAME = "mydata";
    public TestStore() {
        RecordStore rs = null;
        // ɾɵRecordStore
        try {
            RecordStore.deleteRecordStore( DBNAME );
        }
        catch( Exception e ){
            // ԳֵĴ
        }
        // һµRecordStoreȻе
        try {
            rs = RecordStore.openRecordStore( DBNAME, true );
            byte[] data1 = "Here is the first record".getBytes();
            byte[] data2 = "And here is the second".getBytes();
            byte[] data3 = "And then the third".getBytes();
            data3[0] = 0;
            data3[data3.length-1] = (byte) -1;
            rs.addRecord( data1, 0, data1.length );  // Ӽ¼
            rs.addRecord( data2, 0, data2.length );
            rs.addRecord( data3, 0, data3.length );
            dumpRecordStore( rs, System.out );  // RecordStore
            rs.closeRecordStore();
        }
        catch( RecordStoreException e ){
            System.out.println( e );
        }

        destroyApp(true);
        notifyDestroyed();
    }

    public void dumpRecordStore( RecordStore rs, PrintStream out ){
        if( rs == null ) return;
        StringBuffer hexLine = new StringBuffer();
        StringBuffer charLine = new StringBuffer();
        try {
            int    lastID = rs.getNextRecordID();
            byte[] data = new byte[100];
            byte[] newdata = new byte[100];
            int    size;

            // ¼¼
            out.println( "Update every record...");
            for( int i = 1; i < lastID; ++i ){
                try {
                    size = rs.getRecordSize( i );
                    if( size > data.length ){
                        data = new byte[ size * 2 ];
                    }

                    out.println( "Record " + i + " of size " + size );
                    rs.getRecord( i, data, 0 );
                    dumpRecord( data, size, out, hexLine, charLine, 16 );
                    out.println( "" );

                    // µǰ¼
                    newdata = "Update a Record...".getBytes();
                    rs.setRecord( i, newdata, 0, newdata.length);
                    rs.getRecord( i, data, 0 );                    
                    dumpRecord( data, size, out, hexLine, charLine, 16 );
                    out.println( "" );
                }
                catch( InvalidRecordIDException e ){
                    continue;
                }
            }
        }
        catch( RecordStoreException e ){
            out.println( "Exception reading record store: " + e );
        }
    } 
    private void dumpRecord( byte[] data, int size,
                             PrintStream out,
                             StringBuffer hexLine,
                             StringBuffer charLine,
                             int maxLen )
    {
        if( size == 0 ) return;

        hexLine.setLength( 0 );  // ԤóΪ0
        charLine.setLength( 0 );

        int count = 0;

        for( int i = 0; i < size; ++i ){
            char b = (char) ( data[i] & 0xFF );

            if( b < 0x10 ){
                hexLine.append( '0' );
            }

            hexLine.append( Integer.toHexString( b ) );
            hexLine.append( ' ' );

            if( ( b >= 32 && b <= 127 ) ||   // жַ
                Character.isDigit( b ) ||
                Character.isLowerCase( b ) ||
                Character.isUpperCase( b ) ){
                charLine.append( (char) b );
            } else {
                charLine.append( '.' );
            }

            if( ++count >= maxLen || i == size-1 ){
                while( count++ < maxLen ){
                hexLine.append( "   " );
                }

                hexLine.append( ' ' );
                hexLine.append( charLine.toString() );

                out.println( hexLine.toString() );  // Ļ
  
                hexLine.setLength( 0 );
                charLine.setLength( 0 );
                count = 0;
            }
        }
    }

    public void destroyApp( boolean unconditional ) {}
    public void startApp() {}
    public void pauseApp() {}
}


//5.2.4  Ӽ¼ĸı
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordListenerExample extends MIDlet implements RecordListener{
  RecordStore rs1=null;
  RecordStore rs2=null;
  public RecordListenerExample(){}
  public void startApp()throws MIDletStateChangeException {
    // Record Stores
    try {
      rs1 =RecordStore.openRecordStore("test1 ",true);
      rs1.addRecordListener(this);
    }catch(Exception e){}
    try {
      rs2 =RecordStore.openRecordStore("test2 ",true);
    }catch(Exception e){}
    // rs1¼
    byte data []=new byte [4 ];
    for(int j=0;j<2;j++){
      try {
        int i=rs1.getNextRecordID();
        data [0 ] = (byte)((i >>24)&0xff);
        data [1 ] = (byte)((i >>16)&0xff);
        data [2 ] = (byte)((i >>8)&0xff);
        data [3 ] = (byte)(i &0xff);
        System.out.println("record #"+rs1.addRecord(data,0,4)+" is added to Record Store 1 ");
      }catch (Exception e){}
    }
    // ޸ļ¼
    try {
      int id=rs1.getNextRecordID()-2;
      data=rs1.getRecord(id);
      data [0 ]+=1;
      rs1.setRecord(id,data,0,4);
      System.out.println("record #"+id+" of Record Store 1 is modified..");
    }catch(Exception e){}
    // ɾļ¼
    try {
      int id=rs1.getNextRecordID()-1;
      rs1.deleteRecord(id);
      System.out.println("record #"+id+" of Record Store 1 is deleted..");
    }catch (Exception e){}
    // 
    destroyApp(true);
    notifyDestroyed();
  }
  public void pauseApp(){}
  public void destroyApp(boolean unconditional){
  
  //رRecordStores
  try {
    if(rs1!=null)rs1.closeRecordStore();
  }catch(Exception e){}
  try {
    if(rs2!=null)rs2.closeRecordStore();
  }catch (Exception e){}
}
// ʵRecordListener
public void recordAdded(RecordStore rs,int rid){
  if(rs==rs1){
  try {
    byte data []=rs.getRecord(rid);
    int id=rs2.addRecord(data,0,data.length);
    System.out.println("record #"+id+" is added to Record Store 2..");
  }catch(Exception e){}
  }
}
public void recordChanged(RecordStore rs,int rid){
  if(rs==rs1){
    try {
      byte data []=rs.getRecord(rid);
      rs2.setRecord(rid,data,0,data.length);
      System.out.println("record #"+rid+" of Record Store 2 is modified..");
      // ʾ¼޸
    }catch(Exception e){}
  }
}

public void recordDeleted(RecordStore rs,int rid){
  if(rs==rs1){
    try {
      rs2.deleteRecord(rid);
      System.out.println("record #"+rid+" of Record Store 2 is deleted..");
    }catch(Exception e){}
  }
}
}



//5.2.6  ʹRecordEnumeration¼
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordStoreList extends MIDlet {
  public RecordStoreList(){}
  public void startApp()throws MIDletStateChangeException {
    RecordStore rs=null;
    RecordEnumeration re=null;
    try {
      rs =RecordStore.openRecordStore("file1",true); // RecordStore
      byte data [];
       re=rs.enumerateRecords((RecordFilter)null,(RecordComparator)null,false);
      System.out.println(re.numRecords()+" records are in the Record Store..");
      System.out.println("records with even recordIds:");  // ¼
      for(int i=1;i<=re.numRecords();i++){
        try{
          int j=re.nextRecordId();
          if(j%2==0){  // ¼idΪż
          data=rs.getRecord(j);
          System.out.println("record "+j+" is retrieved..");
        }
        }catch (Exception e){}
      } 
     System.out.println("records with odd recordIds:");
     /*ڼ¼ָָݿһ¼
       ʹresetƵһ¼
     */
     re.reset();
     while(re.hasNextElement()){
       try{
         int j=re.nextRecordId();
         if(j%2==1){ // ¼
           data=rs.getRecord(j);
           System.out.println("record "+j+" is retrieved..");
         }
       }catch (Exception e){}
      }
    }catch(Exception e){}
    finally{
    // ͷrecord enumerator
    try {
       re.destroy();
    }catch(Exception e){}
    // رRecordStore
    try {
      rs.closeRecordStore();
    }catch (Exception e){}
  }
  destroyApp(true);
  notifyDestroyed();
  }
  public void pauseApp(){}
  public void destroyApp(boolean unconditional){}
}



//5.4.2  ݿ
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

public class RecordSort extends MIDlet{
  private RecordStore rs = null;
  static final String REC_STORE = "db_1";
 
  public RecordSort(){
    openRecStore();   // RecordStore
    
    // дµļ¼
    writeRecord("Chinese");
    writeRecord("SiChuan");
    writeRecord("ChengDu");    
    writeRecord("BeiJing");        
 
    // ʹenumeratorдļ¼
    readRecords();
    
    closeRecStore();  // رRecordStore
    deleteRecStore();  //ɾRecordStore
  }
 
  public void destroyApp( boolean unconditional ){}
 
  public void startApp(){
    destroyApp(false);
    notifyDestroyed();
  }
 
  public void pauseApp(){}
 
  public void openRecStore(){
    try{
      // RecordStoreڣʹµ
      rs = RecordStore.openRecordStore(REC_STORE, true );
    }catch (Exception e){
      db(e.toString());
    }
  }    
  
  public void closeRecStore(){
    try{
      rs.closeRecordStore();
    }catch (Exception e){
      db(e.toString());
    }
  }
 
 // ɾRecordStores
  public void deleteRecStore(){
    if (RecordStore.listRecordStores() != null){
      try{
        RecordStore.deleteRecordStore(REC_STORE);
      }catch (Exception e){
        db(e.toString());
      }
    }      
  }
  // дRecordStores
  public void writeRecord(String str){
    byte[] rec = str.getBytes();
 
    try{
      rs.addRecord(rec, 0, rec.length);
    }catch (Exception e){
      db(e.toString());
    }
  }
 // ȡRecordStores
  public void readRecords(){
    try{
      if (rs.getNumRecords() > 0){
        Comparator comp = new Comparator();
        
        RecordEnumeration re = rs.enumerateRecords(null, comp, false);
        while (re.hasNextElement()){
          String str = new String(re.nextRecord());
          System.out.println(str);
          System.out.println("------------------------------");                        
        }
      }
    }
    catch (Exception e){
         db(e.toString());
    }
  }
 
  /*--------------------------------------------------
  * ĻԻߴϢ
  *-------------------------------------------------*/
  private void db(String str){
    System.err.println("Msg: " + str);
  }
}
 
/*--------------------------------------------------
| Comparator.java
|
| ¼бȽԾ˳
*-------------------------------------------------*/
class Comparator implements RecordComparator{
  public int compare(byte[] rec1, byte[] rec2){
    String str1 = new String(rec1), str2 = new String(rec2);
    
    int result = str1.compareTo(str2);
    if (result == 0)
      return RecordComparator.EQUIVALENT;
    else if (result < 0)
      return RecordComparator.PRECEDES;
    else
      return RecordComparator.FOLLOWS;          
  }
}


//5.5.2  Ҽ¼
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.lcdui.*;
 
public class RecordSearch extends MIDlet implements CommandListener{
  private Display display;       // Display
  private Form fmMain;        // 
  private StringItem siMatch;    // ƥı
  private Command cmFind;        
  private Command cmExit;        
  private TextField tfFind;      
  private RecordStore rs = null; 
  static final String REC_STORE = "db_2"; // RecordStore
 
  public RecordSearch()  {
    display = Display.getDisplay(this);
    
    // TextField, StringItemCommand
    tfFind = new TextField("Find", "", 10, TextField.ANY); 
    siMatch = new StringItem(null, null);    
    cmExit = new Command("Exit", Command.EXIT, 1);
    cmFind = new Command("Find", Command.SCREEN, 2);
 
    // Form Command
    fmMain = new Form("Record Search");
    fmMain.addCommand(cmExit);    
    fmMain.addCommand(cmFind);
  
    // TextField StringItem
    fmMain.append(tfFind);
    fmMain.append(siMatch);
 
    // ¼
    fmMain.setCommandListener(this);    
 
    //--------------------------------
    // 򿪲дRecordStore
    //--------------------------------    
    openRecStore();   // RecordStore
    writeTestData();
  }
 
  public void destroyApp( boolean unconditional){
    closeRecStore();
  }
 
  public void startApp(){display.setCurrent(fmMain);}
 
  public void pauseApp(){}
 
  public void openRecStore(){
    try{
      // RecordStoreڣʹ
      rs = RecordStore.openRecordStore(REC_STORE, true);
    }catch (Exception e){
      db(e.toString());
    }
  }    
  
  public void closeRecStore(){
    try{
      rs.closeRecordStore();
    }catch (Exception e){
      db(e.toString());
    }
  }
 
  /*--------------------------------------------------
  * дRecordStore
  *-------------------------------------------------*/
  public void writeTestData(){
  String[] golfClubs = {
         "BeiJing...The capital of my matherland", 
         "UESTC...University of Electronical Science and Technology of China", 
       "J2ME is a good sofrware"};    
    writeRecords(golfClubs);
  }
 
  /*--------------------------------------------------
  * дRecordStore
  *-------------------------------------------------*/    
  public void writeRecords(String[] sData){
    byte[] record;
 
    try{
      // Ӽ¼һ
      if (rs.getNumRecords() > 0)
        return;
 
      for (int i = 0; i < sData.length; i++){
        record = sData[i].getBytes();
        rs.addRecord(record, 0, record.length);
      }
    }catch (Exception e){
      db(e.toString());
    }
  }
 
  /*--------------------------------------------------
  * ʹenumeratorrecord filterв
  *-------------------------------------------------*/
  private void searchRecordStore(){
    try{
      // RecordStoreǿ
      if (rs.getNumRecords() > 0){
        // ʹûıSearchFilter
        SearchFilter search = new SearchFilter(tfFind.getString());
        
        RecordEnumeration re = rs.enumerateRecords(search, null, false);
 
        // ҳɹ
        if (re.numRecords() > 0)          
          siMatch.setText(new String(re.nextRecord()));  
          re.destroy();   // ͷenumerator
      }
    }catch (Exception e){
      db(e.toString());
    }
  }
 
  public void commandAction(Command c, Displayable s){
    if (c == cmFind){
      searchRecordStore();
    }else if (c == cmExit){
      destroyApp(false);
      notifyDestroyed();
    }
  }  
    
  /*--------------------------------------------------
  * ĻʾԻϢ
  *-------------------------------------------------*/
  private void db(String str){
    System.err.println("Msg: " + str);
  }
}
 
/*--------------------------------------------------
* ڼ¼вһı
*-------------------------------------------------*/
class SearchFilter implements RecordFilter{
  private String searchText = null;  
  public SearchFilter(String searchText){
    // Ҫҵı
    this.searchText = searchText.toLowerCase();
  }
 
  public boolean matches(byte[] candidate){
    String str = new String(candidate).toLowerCase();
 
    // һƥ
    if (searchText != null && str.indexOf(searchText) != -1)
      return true;
    else
      return false;
  }
}


//5.6.5  ЧʹRMS
/* Record.java */
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.io.*;

public class Record implements DataInput {
    private RecordStore _rs;
    private byte[] _data;
    private int _length;
    private int _id;
    private DataInputStream _din;

    public Record( RecordStore rs ){
        this( rs, 100 );
    }

    public Record( 
        RecordStore rs, int initialRecordSize ){
        _rs     = rs;
        _data   = new byte[ initialRecordSize ];
        _din    = new DataInputStream(new ByteArrayInputStream( _data ) );
        _length = -1;
    }

    public byte[] getByteArray() { return _data; }

    public int getLength() { return _length; }

    public byte[] moveTo( int id ) 
                 throws RecordStoreNotOpenException,
                              InvalidRecordIDException,
                                  RecordStoreException,
                                           IOException {
        _length = _rs.getRecordSize( id );
        if( _length > _data.length ){
            _data = new byte[ _length + 40 ];
            _din = new DataInputStream(new ByteArrayInputStream( _data ) );
        }
        _rs.getRecord( id, _data, 0 );
        _id = id;
        _din.reset();
        return _data;
    }

	public void readFully(byte b[]) throws IOException {
        _din.readFully( b );
    }

	public int skipBytes(int n) throws IOException {
	       return _din.skipBytes( n );
    }

	public void readFully(byte b[], int off, int len) throws IOException {
        _din.readFully( b, off, len );
	}

	public boolean readBoolean() throws IOException {
        return _din.readBoolean();
    }
 
    public byte readByte() throws IOException {
        return _din.readByte();
    }

    public int readUnsignedByte() 
                                   throws IOException {
       return _din.readUnsignedByte();
    }

    public short readShort() throws IOException {
        return _din.readShort();
    }

    public int readUnsignedShort() 
                                   throws IOException {
       return _din.readUnsignedShort();
    }

    public char readChar() throws IOException {
        return _din.readChar();
    }
    public int readInt() throws IOException {
        return _din.readInt();
    }

    public long readLong() throws IOException {
        return _din.readLong();
    }

    public String readUTF() throws IOException {
        return _din.readUTF();
    }
};

/* test.java */
import java.io.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;
import javax.microedition.io.*;

public class test extends MIDlet {

  public test(){}

  public void startApp()throws MIDletStateChangeException{

   RecordStore rs=null;

   try {
    rs = RecordStore.openRecordStore( "mydata", true );  
    // ݿд¼
    ByteArrayOutputStream bout = new ByteArrayOutputStream();
    DataOutputStream dout = new DataOutputStream( bout );
    byte[] data;

    dout.writeUTF( "this is a test" );
    dout.writeInt( 1 );
    dout.flush();
    data = bout.toByteArray();

    rs.addRecord( data, 0, data.length );

    bout.reset();
    dout.writeUTF( "this is another test" );
    dout.writeInt( 99 );
    dout.flush();
    data = bout.toByteArray();

    rs.addRecord( data, 0, data.length );
   
    // ڱݿ

    Record record = new Record( rs );
    int lastID = rs.getNextRecordID();
    RecordEnumeration enum = rs.enumerateRecords(null, null,false);

    while( enum.hasNextElement() ){
        int id = enum.nextRecordId();
        record.moveTo( id );
        System.out.println( record.readUTF() + " " + 
                                    record.readInt() );
    }

    rs.closeRecordStore();
   }
   
   catch( Exception e ){
    // Ӵ
   }	


   destroyApp(true);
   notifyDestroyed();

 }
  public void pauseApp(){}
  public void destroyApp(boolean unconditional){}
}


//