BodyExtension.kt 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package com.drake.net.body
  2. import com.drake.net.interfaces.ProgressListener
  3. import okhttp3.MultipartBody
  4. import okhttp3.RequestBody
  5. import okhttp3.ResponseBody
  6. import okhttp3.ResponseBody.Companion.asResponseBody
  7. import okio.Buffer
  8. import java.util.concurrent.ConcurrentLinkedQueue
  9. fun RequestBody.toNetRequestBody(listeners: ConcurrentLinkedQueue<ProgressListener>? = null) = run {
  10. NetRequestBody(this, listeners)
  11. }
  12. fun ResponseBody.toNetResponseBody(
  13. listeners: ConcurrentLinkedQueue<ProgressListener>? = null,
  14. complete: (() -> Unit)? = null
  15. ) = run { NetResponseBody(this, listeners, complete) }
  16. /**
  17. * 复制一段指定长度的字符串内容
  18. * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
  19. */
  20. @JvmName("peekString")
  21. fun RequestBody?.peekString(byteCount: Long = 1024 * 1024, discard: Boolean = false): String? {
  22. return when (this) {
  23. null -> return null
  24. is NetRequestBody -> peekString(byteCount, discard)
  25. else -> {
  26. val buffer = Buffer()
  27. writeTo(buffer)
  28. if (discard && buffer.size > byteCount) return ""
  29. val byteCountFinal = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
  30. buffer.readUtf8(byteCountFinal)
  31. }
  32. }
  33. }
  34. /**
  35. * 复制一段指定长度的字符串内容
  36. * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
  37. */
  38. fun ResponseBody.peekString(byteCount: Long = 1024 * 1024 * 4, discard: Boolean = false): String {
  39. return when (this) {
  40. is NetResponseBody -> peekString(byteCount, discard)
  41. else -> {
  42. val peeked = source().peek()
  43. val buffer = Buffer()
  44. peeked.request(byteCount)
  45. val byteCountFinal =
  46. if (byteCount < 0) peeked.buffer.size else minOf(byteCount, peeked.buffer.size)
  47. buffer.write(peeked, byteCountFinal)
  48. if (discard && buffer.size > byteCount) return ""
  49. buffer.asResponseBody(contentType(), byteCountFinal).string()
  50. }
  51. }
  52. }
  53. /**
  54. * 通过判断[okhttp3.Headers]里面的Content-Disposition是否存在filename属性来确定是否为文件类型[MultipartBody.Part]
  55. */
  56. fun MultipartBody.Part.isFile(): Boolean {
  57. val contentDisposition = headers?.get("Content-Disposition") ?: return false
  58. return ";\\s${"filename"}=\"(.+?)\"".toRegex().find(contentDisposition)?.groupValues?.getOrNull(1) != null
  59. }
  60. /**
  61. * 返回Content-Disposition里面的字段名称
  62. */
  63. fun MultipartBody.Part.name(): String? {
  64. val contentDisposition = headers?.get("Content-Disposition") ?: return null
  65. return ";\\s${"name"}=\"(.+?)\"".toRegex().find(contentDisposition)?.groupValues?.getOrNull(1) ?: ""
  66. }
  67. /**
  68. * 将[MultipartBody.Part.body]作为字符串返回
  69. * 如果[MultipartBody.Part]是文件类型则返回的是文件名称, 确定文件类型请参考[MultipartBody.Part.isFile]
  70. */
  71. fun MultipartBody.Part.value(): String? {
  72. val contentDisposition = headers?.get("Content-Disposition") ?: return null
  73. return ";\\s${"filename"}=\"(.+?)\"".toRegex().find(contentDisposition)?.groupValues?.getOrNull(1)
  74. ?: body.peekString()
  75. }