summaryrefslogtreecommitdiffstats
path: root/core/java/android/database/CursorWindow.java
blob: 8e2673036e063197cc7eeff621679826b3c8b1d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.database;

import android.database.sqlite.SQLiteClosable;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * A buffer containing multiple cursor rows.
 */
public class CursorWindow extends SQLiteClosable implements Parcelable {
    /** The pointer to the native window class */
    @SuppressWarnings("unused")
    private int nWindow;

    private int mStartPos;

    /**
     * Creates a new empty window.
     *
     * @param localWindow true if this window will be used in this process only
     */
    public CursorWindow(boolean localWindow) {
        mStartPos = 0;
        native_init(localWindow);
    }

    /**
     * Returns the starting position of this window within the entire
     * Cursor's result set.
     * 
     * @return the starting position of this window within the entire
     * Cursor's result set.
     */
    public int getStartPosition() {
        return mStartPos;
    }

    /**
     * Set the start position of cursor window
     * @param pos
     */
    public void setStartPosition(int pos) {
        mStartPos = pos;
    }    
 
    /**
     * Returns the number of rows in this window.
     * 
     * @return the number of rows in this window.
     */
    public int getNumRows() {
        acquireReference();
        try {
            return getNumRows_native();
        } finally {
            releaseReference();
        }
    }
    
