Home | History | Annotate | Download | only in database
      1 /*
      2  * Copyright (C) 2006 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.database;
     18 
     19 import android.database.sqlite.SQLiteClosable;
     20 import android.os.IBinder;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 
     24 /**
     25  * A buffer containing multiple cursor rows.
     26  */
     27 public class CursorWindow extends SQLiteClosable implements Parcelable {
     28     /** The pointer to the native window class */
     29     @SuppressWarnings("unused")
     30     private int nWindow;
     31 
     32     private int mStartPos;
     33 
     34     /**
     35      * Creates a new empty window.
     36      *
     37      * @param localWindow true if this window will be used in this process only
     38      */
     39     public CursorWindow(boolean localWindow) {
     40         mStartPos = 0;
     41         native_init(localWindow);
     42     }
     43 
     44     /**
     45      * Returns the starting position of this window within the entire
     46      * Cursor's result set.
     47      *
     48      * @return the starting position of this window within the entire
     49      * Cursor's result set.
     50      */
     51     public int getStartPosition() {
     52         return mStartPos;
     53     }
     54 
     55     /**
     56      * Set the start position of cursor window
     57      * @param pos
     58      */
     59     public void setStartPosition(int pos) {
     60         mStartPos = pos;
     61     }
     62 
     63     /**
     64      * Returns the number of rows in this window.
     65      *
     66      * @return the number of rows in this window.
     67      */
     68     public int getNumRows() {
     69         acquireReference();
     70         try {
     71             return getNumRows_native();
     72         } finally {
     73             releaseReference();
     74         }
     75     }
     76 
     77     private native int getNumRows_native();
     78     /**
     79      * Set number of Columns
     80      * @param columnNum
     81      * @return true if success
     82      */
     83     public boolean setNumColumns(int columnNum) {
     84         acquireReference();
     85         try {
     86             return setNumColumns_native(columnNum);
     87         } finally {
     88             releaseReference();
     89         }
     90     }
     91 
     92     private native boolean setNumColumns_native(int columnNum);
     93 
     94     /**
     95      * Allocate a row in cursor window
     96      * @return false if cursor window is out of memory
     97      */
     98     public boolean allocRow(){
     99         acquireReference();
    100         try {
    101             return allocRow_native();
    102         } finally {
    103             releaseReference();
    104         }
    105     }
    106 
    107     private native boolean allocRow_native();
    108 
    109     /**
    110      * Free the last row
    111      */
    112     public void freeLastRow(){
    113         acquireReference();
    114         try {
    115             freeLastRow_native();
    116         } finally {
    117             releaseReference();
    118         }
    119     }
    120 
    121     private native void freeLastRow_native();
    122 
    123     /**
    124      * copy byte array to cursor window
    125      * @param value
    126      * @param row
    127      * @param col
    128      * @return false if fail to copy
    129      */
    130     public boolean putBlob(byte[] value, int row, int col) {
    131         acquireReference();
    132         try {
    133             return putBlob_native(value, row - mStartPos, col);
    134         } finally {
    135             releaseReference();
    136         }
    137     }
    138 
    139     private native boolean putBlob_native(byte[] value, int row, int col);
    140 
    141     /**
    142      * Copy String to cursor window
    143      * @param value
    144      * @param row
    145      * @param col
    146      * @return false if fail to copy
    147      */
    148     public boolean putString(String value, int row, int col) {
    149         acquireReference();
    150         try {
    151             return putString_native(value, row - mStartPos, col);
    152         } finally {
    153             releaseReference();
    154         }
    155     }
    156 
    157     private native boolean putString_native(String value, int row, int col);
    158 
    159     /**
    160      * Copy integer to cursor window
    161      * @param value
    162      * @param row
    163      * @param col
    164      * @return false if fail to copy
    165      */
    166     public boolean putLong(long value, int row, int col) {
    167         acquireReference();
    168         try {
    169             return putLong_native(value, row - mStartPos, col);
    170         } finally {
    171             releaseReference();
    172         }
    173     }
    174 
    175     private native boolean putLong_native(long value, int row, int col);
    176 
    177 
    178     /**
    179      * Copy double to cursor window
    180      * @param value
    181      * @param row
    182      * @param col
    183      * @return false if fail to copy
    184      */
    185     public boolean putDouble(double value, int row, int col) {
    186         acquireReference();
    187         try {
    188             return putDouble_native(value, row - mStartPos, col);
    189         } finally {
    190             releaseReference();
    191         }
    192     }
    193 
    194     private native boolean putDouble_native(double value, int row, int col);
    195 
    196     /**
    197      * Set the [row, col] value to NULL
    198      * @param row
    199      * @param col
    200      * @return false if fail to copy
    201      */
    202     public boolean putNull(int row, int col) {
    203         acquireReference();
    204         try {
    205             return putNull_native(row - mStartPos, col);
    206         } finally {
    207             releaseReference();
    208         }
    209     }
    210 
    211     private native boolean putNull_native(int row, int col);
    212 
    213 
    214     /**
    215      * Returns {@code true} if given field is {@code NULL}.
    216      *
    217      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    218      * @param col the column to read from
    219      * @return {@code true} if given field is {@code NULL}
    220      */
    221     public boolean isNull(int row, int col) {
    222         acquireReference();
    223         try {
    224             return isNull_native(row - mStartPos, col);
    225         } finally {
    226             releaseReference();
    227         }
    228     }
    229 
    230     private native boolean isNull_native(int row, int col);
    231 
    232     /**
    233      * Returns a byte array for the given field.
    234      *
    235      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    236      * @param col the column to read from
    237      * @return a String value for the given field
    238      */
    239     public byte[] getBlob(int row, int col) {
    240         acquireReference();
    241         try {
    242             return getBlob_native(row - mStartPos, col);
    243         } finally {
    244             releaseReference();
    245         }
    246     }
    247 
    248     private native byte[] getBlob_native(int row, int col);
    249 
    250     /**
    251      * Checks if a field contains either a blob or is null.
    252      *
    253      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    254      * @param col the column to read from
    255      * @return {@code true} if given field is {@code NULL} or a blob
    256      */
    257     public boolean isBlob(int row, int col) {
    258         acquireReference();
    259         try {
    260             return isBlob_native(row - mStartPos, col);
    261         } finally {
    262             releaseReference();
    263         }
    264     }
    265 
    266     /**
    267      * Checks if a field contains a long
    268      *
    269      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    270      * @param col the column to read from
    271      * @return {@code true} if given field is a long
    272      */
    273     public boolean isLong(int row, int col) {
    274         acquireReference();
    275         try {
    276             return isInteger_native(row - mStartPos, col);
    277         } finally {
    278             releaseReference();
    279         }
    280     }
    281 
    282     /**
    283      * Checks if a field contains a float.
    284      *
    285      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    286      * @param col the column to read from
    287      * @return {@code true} if given field is a float
    288      */
    289     public boolean isFloat(int row, int col) {
    290         acquireReference();
    291         try {
    292             return isFloat_native(row - mStartPos, col);
    293         } finally {
    294             releaseReference();
    295         }
    296     }
    297 
    298     /**
    299      * Checks if a field contains either a String or is null.
    300      *
    301      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    302      * @param col the column to read from
    303      * @return {@code true} if given field is {@code NULL} or a String
    304      */
    305     public boolean isString(int row, int col) {
    306         acquireReference();
    307         try {
    308             return isString_native(row - mStartPos, col);
    309         } finally {
    310             releaseReference();
    311         }
    312     }
    313 
    314     private native boolean isBlob_native(int row, int col);
    315     private native boolean isString_native(int row, int col);
    316     private native boolean isInteger_native(int row, int col);
    317     private native boolean isFloat_native(int row, int col);
    318 
    319     /**
    320      * Returns a String for the given field.
    321      *
    322      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    323      * @param col the column to read from
    324      * @return a String value for the given field
    325      */
    326     public String getString(int row, int col) {
    327         acquireReference();
    328         try {
    329             return getString_native(row - mStartPos, col);
    330         } finally {
    331             releaseReference();
    332         }
    333     }
    334 
    335     private native String getString_native(int row, int col);
    336 
    337     /**
    338      * copy the text for the given field in the provided char array.
    339      *
    340      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    341      * @param col the column to read from
    342      * @param buffer the CharArrayBuffer to copy the text into,
    343      * If the requested string is larger than the buffer
    344      * a new char buffer will be created to hold the string. and assigne to
    345      * CharArrayBuffer.data
    346       */
    347     public void copyStringToBuffer(int row, int col, CharArrayBuffer buffer) {
    348         if (buffer == null) {
    349             throw new IllegalArgumentException("CharArrayBuffer should not be null");
    350         }
    351         if (buffer.data == null) {
    352             buffer.data = new char[64];
    353         }
    354         acquireReference();
    355         try {
    356             char[] newbuf = copyStringToBuffer_native(
    357                     row - mStartPos, col, buffer.data.length, buffer);
    358             if (newbuf != null) {
    359                 buffer.data = newbuf;
    360             }
    361         } finally {
    362             releaseReference();
    363         }
    364     }
    365 
    366     private native char[] copyStringToBuffer_native(
    367             int row, int col, int bufferSize, CharArrayBuffer buffer);
    368 
    369     /**
    370      * Returns a long for the given field.
    371      * row is 0 based
    372      *
    373      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    374      * @param col the column to read from
    375      * @return a long value for the given field
    376      */
    377     public long getLong(int row, int col) {
    378         acquireReference();
    379         try {
    380             return getLong_native(row - mStartPos, col);
    381         } finally {
    382             releaseReference();
    383         }
    384     }
    385 
    386     private native long getLong_native(int row, int col);
    387 
    388     /**
    389      * Returns a double for the given field.
    390      * row is 0 based
    391      *
    392      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    393      * @param col the column to read from
    394      * @return a double value for the given field
    395      */
    396     public double getDouble(int row, int col) {
    397         acquireReference();
    398         try {
    399             return getDouble_native(row - mStartPos, col);
    400         } finally {
    401             releaseReference();
    402         }
    403     }
    404 
    405     private native double getDouble_native(int row, int col);
    406 
    407     /**
    408      * Returns a short for the given field.
    409      * row is 0 based
    410      *
    411      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    412      * @param col the column to read from
    413      * @return a short value for the given field
    414      */
    415     public short getShort(int row, int col) {
    416         acquireReference();
    417         try {
    418             return (short) getLong_native(row - mStartPos, col);
    419         } finally {
    420             releaseReference();
    421         }
    422     }
    423 
    424     /**
    425      * Returns an int for the given field.
    426      *
    427      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    428      * @param col the column to read from
    429      * @return an int value for the given field
    430      */
    431     public int getInt(int row, int col) {
    432         acquireReference();
    433         try {
    434             return (int) getLong_native(row - mStartPos, col);
    435         } finally {
    436             releaseReference();
    437         }
    438     }
    439 
    440     /**
    441      * Returns a float for the given field.
    442      * row is 0 based
    443      *
    444      * @param row the row to read from, row - getStartPosition() being the actual row in the window
    445      * @param col the column to read from
    446      * @return a float value for the given field
    447      */
    448     public float getFloat(int row, int col) {
    449         acquireReference();
    450         try {
    451             return (float) getDouble_native(row - mStartPos, col);
    452         } finally {
    453             releaseReference();
    454         }
    455     }
    456 
    457     /**
    458      * Clears out the existing contents of the window, making it safe to reuse
    459      * for new data. Note that the number of columns in the window may NOT
    460      * change across a call to clear().
    461      */
    462     public void clear() {
    463         acquireReference();
    464         try {
    465             mStartPos = 0;
    466             native_clear();
    467         } finally {
    468             releaseReference();
    469         }
    470     }
    471 
    472     /** Clears out the native side of things */
    473     private native void native_clear();
    474 
    475     /**
    476      * Cleans up the native resources associated with the window.
    477      */
    478     public void close() {
    479         releaseReference();
    480     }
    481 
    482     private native void close_native();
    483 
    484     @Override
    485     protected void finalize() {
    486         // Just in case someone forgot to call close...
    487         close_native();
    488     }
    489 
    490     public static final Parcelable.Creator<CursorWindow> CREATOR
    491             = new Parcelable.Creator<CursorWindow>() {
    492         public CursorWindow createFromParcel(Parcel source) {
    493             return new CursorWindow(source);
    494         }
    495 
    496         public CursorWindow[] newArray(int size) {
    497             return new CursorWindow[size];
    498         }
    499     };
    500 
    501     public static CursorWindow newFromParcel(Parcel p) {
    502         return CREATOR.createFromParcel(p);
    503     }
    504 
    505     public int describeContents() {
    506         return 0;
    507     }
    508 
    509     public void writeToParcel(Parcel dest, int flags) {
    510         dest.writeStrongBinder(native_getBinder());
    511         dest.writeInt(mStartPos);
    512     }
    513 
    514     private CursorWindow(Parcel source) {
    515         IBinder nativeBinder = source.readStrongBinder();
    516         mStartPos = source.readInt();
    517 
    518         native_init(nativeBinder);
    519     }
    520 
    521     /** Get the binder for the native side of the window */
    522     private native IBinder native_getBinder();
    523 
    524     /** Does the native side initialization for an empty window */
    525     private native void native_init(boolean localOnly);
    526 
    527     /** Does the native side initialization with an existing binder from another process */
    528     private native void native_init(IBinder nativeBinder);
    529 
    530     @Override
    531     protected void onAllReferencesReleased() {
    532         close_native();
    533     }
    534 }
    535