CursorWindow.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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 17package android.database; 18 19import android.database.sqlite.SQLiteClosable; 20import android.os.IBinder; 21import android.os.Parcel; 22import android.os.Parcelable; 23 24/** 25 * A buffer containing multiple cursor rows. 26 */ 27public 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 private native boolean isBlob_native(int row, int col); 267 268 /** 269 * Returns a String for the given field. 270 * 271 * @param row the row to read from, row - getStartPosition() being the actual row in the window 272 * @param col the column to read from 273 * @return a String value for the given field 274 */ 275 public String getString(int row, int col) { 276 acquireReference(); 277 try { 278 return getString_native(row - mStartPos, col); 279 } finally { 280 releaseReference(); 281 } 282 } 283 284 private native String getString_native(int row, int col); 285 286 /** 287 * copy the text for the given field in the provided char array. 288 * 289 * @param row the row to read from, row - getStartPosition() being the actual row in the window 290 * @param col the column to read from 291 * @param buffer the CharArrayBuffer to copy the text into, 292 * If the requested string is larger than the buffer 293 * a new char buffer will be created to hold the string. and assigne to 294 * CharArrayBuffer.data 295 */ 296 public void copyStringToBuffer(int row, int col, CharArrayBuffer buffer) { 297 if (buffer == null) { 298 throw new IllegalArgumentException("CharArrayBuffer should not be null"); 299 } 300 if (buffer.data == null) { 301 buffer.data = new char[64]; 302 } 303 acquireReference(); 304 try { 305 char[] newbuf = copyStringToBuffer_native( 306 row - mStartPos, col, buffer.data.length, buffer); 307 if (newbuf != null) { 308 buffer.data = newbuf; 309 } 310 } finally { 311 releaseReference(); 312 } 313 } 314 315 private native char[] copyStringToBuffer_native( 316 int row, int col, int bufferSize, CharArrayBuffer buffer); 317 318 /** 319 * Returns a long for the given field. 320 * row is 0 based 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 long value for the given field 325 */ 326 public long getLong(int row, int col) { 327 acquireReference(); 328 try { 329 return getLong_native(row - mStartPos, col); 330 } finally { 331 releaseReference(); 332 } 333 } 334 335 private native long getLong_native(int row, int col); 336 337 /** 338 * Returns a double for the given field. 339 * row is 0 based 340 * 341 * @param row the row to read from, row - getStartPosition() being the actual row in the window 342 * @param col the column to read from 343 * @return a double value for the given field 344 */ 345 public double getDouble(int row, int col) { 346 acquireReference(); 347 try { 348 return getDouble_native(row - mStartPos, col); 349 } finally { 350 releaseReference(); 351 } 352 } 353 354 private native double getDouble_native(int row, int col); 355 356 /** 357 * Returns a short for the given field. 358 * row is 0 based 359 * 360 * @param row the row to read from, row - getStartPosition() being the actual row in the window 361 * @param col the column to read from 362 * @return a short value for the given field 363 */ 364 public short getShort(int row, int col) { 365 acquireReference(); 366 try { 367 return (short) getLong_native(row - mStartPos, col); 368 } finally { 369 releaseReference(); 370 } 371 } 372 373 /** 374 * Returns an int for the given field. 375 * 376 * @param row the row to read from, row - getStartPosition() being the actual row in the window 377 * @param col the column to read from 378 * @return an int value for the given field 379 */ 380 public int getInt(int row, int col) { 381 acquireReference(); 382 try { 383 return (int) getLong_native(row - mStartPos, col); 384 } finally { 385 releaseReference(); 386 } 387 } 388 389 /** 390 * Returns a float for the given field. 391 * row is 0 based 392 * 393 * @param row the row to read from, row - getStartPosition() being the actual row in the window 394 * @param col the column to read from 395 * @return a float value for the given field 396 */ 397 public float getFloat(int row, int col) { 398 acquireReference(); 399 try { 400 return (float) getDouble_native(row - mStartPos, col); 401 } finally { 402 releaseReference(); 403 } 404 } 405 406 /** 407 * Clears out the existing contents of the window, making it safe to reuse 408 * for new data. Note that the number of columns in the window may NOT 409 * change across a call to clear(). 410 */ 411 public void clear() { 412 acquireReference(); 413 try { 414 mStartPos = 0; 415 native_clear(); 416 } finally { 417 releaseReference(); 418 } 419 } 420 421 /** Clears out the native side of things */ 422 private native void native_clear(); 423 424 /** 425 * Cleans up the native resources associated with the window. 426 */ 427 public void close() { 428 releaseReference(); 429 } 430 431 private native void close_native(); 432 433 @Override 434 protected void finalize() { 435 // Just in case someone forgot to call close... 436 close_native(); 437 } 438 439 public static final Parcelable.Creator<CursorWindow> CREATOR 440 = new Parcelable.Creator<CursorWindow>() { 441 public CursorWindow createFromParcel(Parcel source) { 442 return new CursorWindow(source); 443 } 444 445 public CursorWindow[] newArray(int size) { 446 return new CursorWindow[size]; 447 } 448 }; 449 450 public static CursorWindow newFromParcel(Parcel p) { 451 return CREATOR.createFromParcel(p); 452 } 453 454 public int describeContents() { 455 return 0; 456 } 457 458 public void writeToParcel(Parcel dest, int flags) { 459 dest.writeStrongBinder(native_getBinder()); 460 dest.writeInt(mStartPos); 461 } 462 463 private CursorWindow(Parcel source) { 464 IBinder nativeBinder = source.readStrongBinder(); 465 mStartPos = source.readInt(); 466 467 native_init(nativeBinder); 468 } 469 470 /** Get the binder for the native side of the window */ 471 private native IBinder native_getBinder(); 472 473 /** Does the native side initialization for an empty window */ 474 private native void native_init(boolean localOnly); 475 476 /** Does the native side initialization with an existing binder from another process */ 477 private native void native_init(IBinder nativeBinder); 478 479 @Override 480 protected void onAllReferencesReleased() { 481 close_native(); 482 } 483} 484