Skip to content

Commit

Permalink
合并拉取请求 #779
Browse files Browse the repository at this point in the history
pref: JVM 中部分 Resource 实现增加与 Charset 相关的参数或API;优化部分实现的 toString 等内容
  • Loading branch information
ForliyScarlet authored Feb 3, 2024
1 parent 7ea0e53 commit a3a59e8
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ import kotlin.jvm.JvmName
*
* [Resource] 提供了一个基于 [Base64] 进行序列化操作的 [ResourceBase64Serializer]。
*
* ## 第三方实现不稳定
*
* [Resource] 主要由内部实现,不保证对第三方实现的稳定与兼容
*
* @author ForteScarlet
*/
public interface Resource {
Expand Down Expand Up @@ -119,6 +123,12 @@ private data class ByteArrayResourceImpl(private val raw: ByteArray) : ByteArray
override fun hashCode(): Int {
return raw.contentHashCode()
}

override fun toString(): String = buildString {
append("ByteArrayResource(raw=")
raw.joinTo(buffer = this, separator = ", ", prefix = "[", postfix = "]", limit = 8)
append(")")
}
}

/**
Expand All @@ -142,4 +152,18 @@ public fun String.toStringResource(): StringResource = StringResourceImpl(this)
private data class StringResourceImpl(private val string: String) : StringResource {
override fun string(): String = string
override fun data(): ByteArray = string().encodeToByteArray()
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is StringResourceImpl) return false

if (string != other.string) return false

return true
}

override fun hashCode(): Int {
return string.hashCode()
}

override fun toString(): String = "StringResource(string=\"$string\")"
}
172 changes: 139 additions & 33 deletions simbot-api/src/jvmMain/kotlin/love/forte/simbot/resource/Resource.jvm.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import java.nio.file.OpenOption
import java.nio.file.Path
import kotlin.io.path.inputStream
import kotlin.io.path.readBytes
import kotlin.io.path.readText
import kotlin.io.path.reader

/**
Expand All @@ -51,33 +50,69 @@ public interface InputStreamResource : Resource {
* 默认通过 [inputStream] 读取。
*
*/
@Throws(Exception::class)
@Throws(IOException::class)
override fun data(): ByteArray = inputStream().use { it.readAllBytes() }

/**
* 获取可用于读取当前资源数据的输入流。
*/
@Throws(Exception::class)
@Throws(IOException::class)
public fun inputStream(): InputStream
}

/**
* 在 JVM 平台下对 [StringResource] 的额外扩展,
* 与 [StringResource] 相比,对相关方法增加了 [Charset] 参数。
* 默认情况下使用 [Charsets.UTF_8] 格式编码。
*/
public interface JVMStringResource : StringResource {
/**
* 读取此资源的 [String] 内容。
* 默认使用 [DEFAULT_CHARSET] 编码。
*/
@Throws(IOException::class)
override fun string(): String = string(DEFAULT_CHARSET)

/**
* 读取此资源的 [String] 内容。
*/
@Throws(IOException::class)
public fun string(charset: Charset): String


public companion object {
/**
* 默认编码格式: [Charsets.UTF_8]
*/
@JvmField
public val DEFAULT_CHARSET: Charset = Charsets.UTF_8
}
}

