• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 package android.database;
17 
18 import android.database.sqlite.SQLiteException;
19 import android.os.Parcel;
20 import android.ravenwood.annotation.RavenwoodKeepWholeClass;
21 import android.util.Base64;
22 
23 import java.text.DecimalFormat;
24 import java.text.ParsePosition;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.List;
29 
30 @RavenwoodKeepWholeClass
31 class CursorWindow_ravenwood {
32 
33     private static final HashMap<Long, CursorWindow_ravenwood> sInstances = new HashMap<>();
34     private static long sNextId = 1;
35 
36     private String mName;
37     private int mColumnNum;
38     private static class Row {
39         String[] mFields;
40         int[] mTypes;
41     }
42 
43     private final List<Row> mRows = new ArrayList<>();
44 
nativeCreate(String name, int cursorWindowSize)45     public static long nativeCreate(String name, int cursorWindowSize) {
46         CursorWindow_ravenwood instance = new CursorWindow_ravenwood();
47         instance.mName = name;
48         long instanceId = sNextId++;
49         sInstances.put(instanceId, instance);
50         return instanceId;
51     }
52 
nativeDispose(long windowPtr)53     public static void nativeDispose(long windowPtr) {
54         sInstances.remove(windowPtr);
55     }
56 
nativeGetName(long windowPtr)57     public static String nativeGetName(long windowPtr) {
58         return sInstances.get(windowPtr).mName;
59     }
60 
nativeSetNumColumns(long windowPtr, int columnNum)61     public static boolean nativeSetNumColumns(long windowPtr, int columnNum) {
62         sInstances.get(windowPtr).mColumnNum = columnNum;
63         return true;
64     }
65 
nativeGetNumRows(long windowPtr)66     public static int nativeGetNumRows(long windowPtr) {
67         return sInstances.get(windowPtr).mRows.size();
68     }
69 
nativeAllocRow(long windowPtr)70     public static boolean nativeAllocRow(long windowPtr) {
71         CursorWindow_ravenwood instance = sInstances.get(windowPtr);
72         Row row = new Row();
73         row.mFields = new String[instance.mColumnNum];
74         row.mTypes = new int[instance.mColumnNum];
75         Arrays.fill(row.mTypes, Cursor.FIELD_TYPE_NULL);
76         instance.mRows.add(row);
77         return true;
78     }
79 
put(long windowPtr, String value, int type, int row, int column)80     private static boolean put(long windowPtr, String value, int type, int row, int column) {
81         CursorWindow_ravenwood instance = sInstances.get(windowPtr);
82         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
83             return false;
84         }
85         Row r = instance.mRows.get(row);
86         r.mFields[column] = value;
87         r.mTypes[column] = type;
88         return true;
89     }
90 
nativeGetType(long windowPtr, int row, int column)91     public static int nativeGetType(long windowPtr, int row, int column) {
92         CursorWindow_ravenwood instance = sInstances.get(windowPtr);
93         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
94             return Cursor.FIELD_TYPE_NULL;
95         }
96 
97         return instance.mRows.get(row).mTypes[column];
98     }
99 
nativePutString(long windowPtr, String value, int row, int column)100     public static boolean nativePutString(long windowPtr, String value,
101             int row, int column) {
102         return put(windowPtr, value, Cursor.FIELD_TYPE_STRING, row, column);
103     }
104 
nativeGetString(long windowPtr, int row, int column)105     public static String nativeGetString(long windowPtr, int row, int column) {
106         CursorWindow_ravenwood instance = sInstances.get(windowPtr);
107         if (row >= instance.mRows.size() || column >= instance.mColumnNum) {
108             return null;
109         }
110 
111         return instance.mRows.get(row).mFields[column];
112     }
113 
nativePutLong(long windowPtr, long value, int row, int column)114     public static boolean nativePutLong(long windowPtr, long value, int row, int column) {
115         return put(windowPtr, Long.toString(value), Cursor.FIELD_TYPE_INTEGER, row, column);
116     }
117 
nativeGetLong(long windowPtr, int row, int column)118     public static long nativeGetLong(long windowPtr, int row, int column) {
119         String value = nativeGetString(windowPtr, row, column);
120         if (value == null) {
121             return 0;
122         }
123 
124         Number number = new DecimalFormat().parse(value, new ParsePosition(0));
125         return number == null ? 0 : number.longValue();
126     }
127 
nativePutDouble(long windowPtr, double value, int row, int column)128     public static boolean nativePutDouble(long windowPtr, double value, int row, int column) {
129         return put(windowPtr, Double.toString(value), Cursor.FIELD_TYPE_FLOAT, row, column);
130     }
131 
nativeGetDouble(long windowPtr, int row, int column)132     public static double nativeGetDouble(long windowPtr, int row, int column) {
133         String value = nativeGetString(windowPtr, row, column);
134         if (value == null) {
135             return 0;
136         }
137 
138         Number number = new DecimalFormat().parse(value, new ParsePosition(0));
139         return number == null ? 0 : number.doubleValue();
140     }
141 
nativePutBlob(long windowPtr, byte[] value, int row, int column)142     public static boolean nativePutBlob(long windowPtr, byte[] value, int row, int column) {
143         return put(windowPtr, value == null ? null : Base64.encodeToString(value, 0),
144                 Cursor.FIELD_TYPE_BLOB, row, column);
145     }
146 
nativeGetBlob(long windowPtr, int row, int column)147     public static byte[] nativeGetBlob(long windowPtr, int row, int column) {
148         int type = nativeGetType(windowPtr, row, column);
149         switch (type) {
150             case Cursor.FIELD_TYPE_BLOB: {
151                 String value = nativeGetString(windowPtr, row, column);
152                 return value == null ? null : Base64.decode(value, 0);
153             }
154             case Cursor.FIELD_TYPE_STRING: {
155                 String value = nativeGetString(windowPtr, row, column);
156                 return value == null ? null : value.getBytes();
157             }
158             case Cursor.FIELD_TYPE_FLOAT:
159                 throw new SQLiteException();
160             case Cursor.FIELD_TYPE_INTEGER:
161                 throw new SQLiteException();
162             case Cursor.FIELD_TYPE_NULL:
163             default:
164                 return null;
165         }
166     }
167 
nativeWriteToParcel(long windowPtr, Parcel parcel)168     public static void nativeWriteToParcel(long windowPtr, Parcel parcel) {
169         CursorWindow_ravenwood window = sInstances.get(windowPtr);
170         parcel.writeString(window.mName);
171         parcel.writeInt(window.mColumnNum);
172         parcel.writeInt(window.mRows.size());
173         for (int row = 0; row < window.mRows.size(); row++) {
174             parcel.writeStringArray(window.mRows.get(row).mFields);
175             parcel.writeIntArray(window.mRows.get(row).mTypes);
176         }
177     }
178 
nativeCreateFromParcel(Parcel parcel)179     public static long nativeCreateFromParcel(Parcel parcel) {
180         long windowPtr = nativeCreate(null, 0);
181         CursorWindow_ravenwood window = sInstances.get(windowPtr);
182         window.mName = parcel.readString();
183         window.mColumnNum = parcel.readInt();
184         int rowCount = parcel.readInt();
185         for (int row = 0; row < rowCount; row++) {
186             Row r = new Row();
187             r.mFields = parcel.createStringArray();
188             r.mTypes = parcel.createIntArray();
189             window.mRows.add(r);
190         }
191         return windowPtr;
192     }
193 }
194