780 lines
28 KiB
Java
780 lines
28 KiB
Java
/*
|
|
* 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.annotation.BytesLong;
|
|
import android.annotation.IntRange;
|
|
import android.compat.annotation.UnsupportedAppUsage;
|
|
import android.content.res.Resources;
|
|
import android.database.sqlite.SQLiteClosable;
|
|
import android.database.sqlite.SQLiteException;
|
|
import android.os.Parcel;
|
|
import android.os.Parcelable;
|
|
|
|
import dalvik.annotation.optimization.FastNative;
|
|
import dalvik.system.CloseGuard;
|
|
|
|
/**
|
|
* A buffer containing multiple cursor rows.
|
|
* <p>
|
|
* A {@link CursorWindow} is read-write when initially created and used locally.
|
|
* When sent to a remote process (by writing it to a {@link Parcel}), the remote process
|
|
* receives a read-only view of the cursor window. Typically the cursor window
|
|
* will be allocated by the producer, filled with data, and then sent to the
|
|
* consumer for reading.
|
|
* </p>
|
|
*/
|
|
@android.ravenwood.annotation.RavenwoodKeepWholeClass
|
|
@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
|
|
"com.android.platform.test.ravenwood.nativesubstitution.CursorWindow_host")
|
|
public class CursorWindow extends SQLiteClosable implements Parcelable {
|
|
private static final String STATS_TAG = "CursorWindowStats";
|
|
|
|
// This static member will be evaluated when first used.
|
|
@UnsupportedAppUsage
|
|
private static int sCursorWindowSize = -1;
|
|
|
|
/**
|
|
* The native CursorWindow object pointer. (FOR INTERNAL USE ONLY)
|
|
* @hide
|
|
*/
|
|
@UnsupportedAppUsage
|
|
public long mWindowPtr;
|
|
|
|
private int mStartPos;
|
|
private final String mName;
|
|
|
|
private final CloseGuard mCloseGuard;
|
|
|
|
// May throw CursorWindowAllocationException
|
|
private static native long nativeCreate(String name, int cursorWindowSize);
|
|
|
|
// May throw CursorWindowAllocationException
|
|
private static native long nativeCreateFromParcel(Parcel parcel);
|
|
private static native void nativeDispose(long windowPtr);
|
|
private static native void nativeWriteToParcel(long windowPtr, Parcel parcel);
|
|
|
|
private static native String nativeGetName(long windowPtr);
|
|
private static native byte[] nativeGetBlob(long windowPtr, int row, int column);
|
|
private static native String nativeGetString(long windowPtr, int row, int column);
|
|
private static native void nativeCopyStringToBuffer(long windowPtr, int row, int column,
|
|
CharArrayBuffer buffer);
|
|
private static native boolean nativePutBlob(long windowPtr, byte[] value, int row, int column);
|
|
private static native boolean nativePutString(long windowPtr, String value,
|
|
int row, int column);
|
|
|
|
// Below native methods don't do unconstrained work, so are FastNative for performance
|
|
|
|
@FastNative
|
|
private static native void nativeClear(long windowPtr);
|
|
|
|
@FastNative
|
|
private static native int nativeGetNumRows(long windowPtr);
|
|
@FastNative
|
|
private static native boolean nativeSetNumColumns(long windowPtr, int columnNum);
|
|
@FastNative
|
|
private static native boolean nativeAllocRow(long windowPtr);
|
|
@FastNative
|
|
private static native void nativeFreeLastRow(long windowPtr);
|
|
|
|
@FastNative
|
|
private static native int nativeGetType(long windowPtr, int row, int column);
|
|
@FastNative
|
|
private static native long nativeGetLong(long windowPtr, int row, int column);
|
|
@FastNative
|
|
private static native double nativeGetDouble(long windowPtr, int row, int column);
|
|
|
|
@FastNative
|
|
private static native boolean nativePutLong(long windowPtr, long value, int row, int column);
|
|
@FastNative
|
|
private static native boolean nativePutDouble(long windowPtr, double value, int row, int column);
|
|
@FastNative
|
|
private static native boolean nativePutNull(long windowPtr, int row, int column);
|
|
|
|
|
|
/**
|
|
* Creates a new empty cursor window and gives it a name.
|
|
* <p>
|
|
* The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to
|
|
* set the number of columns before adding any rows to the cursor.
|
|
* </p>
|
|
*
|
|
* @param name The name of the cursor window, or null if none.
|
|
*/
|
|
public CursorWindow(String name) {
|
|
this(name, getCursorWindowSize());
|
|
}
|
|
|
|
/**
|
|
* Creates a new empty cursor window and gives it a name.
|
|
* <p>
|
|
* The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to
|
|
* set the number of columns before adding any rows to the cursor.
|
|
* </p>
|
|
*
|
|
* @param name The name of the cursor window, or null if none.
|
|
* @param windowSizeBytes Size of cursor window in bytes.
|
|
* @throws IllegalArgumentException if {@code windowSizeBytes} is less than 0
|
|
* @throws AssertionError if created window pointer is 0
|
|
* <p><strong>Note:</strong> Memory is dynamically allocated as data rows are added to the
|
|
* window. Depending on the amount of data stored, the actual amount of memory allocated can be
|
|
* lower than specified size, but cannot exceed it.
|
|
*/
|
|
public CursorWindow(String name, @BytesLong long windowSizeBytes) {
|
|
if (windowSizeBytes < 0) {
|
|
throw new IllegalArgumentException("Window size cannot be less than 0");
|
|
}
|
|
mStartPos = 0;
|
|
mName = name != null && name.length() != 0 ? name : "<unnamed>";
|
|
mWindowPtr = nativeCreate(mName, (int) windowSizeBytes);
|
|
if (mWindowPtr == 0) {
|
|
throw new AssertionError(); // Not possible, the native code won't return it.
|
|
}
|
|
mCloseGuard = createCloseGuard();
|
|
}
|
|
|
|
/**
|
|
* Creates a new empty cursor window.
|
|
* <p>
|
|
* The cursor initially has no rows or columns. Call {@link #setNumColumns(int)} to
|
|
* set the number of columns before adding any rows to the cursor.
|
|
* </p>
|
|
*
|
|
* @param localWindow True if this window will be used in this process only,
|
|
* false if it might be sent to another processes. This argument is ignored.
|
|
*
|
|
* @deprecated There is no longer a distinction between local and remote
|
|
* cursor windows. Use the {@link #CursorWindow(String)} constructor instead.
|
|
*/
|
|
@Deprecated
|
|
public CursorWindow(boolean localWindow) {
|
|
this((String)null);
|
|
}
|
|
|
|
private CursorWindow(Parcel source) {
|
|
mStartPos = source.readInt();
|
|
mWindowPtr = nativeCreateFromParcel(source);
|
|
if (mWindowPtr == 0) {
|
|
throw new AssertionError(); // Not possible, the native code won't return it.
|
|
}
|
|
mName = nativeGetName(mWindowPtr);
|
|
mCloseGuard = createCloseGuard();
|
|
}
|
|
|
|
@android.ravenwood.annotation.RavenwoodReplace
|
|
private CloseGuard createCloseGuard() {
|
|
final CloseGuard closeGuard = CloseGuard.get();
|
|
closeGuard.open("CursorWindow.close");
|
|
return closeGuard;
|
|
}
|
|
|
|
private CloseGuard createCloseGuard$ravenwood() {
|
|
return null;
|
|
}
|
|
|
|
@Override
|
|
protected void finalize() throws Throwable {
|
|
try {
|
|
if (mCloseGuard != null) {
|
|
mCloseGuard.warnIfOpen();
|
|
}
|
|
dispose();
|
|
} finally {
|
|
super.finalize();
|
|
}
|
|
}
|
|
|
|
private void dispose() {
|
|
if (mCloseGuard != null) {
|
|
mCloseGuard.close();
|
|
}
|
|
if (mWindowPtr != 0) {
|
|
nativeDispose(mWindowPtr);
|
|
mWindowPtr = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the name of this cursor window, never null.
|
|
* @hide
|
|
*/
|
|
public String getName() {
|
|
return mName;
|
|
}
|
|
|
|
/**
|
|
* Clears out the existing contents of the window, making it safe to reuse
|
|
* for new data.
|
|
* <p>
|
|
* The start position ({@link #getStartPosition()}), number of rows ({@link #getNumRows()}),
|
|
* and number of columns in the cursor are all reset to zero.
|
|
* </p>
|
|
*/
|
|
public void clear() {
|
|
acquireReference();
|
|
try {
|
|
mStartPos = 0;
|
|
nativeClear(mWindowPtr);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the start position of this cursor window.
|
|
* <p>
|
|
* The start position is the zero-based index of the first row that this window contains
|
|
* relative to the entire result set of the {@link Cursor}.
|
|
* </p>
|
|
*
|
|
* @return The zero-based start position.
|
|
*/
|
|
public @IntRange(from = 0) int getStartPosition() {
|
|
return mStartPos;
|
|
}
|
|
|
|
/**
|
|
* Sets the start position of this cursor window.
|
|
* <p>
|
|
* The start position is the zero-based index of the first row that this window contains
|
|
* relative to the entire result set of the {@link Cursor}.
|
|
* </p>
|
|
*
|
|
* @param pos The new zero-based start position.
|
|
*/
|
|
public void setStartPosition(@IntRange(from = 0) int pos) {
|
|
mStartPos = pos;
|
|
}
|
|
|
|
/**
|
|
* Gets the number of rows in this window.
|
|
*
|
|
* @return The number of rows in this cursor window.
|
|
*/
|
|
public @IntRange(from = 0) int getNumRows() {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetNumRows(mWindowPtr);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the number of columns in this window.
|
|
* <p>
|
|
* This method must be called before any rows are added to the window, otherwise
|
|
* it will fail to set the number of columns if it differs from the current number
|
|
* of columns.
|
|
* </p>
|
|
*
|
|
* @param columnNum The new number of columns.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean setNumColumns(@IntRange(from = 0) int columnNum) {
|
|
acquireReference();
|
|
try {
|
|
return nativeSetNumColumns(mWindowPtr, columnNum);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Allocates a new row at the end of this cursor window.
|
|
*
|
|
* @return True if successful, false if the cursor window is out of memory.
|
|
*/
|
|
public boolean allocRow(){
|
|
acquireReference();
|
|
try {
|
|
return nativeAllocRow(mWindowPtr);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Frees the last row in this cursor window.
|
|
*/
|
|
public void freeLastRow(){
|
|
acquireReference();
|
|
try {
|
|
nativeFreeLastRow(mWindowPtr);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns true if the field at the specified row and column index
|
|
* has type {@link Cursor#FIELD_TYPE_NULL}.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if the field has type {@link Cursor#FIELD_TYPE_NULL}.
|
|
* @deprecated Use {@link #getType(int, int)} instead.
|
|
*/
|
|
@Deprecated
|
|
public boolean isNull(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return getType(row, column) == Cursor.FIELD_TYPE_NULL;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the field at the specified row and column index
|
|
* has type {@link Cursor#FIELD_TYPE_BLOB} or {@link Cursor#FIELD_TYPE_NULL}.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if the field has type {@link Cursor#FIELD_TYPE_BLOB} or
|
|
* {@link Cursor#FIELD_TYPE_NULL}.
|
|
* @deprecated Use {@link #getType(int, int)} instead.
|
|
*/
|
|
@Deprecated
|
|
public boolean isBlob(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
int type = getType(row, column);
|
|
return type == Cursor.FIELD_TYPE_BLOB || type == Cursor.FIELD_TYPE_NULL;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the field at the specified row and column index
|
|
* has type {@link Cursor#FIELD_TYPE_INTEGER}.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if the field has type {@link Cursor#FIELD_TYPE_INTEGER}.
|
|
* @deprecated Use {@link #getType(int, int)} instead.
|
|
*/
|
|
@Deprecated
|
|
public boolean isLong(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return getType(row, column) == Cursor.FIELD_TYPE_INTEGER;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the field at the specified row and column index
|
|
* has type {@link Cursor#FIELD_TYPE_FLOAT}.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if the field has type {@link Cursor#FIELD_TYPE_FLOAT}.
|
|
* @deprecated Use {@link #getType(int, int)} instead.
|
|
*/
|
|
@Deprecated
|
|
public boolean isFloat(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return getType(row, column) == Cursor.FIELD_TYPE_FLOAT;
|
|
}
|
|
|
|
/**
|
|
* Returns true if the field at the specified row and column index
|
|
* has type {@link Cursor#FIELD_TYPE_STRING} or {@link Cursor#FIELD_TYPE_NULL}.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if the field has type {@link Cursor#FIELD_TYPE_STRING}
|
|
* or {@link Cursor#FIELD_TYPE_NULL}.
|
|
* @deprecated Use {@link #getType(int, int)} instead.
|
|
*/
|
|
@Deprecated
|
|
public boolean isString(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
int type = getType(row, column);
|
|
return type == Cursor.FIELD_TYPE_STRING || type == Cursor.FIELD_TYPE_NULL;
|
|
}
|
|
|
|
/**
|
|
* Returns the type of the field at the specified row and column index.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The field type.
|
|
*/
|
|
public @Cursor.FieldType int getType(@IntRange(from = 0) int row,
|
|
@IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetType(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a byte array.
|
|
* <p>
|
|
* The result is determined as follows:
|
|
* <ul>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
|
|
* is <code>null</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then the result
|
|
* is the blob value.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
|
|
* is the array of bytes that make up the internal representation of the
|
|
* string value.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER} or
|
|
* {@link Cursor#FIELD_TYPE_FLOAT}, then a {@link SQLiteException} is thrown.</li>
|
|
* </ul>
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as a byte array.
|
|
*/
|
|
public byte[] getBlob(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetBlob(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a string.
|
|
* <p>
|
|
* The result is determined as follows:
|
|
* <ul>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
|
|
* is <code>null</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
|
|
* is the string value.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
|
|
* is a string representation of the integer in decimal, obtained by formatting the
|
|
* value with the <code>printf</code> family of functions using
|
|
* format specifier <code>%lld</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
|
|
* is a string representation of the floating-point value in decimal, obtained by
|
|
* formatting the value with the <code>printf</code> family of functions using
|
|
* format specifier <code>%g</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
|
|
* {@link SQLiteException} is thrown.</li>
|
|
* </ul>
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as a string.
|
|
*/
|
|
public String getString(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetString(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copies the text of the field at the specified row and column index into
|
|
* a {@link CharArrayBuffer}.
|
|
* <p>
|
|
* The buffer is populated as follows:
|
|
* <ul>
|
|
* <li>If the buffer is too small for the value to be copied, then it is
|
|
* automatically resized.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the buffer
|
|
* is set to an empty string.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the buffer
|
|
* is set to the contents of the string.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the buffer
|
|
* is set to a string representation of the integer in decimal, obtained by formatting the
|
|
* value with the <code>printf</code> family of functions using
|
|
* format specifier <code>%lld</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the buffer is
|
|
* set to a string representation of the floating-point value in decimal, obtained by
|
|
* formatting the value with the <code>printf</code> family of functions using
|
|
* format specifier <code>%g</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
|
|
* {@link SQLiteException} is thrown.</li>
|
|
* </ul>
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @param buffer The {@link CharArrayBuffer} to hold the string. It is automatically
|
|
* resized if the requested string is larger than the buffer's current capacity.
|
|
*/
|
|
public void copyStringToBuffer(@IntRange(from = 0) int row, @IntRange(from = 0) int column,
|
|
CharArrayBuffer buffer) {
|
|
if (buffer == null) {
|
|
throw new IllegalArgumentException("CharArrayBuffer should not be null");
|
|
}
|
|
acquireReference();
|
|
try {
|
|
nativeCopyStringToBuffer(mWindowPtr, row - mStartPos, column, buffer);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a <code>long</code>.
|
|
* <p>
|
|
* The result is determined as follows:
|
|
* <ul>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
|
|
* is <code>0L</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
|
|
* is the value obtained by parsing the string value with <code>strtoll</code>.
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
|
|
* is the <code>long</code> value.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
|
|
* is the floating-point value converted to a <code>long</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
|
|
* {@link SQLiteException} is thrown.</li>
|
|
* </ul>
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as a <code>long</code>.
|
|
*/
|
|
public long getLong(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetLong(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a
|
|
* <code>double</code>.
|
|
* <p>
|
|
* The result is determined as follows:
|
|
* <ul>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_NULL}, then the result
|
|
* is <code>0.0</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_STRING}, then the result
|
|
* is the value obtained by parsing the string value with <code>strtod</code>.
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_INTEGER}, then the result
|
|
* is the integer value converted to a <code>double</code>.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_FLOAT}, then the result
|
|
* is the <code>double</code> value.</li>
|
|
* <li>If the field is of type {@link Cursor#FIELD_TYPE_BLOB}, then a
|
|
* {@link SQLiteException} is thrown.</li>
|
|
* </ul>
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as a <code>double</code>.
|
|
*/
|
|
public double getDouble(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativeGetDouble(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a
|
|
* <code>short</code>.
|
|
* <p>
|
|
* The result is determined by invoking {@link #getLong} and converting the
|
|
* result to <code>short</code>.
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as a <code>short</code>.
|
|
*/
|
|
public short getShort(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return (short) getLong(row, column);
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as an
|
|
* <code>int</code>.
|
|
* <p>
|
|
* The result is determined by invoking {@link #getLong} and converting the
|
|
* result to <code>int</code>.
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as an <code>int</code>.
|
|
*/
|
|
public int getInt(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return (int) getLong(row, column);
|
|
}
|
|
|
|
/**
|
|
* Gets the value of the field at the specified row and column index as a
|
|
* <code>float</code>.
|
|
* <p>
|
|
* The result is determined by invoking {@link #getDouble} and converting the
|
|
* result to <code>float</code>.
|
|
* </p>
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return The value of the field as an <code>float</code>.
|
|
*/
|
|
public float getFloat(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
return (float) getDouble(row, column);
|
|
}
|
|
|
|
/**
|
|
* Copies a byte array into the field at the specified row and column index.
|
|
*
|
|
* @param value The value to store.
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean putBlob(byte[] value,
|
|
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativePutBlob(mWindowPtr, value, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Copies a string into the field at the specified row and column index.
|
|
*
|
|
* @param value The value to store.
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean putString(String value,
|
|
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativePutString(mWindowPtr, value, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Puts a long integer into the field at the specified row and column index.
|
|
*
|
|
* @param value The value to store.
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean putLong(long value,
|
|
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativePutLong(mWindowPtr, value, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Puts a double-precision floating point value into the field at the
|
|
* specified row and column index.
|
|
*
|
|
* @param value The value to store.
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean putDouble(double value,
|
|
@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativePutDouble(mWindowPtr, value, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Puts a null value into the field at the specified row and column index.
|
|
*
|
|
* @param row The zero-based row index.
|
|
* @param column The zero-based column index.
|
|
* @return True if successful.
|
|
*/
|
|
public boolean putNull(@IntRange(from = 0) int row, @IntRange(from = 0) int column) {
|
|
acquireReference();
|
|
try {
|
|
return nativePutNull(mWindowPtr, row - mStartPos, column);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
public static final @android.annotation.NonNull 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) {
|
|
acquireReference();
|
|
try {
|
|
dest.writeInt(mStartPos);
|
|
nativeWriteToParcel(mWindowPtr, dest);
|
|
} finally {
|
|
releaseReference();
|
|
}
|
|
|
|
if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
|
|
releaseReference();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onAllReferencesReleased() {
|
|
dispose();
|
|
}
|
|
|
|
@android.ravenwood.annotation.RavenwoodReplace
|
|
private static int getCursorWindowSize() {
|
|
if (sCursorWindowSize < 0) {
|
|
// The cursor window size. resource xml file specifies the value in kB.
|
|
// convert it to bytes here by multiplying with 1024.
|
|
sCursorWindowSize = Resources.getSystem().getInteger(
|
|
com.android.internal.R.integer.config_cursorWindowSize) * 1024;
|
|
}
|
|
return sCursorWindowSize;
|
|
}
|
|
|
|
private static int getCursorWindowSize$ravenwood() {
|
|
return 1024;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return getName() + " {" + Long.toHexString(mWindowPtr) + "}";
|
|
}
|
|
}
|