1 /*
2  * Copyright (C) 2024 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 com.android.intentresolver.util.cursor
18 
19 import android.database.Cursor
20 
21 /** A [CursorView] that produces chunks/pages from an underlying cursor. */
22 interface PagedCursor<out E> : CursorView<Sequence<E?>> {
23     /** The configured size of each page produced by this cursor. */
24     val pageSize: Int
25 }
26 
27 /** Returns a [PagedCursor] that produces pages of data from the given [CursorView]. */
pagednull28 fun <E> CursorView<E>.paged(pageSize: Int): PagedCursor<E> =
29     object : PagedCursor<E>, Cursor by this@paged {
30 
31         init {
32             check(pageSize > 0) { "pageSize must be greater than 0" }
33         }
34 
35         override val pageSize: Int = pageSize
36 
37         override fun getCount(): Int =
38             this@paged.count.let { it / pageSize + minOf(1, it % pageSize) }
39 
40         override fun getPosition(): Int =
41             (this@paged.position / pageSize).let { if (this@paged.position < 0) it - 1 else it }
42 
43         override fun moveToNext(): Boolean = moveToPosition(position + 1)
44 
45         override fun moveToPrevious(): Boolean = moveToPosition(position - 1)
46 
47         override fun moveToPosition(position: Int): Boolean =
48             this@paged.moveToPosition(position * pageSize)
49 
50         override fun readRow(): Sequence<E?> =
51             this@paged.startAt(position * pageSize).limit(pageSize).asSequence()
52     }
53