/**
* 能够获取到 [Reader] 资源的 [Resource] 扩展实现。
*
* @author forte
*/
public interface ReaderResource : StringResource {
public interface ReaderResource : JVMStringResource {
/**
* 读取当前资源的字符串数据。
*/
@Throws(Exception::class)
override fun string(): String = reader().use { it.readText() }
@Throws(IOException::class)
override fun string(charset: Charset): String = reader(charset).use { it.readText() }

/**
* 获取可用于读取当前资源数据的读取流。
* 默认使用 [JVMStringResource.DEFAULT_CHARSET] 编码。
*/
@Throws(Exception::class)
public fun reader(): Reader
@Throws(IOException::class)
public fun reader(): Reader = reader(JVMStringResource.DEFAULT_CHARSET)

/**
* 获取可用于读取当前资源数据的读取流。
*/
@Throws(IOException::class)
public fun reader(charset: Charset): Reader
}

/**
Expand All @@ -99,12 +134,20 @@ public interface FileResource : InputStreamResource, ReaderResource {
@Throws(FileNotFoundException::class)
override fun inputStream(): InputStream = file.inputStream()

/**
* 从与此资源关联的 [File] 创建新的 [Reader]。
* 默认使用 [JVMStringResource.DEFAULT_CHARSET] 编码。
* @throws FileNotFoundException 如果文件不存在
*/
@Throws(FileNotFoundException::class)
override fun reader(): Reader = reader(JVMStringResource.DEFAULT_CHARSET)

/**
* 从与此资源关联的 [File] 创建新的 [Reader]
* @throws FileNotFoundException 如果文件不存在
*/
@Throws(FileNotFoundException::class)
override fun reader(): Reader
override fun reader(charset: Charset): Reader

/**
* 将与此资源关联的 [File] 读取为字节数组
Expand All @@ -113,26 +156,57 @@ public interface FileResource : InputStreamResource, ReaderResource {
@Throws(IOException::class)
override fun data(): ByteArray = file.readBytes()

/**
* 将与此资源关联的 [File] 读取为字符串。
* 默认使用 [JVMStringResource.DEFAULT_CHARSET] 编码。
* @throws IOException 如果文件无法读取
*/
@Throws(IOException::class)
override fun string(): String = string(JVMStringResource.DEFAULT_CHARSET)

/**
* 将与此资源关联的 [File] 读取为字符串
* @throws IOException 如果文件无法读取
*/
@Throws(IOException::class)
override fun string(): String
override fun string(charset: Charset): String
}

/**
* Converts a [File] to a [FileResource].
* [charset] 会作为需要使用编码参数的方法的默认编码。
* 默认使用 [JVMStringResource.DEFAULT_CHARSET]。
*
* @return The converted [FileResource].
*/
@JvmName("valueOf")
@JvmOverloads
public fun File.toResource(charset: Charset = Charsets.UTF_8): FileResource = FileResourceImpl(this, charset)
public fun File.toResource(charset: Charset = JVMStringResource.DEFAULT_CHARSET): FileResource =
FileResourceImpl(this, charset)

private data class FileResourceImpl(override val file: File, private val charset: Charset) : FileResource {
override fun string(): String = file.readText(charset)
override fun reader(): Reader = file.reader(charset)
override fun string(): String = string(charset)
override fun reader(): Reader = reader(charset)

override fun string(charset: Charset): String = file.readText(charset)
override fun reader(charset: Charset): Reader = file.reader(charset)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is FileResourceImpl) return false

if (file != other.file) return false
if (charset != other.charset) return false

return true
}

override fun hashCode(): Int {
var result = file.hashCode()
result = 31 * result + charset.hashCode()
return result
}

override fun toString(): String = "FileResource(file=$file, charset=$charset)"
}

/**
Expand All @@ -155,49 +229,56 @@ public interface PathResource : InputStreamResource, ReaderResource {
override fun inputStream(): InputStream

/**
* 从与此资源关联的 [Path] 创建新的 [Reader]
* @throws IOException 如果路径无法打开
* 将与此资源关联的 [Path] 读取为字节数组
* @throws Exception 如果在路径上执行该操作时出现错误
*/
@Throws(IOException::class)
override fun reader(): Reader
override fun data(): ByteArray = path.readBytes()

/**
* 将与此资源关联的 [Path] 读取为字节数组
* @throws Exception 如果在路径上执行该操作时出现错误
* 从与此资源关联的 [Path] 创建新的 [Reader]。
* @throws IOException 如果路径无法打开
*/
@Throws(Exception::class)
override fun data(): ByteArray = path.readBytes()
@Throws(IOException::class)
override fun reader(charset: Charset): Reader

/**
* 将与此资源关联的 [Path] 读取为字符串
* @throws Exception 如果在路径上执行该操作时出现错误
*/
@Throws(Exception::class)
override fun string(): String
@Throws(IOException::class)
override fun string(charset: Charset): String
}

/**
* Converts the given [Path] to a [PathResource] with the specified options.
*
*
* @param charset 读取内容如果需要 [Charset] 信息时的默认值
* @param options the options to use for opening the resource (vararg)
* @return the [PathResource] representing the converted path
*/
@JvmName("valueOf")
@JvmOverloads
public fun Path.toResource(charset: Charset = Charsets.UTF_8, vararg options: OpenOption): PathResource =
public fun Path.toResource(
charset: Charset = JVMStringResource.DEFAULT_CHARSET,
vararg options: OpenOption
): PathResource =
PathResourceImpl(this, charset, options)

