Skip to content

Commit

Permalink
Minor documentation fixes and clean up. (#1122)
Browse files Browse the repository at this point in the history
* Minor documentation fixes and clean up.

* Docs.

* Fix.

* Docs.
  • Loading branch information
colinrtwhite authored Feb 3, 2022
1 parent 5215ae7 commit 090a6d7
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 69 deletions.
4 changes: 2 additions & 2 deletions coil-base/api/coil-base.api
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ public final class coil/decode/ImageSources {
public static final fun create (Lokio/BufferedSource;Landroid/content/Context;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/BufferedSource;Landroid/content/Context;Lcoil/decode/ImageSource$Metadata;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/BufferedSource;Ljava/io/File;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/BufferedSource;Lokio/Path;Lokio/FileSystem;Lcoil/decode/ImageSource$Metadata;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/BufferedSource;Ljava/io/File;Lcoil/decode/ImageSource$Metadata;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/Path;Lokio/FileSystem;Ljava/lang/String;Ljava/io/Closeable;)Lcoil/decode/ImageSource;
public static final fun create (Lokio/Path;Lokio/FileSystem;Ljava/lang/String;Ljava/io/Closeable;Lcoil/decode/ImageSource$Metadata;)Lcoil/decode/ImageSource;
public static synthetic fun create$default (Lokio/BufferedSource;Landroid/content/Context;Lcoil/decode/ImageSource$Metadata;ILjava/lang/Object;)Lcoil/decode/ImageSource;
public static synthetic fun create$default (Lokio/BufferedSource;Lokio/Path;Lokio/FileSystem;Lcoil/decode/ImageSource$Metadata;ILjava/lang/Object;)Lcoil/decode/ImageSource;
public static synthetic fun create$default (Lokio/BufferedSource;Ljava/io/File;Lcoil/decode/ImageSource$Metadata;ILjava/lang/Object;)Lcoil/decode/ImageSource;
public static synthetic fun create$default (Lokio/Path;Lokio/FileSystem;Ljava/lang/String;Ljava/io/Closeable;ILjava/lang/Object;)Lcoil/decode/ImageSource;
public static synthetic fun create$default (Lokio/Path;Lokio/FileSystem;Ljava/lang/String;Ljava/io/Closeable;Lcoil/decode/ImageSource$Metadata;ILjava/lang/Object;)Lcoil/decode/ImageSource;
}
Expand Down
48 changes: 24 additions & 24 deletions coil-base/src/main/java/coil/decode/ImageSource.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ import java.io.File
* Create a new [ImageSource] backed by a [File].
*
* @param file The file to read from.
* @param fileSystem The file system which contains [file].
* @param diskCacheKey An optional cache key for the [file] in the disk cache.
* @param closeable An optional closeable reference that will
* be closed when the image source is closed.
* @param closeable An optional closeable reference that will be closed when the image source is closed.
*/
@JvmName("create")
fun ImageSource(
Expand All @@ -40,9 +40,9 @@ fun ImageSource(
* Create a new [ImageSource] backed by a [File].
*
* @param file The file to read from.
* @param fileSystem The file system which contains [file].
* @param diskCacheKey An optional cache key for the [file] in the disk cache.
* @param closeable An optional closeable reference that will
* be closed when the image source is closed.
* @param closeable An optional closeable reference that will be closed when the image source is closed.
* @param metadata Metadata for this image source.
*/
@ExperimentalCoilApi
Expand All @@ -65,7 +65,7 @@ fun ImageSource(
fun ImageSource(
source: BufferedSource,
context: Context,
): ImageSource = SourceImageSource(source, context.safeCacheDir.toOkioPath(), FileSystem.SYSTEM, null)
): ImageSource = SourceImageSource(source, context.safeCacheDir, null)

/**
* Create a new [ImageSource] backed by a [BufferedSource].
Expand All @@ -80,37 +80,34 @@ fun ImageSource(
source: BufferedSource,
context: Context,
metadata: ImageSource.Metadata? = null,
): ImageSource = SourceImageSource(source, context.safeCacheDir.toOkioPath(), FileSystem.SYSTEM, metadata)
): ImageSource = SourceImageSource(source, context.safeCacheDir, metadata)

/**
* Create a new [ImageSource] backed by a [BufferedSource].
*
* @param source The buffered source to read from.
* @param cacheDirectory The directory to create temporary files in
* if [ImageSource.file] is called.
* @param cacheDirectory The directory to create temporary files in if [ImageSource.file] is called.
*/
@JvmName("create")
fun ImageSource(
source: BufferedSource,
cacheDirectory: File,
): ImageSource = SourceImageSource(source, cacheDirectory.toOkioPath(), FileSystem.SYSTEM, null)
): ImageSource = SourceImageSource(source, cacheDirectory, null)

/**
* Create a new [ImageSource] backed by a [BufferedSource].
*
* @param source The buffered source to read from.
* @param cacheDirectory The directory to create temporary files in
* if [ImageSource.file] is called.
* @param cacheDirectory The directory to create temporary files in if [ImageSource.file] is called.
* @param metadata Metadata for this image source.
*/
@ExperimentalCoilApi
@JvmName("create")
fun ImageSource(
source: BufferedSource,
cacheDirectory: Path,
fileSystem: FileSystem = FileSystem.SYSTEM,
cacheDirectory: File,
metadata: ImageSource.Metadata? = null,
): ImageSource = SourceImageSource(source, cacheDirectory, fileSystem, metadata)
): ImageSource = SourceImageSource(source, cacheDirectory, metadata)

/**
* Provides access to the image data to be decoded.
Expand All @@ -135,20 +132,21 @@ sealed class ImageSource : Closeable {
abstract fun sourceOrNull(): BufferedSource?

/**
* Return a [File] containing this [ImageSource]'s data.
* Return a [Path] that resolves to a file containing this [ImageSource]'s data.
*
* If this image source is backed by a [BufferedSource], a temporary file containing this
* [ImageSource]'s data will be created.
*/
abstract fun file(): Path

/**
* Return a [File] containing this [ImageSource]'s data if one has already been created.
* Else, return 'null'.
* Return a [Path] that resolves to a file containing this [ImageSource]'s data if one has
* already been created. Else, return 'null'.
*/
abstract fun fileOrNull(): Path?

/**
* The [FileSystem] which contains the file, or [FileSystem.SYSTEM] if none.
* The [FileSystem] which contains the [file].
*/
abstract val fileSystem: FileSystem

Expand Down Expand Up @@ -241,8 +239,7 @@ internal class FileImageSource(

internal class SourceImageSource(
source: BufferedSource,
private val cacheDirectory: Path,
override val fileSystem: FileSystem,
private val cacheDirectory: File,
override val metadata: Metadata?
) : ImageSource() {

Expand All @@ -251,9 +248,11 @@ internal class SourceImageSource(
private var file: Path? = null

init {
require(fileSystem.metadata(cacheDirectory).isDirectory) { "cacheDirectory must be a directory." }
require(cacheDirectory.isDirectory) { "cacheDirectory must be a directory." }
}

override val fileSystem get() = FileSystem.SYSTEM

@Synchronized
override fun source(): BufferedSource {
assertNotClosed()
Expand All @@ -269,9 +268,10 @@ internal class SourceImageSource(
file?.let { return it }

// Copy the source to a temp file.
val tempFile = File.createTempFile("tmp", null, cacheDirectory.toFile()).toOkioPath()
// Replace JVM call with https://github.com/square/okio/issues/1090 once it's available.
val tempFile = File.createTempFile("tmp", null, cacheDirectory).toOkioPath()
fileSystem.write(tempFile) {
this.writeAll(source!!)
writeAll(source!!)
}
source = null
return tempFile.also { file = it }
Expand All @@ -287,7 +287,7 @@ internal class SourceImageSource(
override fun close() {
isClosed = true
source?.closeQuietly()
file?.let { fileSystem.delete(it) }
file?.let(fileSystem::delete)
}

private fun assertNotClosed() {
Expand Down
11 changes: 4 additions & 7 deletions coil-base/src/main/java/coil/disk/DiskCache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import okio.Path.Companion.toOkioPath
import java.io.File

/**
* An LRU cache of [File]s.
* An LRU cache of files.
*/
@ExperimentalCoilApi
interface DiskCache {
Expand All @@ -28,7 +28,7 @@ interface DiskCache {
/** The directory where the cache stores its data. */
val directory: Path

/** The directory where the cache stores its data. */
/** The file system that contains the cache's files. */
val fileSystem: FileSystem

/**
Expand Down Expand Up @@ -122,10 +122,7 @@ interface DiskCache {
* IMPORTANT: It is an error to have two [DiskCache] instances active in the same
* directory at the same time as this can corrupt the disk cache.
*/
fun directory(directory: File) = apply {
this.directory = directory.toOkioPath()
this.fileSystem = FileSystem.SYSTEM
}
fun directory(directory: File) = directory(directory.toOkioPath())

/**
* Set the [directory] where the cache stores its data.
Expand All @@ -138,7 +135,7 @@ interface DiskCache {
}

/**
* Set the fileSystem where the cache stores its data, usually [FileSystem.SYSTEM].
* Set the [fileSystem] where the cache stores its data, usually [FileSystem.SYSTEM].
*/
fun fileSystem(fileSystem: FileSystem) = apply {
this.fileSystem = fileSystem
Expand Down
2 changes: 2 additions & 0 deletions coil-base/src/main/java/coil/disk/RealDiskCache.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ internal class RealDiskCache(
private fun String.hash() = encodeUtf8().sha256().hex()

private class RealSnapshot(private val snapshot: DiskLruCache.Snapshot) : Snapshot {

override val metadata get() = snapshot.file(ENTRY_METADATA)
override val data get() = snapshot.file(ENTRY_DATA)

Expand All @@ -52,6 +53,7 @@ internal class RealDiskCache(
}

private class RealEditor(private val editor: DiskLruCache.Editor) : Editor {

override val metadata get() = editor.file(ENTRY_METADATA)
override val data get() = editor.file(ENTRY_DATA)

Expand Down
72 changes: 45 additions & 27 deletions coil-base/src/main/java/coil/fetch/HttpUriFetcher.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import okhttp3.MediaType
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okio.FileSystem
import okio.IOException
import java.net.HttpURLConnection.HTTP_NOT_MODIFIED

Expand All @@ -35,8 +34,6 @@ internal class HttpUriFetcher(
private val diskCache: Lazy<DiskCache?>,
private val respectCacheHeaders: Boolean
) : Fetcher {
val fileSystem: FileSystem
get() = diskCache.value!!.fileSystem

override suspend fun fetch(): FetchResult {
var snapshot = readFromDiskCache()
Expand Down Expand Up @@ -95,10 +92,10 @@ internal class HttpUriFetcher(
return SourceResult(
source = responseBody.toImageSource(),
mimeType = getMimeType(url, responseBody.contentType()),
dataSource = if (response.networkResponse != null) DataSource.NETWORK else DataSource.DISK
dataSource = response.toDataSource()
)
} catch (e: Exception) {
responseBody.closeQuietly()
response.closeQuietly()
throw e
}
} catch (e: Exception) {
Expand All @@ -108,7 +105,11 @@ internal class HttpUriFetcher(
}

private fun readFromDiskCache(): DiskCache.Snapshot? {
return if (options.diskCachePolicy.readEnabled) diskCache.value?.get(diskCacheKey) else null
return if (options.diskCachePolicy.readEnabled) {
diskCache.value?.get(diskCacheKey)
} else {
null
}
}

private fun writeToDiskCache(
Expand All @@ -123,36 +124,39 @@ internal class HttpUriFetcher(
return null
}

// Open a new editor.
val editor = if (snapshot != null) {
snapshot.closeAndEdit()
} else {
diskCache.value?.edit(diskCacheKey)
} ?: return null
}
if (editor == null) return null

try {
response.use {
// Write the response to the disk cache.
if (response.code == HTTP_NOT_MODIFIED && cacheResponse != null) {
// Only update the metadata.
val combinedResponse = response.newBuilder()
.headers(combineHeaders(CacheResponse(response).responseHeaders, response.headers))
.build()
fileSystem.write(editor.metadata) {
CacheResponse(combinedResponse).writeTo(this)
}
} else {
// Update the metadata and the image data.
fileSystem.write(editor.metadata) {
CacheResponse(response).writeTo(this)
}
fileSystem.write(editor.data) {
response.body!!.source().readAll(this)
}
// Write the response to the disk cache.
if (response.code == HTTP_NOT_MODIFIED && cacheResponse != null) {
// Only update the metadata.
val combinedResponse = response.newBuilder()
.headers(combineHeaders(CacheResponse(response).responseHeaders, response.headers))
.build()
fileSystem.write(editor.metadata) {
CacheResponse(combinedResponse).writeTo(this)
}
} else {
// Update the metadata and the image data.
fileSystem.write(editor.metadata) {
CacheResponse(response).writeTo(this)
}
fileSystem.write(editor.data) {
response.body!!.source().readAll(this)
}
}
return editor.commitAndGet()
} catch (e: Exception) {
editor.abortQuietly()
throw e
} finally {
response.closeQuietly()
}
}

Expand Down Expand Up @@ -238,15 +242,29 @@ internal class HttpUriFetcher(
}

private fun DiskCache.Snapshot.toImageSource(): ImageSource {
return ImageSource(file = data, fileSystem = fileSystem, diskCacheKey = diskCacheKey, closeable = this)
return ImageSource(
file = data,
fileSystem = fileSystem,
diskCacheKey = diskCacheKey,
closeable = this
)
}

private fun ResponseBody.toImageSource(): ImageSource {
return ImageSource(source = source(), context = options.context)
return ImageSource(
source = source(),
context = options.context
)
}

private fun Response.toDataSource(): DataSource {
return if (networkResponse != null) DataSource.NETWORK else DataSource.DISK
}

private val diskCacheKey get() = options.diskCacheKey ?: url

private val fileSystem get() = diskCache.value!!.fileSystem

class Factory(
private val callFactory: Lazy<Call.Factory>,
private val diskCache: Lazy<DiskCache?>,
Expand Down
4 changes: 0 additions & 4 deletions coil-base/src/main/java/coil/util/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import coil.transform.Transformation
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.ExperimentalCoroutinesApi
import okhttp3.Headers
import okio.Path
import java.io.Closeable
import java.io.File

Expand Down Expand Up @@ -272,6 +271,3 @@ internal object SingletonDiskCache {
}
}
}

internal val Path.extension: String
get() = name.substringAfterLast('.', "")
Loading

0 comments on commit 090a6d7

Please sign in to comment.