    private native int getNumRows_native();
    /**
     * Set number of Columns 
     * @param columnNum
     * @return true if success
     */
    public boolean setNumColumns(int columnNum) {
        acquireReference();
        try {
            return setNumColumns_native(columnNum);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean setNumColumns_native(int columnNum);
    
    /**
     * Allocate a row in cursor window
     * @return false if cursor window is out of memory
     */
    public boolean allocRow(){
        acquireReference();
        try {
            return allocRow_native();
        } finally {
            releaseReference();
        }
    }
    
    private native boolean allocRow_native();    
    
    /**
     * Free the last row
     */
    public void freeLastRow(){
        acquireReference();
        try {
            freeLastRow_native();
        } finally {
            releaseReference();
        }
    }
    
    private native void freeLastRow_native();

    /**
     * copy byte array to cursor window
     * @param value
     * @param row
     * @param col
     * @return false if fail to copy
     */
    public boolean putBlob(byte[] value, int row, int col) {
        acquireReference();
        try {
            return putBlob_native(value, row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean putBlob_native(byte[] value, int row, int col);    

    /**
     * Copy String to cursor window
     * @param value
     * @param row
     * @param col
     * @return false if fail to copy
     */
    public boolean putString(String value, int row, int col) {
        acquireReference();
        try {
            return putString_native(value, row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean putString_native(String value, int row, int col);    
    
    /**
     * Copy integer to cursor window
     * @param value
     * @param row
     * @param col
     * @return false if fail to copy
     */
    public boolean putLong(long value, int row, int col) {
        acquireReference();
        try {
            return putLong_native(value, row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean putLong_native(long value, int row, int col);
    

    /**
     * Copy double to cursor window 
     * @param value
     * @param row
     * @param col
     * @return false if fail to copy
     */
    public boolean putDouble(double value, int row, int col) {
        acquireReference();
        try {
            return putDouble_native(value, row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean putDouble_native(double value, int row, int col);    

    /**
     * Set the [row, col] value to NULL
     * @param row
     * @param col
     * @return false if fail to copy
     */
    public boolean putNull(int row, int col) {
        acquireReference();
        try {
            return putNull_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean putNull_native(int row, int col);
    

    /**
     * Returns {@code true} if given field is {@code NULL}.
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window
     * @param col the column to read from
     * @return {@code true} if given field is {@code NULL}
     */
    public boolean isNull(int row, int col) {
        acquireReference();
        try {
            return isNull_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native boolean isNull_native(int row, int col);
    
    /**
     * Returns a byte array for the given field.
     *
     * @param row the row to read from, row - getStartPosition() being the actual row in the window
     * @param col the column to read from
     * @return a String value for the given field
     */
    public byte[] getBlob(int row, int col) {
        acquireReference();
        try {
            return getBlob_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }

    private native byte[] getBlob_native(int row, int col);

    /**
     * Checks if a field contains either a blob or is null.
     *
     * @param row the row to read from, row - getStartPosition() being the actual row in the window
     * @param col the column to read from
     * @return {@code true} if given field is {@code NULL} or a blob
     */
    public boolean isBlob(int row, int col) {
        acquireReference();
        try {
            return isBlob_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }

    private native boolean isBlob_native(int row, int col);

    /**
     * Returns a String for the given field.
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return a String value for the given field
     */
    public String getString(int row, int col) {
        acquireReference();
        try {
            return getString_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native String getString_native(int row, int col);

    /**
     * copy the text for the given field in the provided char array.
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @param buffer the CharArrayBuffer to copy the text into,      
     * If the requested string is larger than the buffer 
     * a new char buffer will be created to hold the string. and assigne to
     * CharArrayBuffer.data
      */
    public void copyStringToBuffer(int row, int col, CharArrayBuffer buffer) {
        if (buffer == null) {
            throw new IllegalArgumentException("CharArrayBuffer should not be null");
        }
        if (buffer.data == null) {
            buffer.data = new char[64];
        }
        acquireReference();
        try {
            char[] newbuf = copyStringToBuffer_native(
                    row - mStartPos, col, buffer.data.length, buffer);
            if (newbuf != null) {
                buffer.data = newbuf;
            }
        } finally {
            releaseReference();
        }
    }
    
    private native char[] copyStringToBuffer_native(
            int row, int col, int bufferSize, CharArrayBuffer buffer);
    
    /**
     * Returns a long for the given field.
     * row is 0 based
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return a long value for the given field
     */
    public long getLong(int row, int col) {
        acquireReference();
        try {
            return getLong_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native long getLong_native(int row, int col);

    /**
     * Returns a double for the given field.
     * row is 0 based
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return a double value for the given field
     */
    public double getDouble(int row, int col) {
        acquireReference();
        try {
            return getDouble_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    private native double getDouble_native(int row, int col);

    /**
     * Returns a short for the given field.
     * row is 0 based
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return a short value for the given field
     */
    public short getShort(int row, int col) {
        acquireReference();
        try {
            return (short) getLong_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }

    /**
     * Returns an int for the given field.
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return an int value for the given field
     */
    public int getInt(int row, int col) {
        acquireReference();
        try {
            return (int) getLong_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    }
    
    /**
     * Returns a float for the given field.
     * row is 0 based
     * 
     * @param row the row to read from, row - getStartPosition() being the actual row in the window 
     * @param col the column to read from
     * @return a float value for the given field
     */
    public float getFloat(int row, int col) {
        acquireReference();
        try {
            return (float) getDouble_native(row - mStartPos, col);
        } finally {
            releaseReference();
        }
    } 
    
    /**
     * Clears out the existing contents of the window, making it safe to reuse
     * for new data. Note that the number of columns in the window may NOT
     * change across a call to clear().
     */
    public void clear() {
        acquireReference();
        try {
            mStartPos = 0;        
            native_clear();
        } finally {
            releaseReference();
        }
    }

    /** Clears out the native side of things */
    private native void native_clear();

    /**
     * Cleans up the native resources associated with the window.
     */
    public void close() {
        releaseReference();
    }
    
    private native void close_native();

    @Override
    protected void finalize() {
        // Just in case someone forgot to call close...
        close_native();
    }
    
    public static final Parcelable.Creator<CursorWindow> CREATOR
            = new Parcelable.Creator<CursorWindow>() {
        public CursorWindow createFromParcel(Parcel source) {
            return new CursorWindow(source);
        }

        public CursorWindow[] newArray(int size) {
            return new CursorWindow[size];
        }
    };

    public static CursorWindow newFromParcel(Parcel p) {
        return CREATOR.createFromParcel(p);
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStrongBinder(native_getBinder());
        dest.writeInt(mStartPos);
    }

    private CursorWindow(Parcel source) {
        IBinder nativeBinder = source.readStrongBinder();
        mStartPos = source.readInt();

        native_init(nativeBinder);
    }

    /** Get the binder for the native side of the window */
    private native IBinder native_getBinder();

    /** Does the native side initialization for an empty window */
    private native void native_init(boolean localOnly);

    /** Does the native side initialization with an existing binder from another process */
    private native void native_init(IBinder nativeBinder);

    @Override
    protected void onAllReferencesReleased() {
        close_native();        
    }
}