private data class PathResourceImpl(
override val path: Path,
private val charset: Charset,
private val openOptions: Array<out OpenOption>
) :
PathResource {
) : PathResource {
override fun inputStream(): InputStream = path.inputStream(options = openOptions)

override fun reader(): Reader = path.reader(charset, options = openOptions)
override fun reader(): Reader = reader(charset)
override fun string(): String = string(charset)

override fun reader(charset: Charset): Reader = path.reader(charset, options = openOptions)
override fun string(charset: Charset): String = reader(charset).use(Reader::readText)

override fun string(): String = path.readText(charset)
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is PathResourceImpl) return false
Expand All @@ -215,14 +296,24 @@ private data class PathResourceImpl(
result = 31 * result + openOptions.contentHashCode()
return result
}

override fun toString(): String = buildString {
append("PathResource(path=")
append(path)
append(", charset=")
append(charset)
append(", openOptions=")
openOptions.joinTo(buffer = this, separator = ", ", prefix = "[", postfix = "]", limit = 8)
append(")")
}
}

/**
* [URIResource] 是一个输入流资源的接口。
*
* @author forte
*/
public interface URIResource : InputStreamResource, StringResource {
public interface URIResource : InputStreamResource, JVMStringResource {
/**
* 与此资源关联的 [URI]
*/
Expand All @@ -248,7 +339,17 @@ public interface URIResource : InputStreamResource, StringResource {
* @throws IOException 如果无法打开输入流,则抛出此异常。具体参看 [URL.openStream][java.net.URL.openStream]
*/
@Throws(IOException::class)
override fun string(): String
override fun string(): String = super.string()

/**
* 读取 [uri] 中的内容并作为字符串返回。
*
* @throws IllegalArgumentException see [URI.toURL]
* @throws MalformedURLException see [URI.toURL]
* @throws IOException 如果无法打开输入流,则抛出此异常。具体参看 [URL.openStream][java.net.URL.openStream]
*/
@Throws(IOException::class)
override fun string(charset: Charset): String
}

/**
Expand All @@ -261,22 +362,26 @@ public interface URIResource : InputStreamResource, StringResource {
* 取而代之的是 [URL.toResource] 可能会产生 [URISyntaxException],
* 因为需要使用 [URL.toURI]。
*
* @param charset 需要使用编码格式时的默认编码值,默认为 [JVMStringResource.DEFAULT_CHARSET]。
* @throws URISyntaxException see [URL.toURI]
* @return The converted [URIResource].
*/
@kotlin.jvm.Throws(URISyntaxException::class)
@JvmName("valueOf")
@JvmOverloads
public fun URL.toResource(charset: Charset = Charsets.UTF_8): URIResource = URIResourceImpl(toURI(), charset, this)
public fun URL.toResource(charset: Charset = JVMStringResource.DEFAULT_CHARSET): URIResource =
URIResourceImpl(toURI(), charset, this)

/**
* Converts the current [URI] to a [URIResource].
*
* @param charset 需要使用编码格式时的默认编码值,默认为 [JVMStringResource.DEFAULT_CHARSET]。
* @return The converted [URIResource].
*/
@JvmName("valueOf")
@JvmOverloads
public fun URI.toResource(charset: Charset = Charsets.UTF_8): URIResource = URIResourceImpl(this, charset, null)
public fun URI.toResource(charset: Charset = JVMStringResource.DEFAULT_CHARSET): URIResource =
URIResourceImpl(this, charset, null)

private class URIResourceImpl(override val uri: URI, val charset: Charset, private var url: URL? = null) : URIResource {
private val urlValue: URL
Expand All @@ -285,7 +390,8 @@ private class URIResourceImpl(override val uri: URI, val charset: Charset, priva
}

override fun inputStream(): InputStream = urlValue.openStream()
override fun string(): String = urlValue.readText(charset)
override fun string(): String = string(charset)
override fun string(charset: Charset): String = urlValue.readText(charset)

override fun toString(): String = "URIResourceImpl(uri=$uri, charset=$charset)"
override fun toString(): String = "URIResource(uri=$uri, charset=$charset)"
}

0 comments on commit a3a59e8

Please sign in to comment.