12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /*
- * Copyright (C) 2018 Drake, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.drake.net.body
- import android.os.SystemClock
- import com.drake.net.component.Progress
- import com.drake.net.interfaces.ProgressListener
- import okhttp3.MediaType
- import okhttp3.RequestBody
- import okio.*
- import java.io.IOException
- import java.util.concurrent.ConcurrentLinkedQueue
- class NetRequestBody(
- private val requestBody: RequestBody,
- private val progressListeners: ConcurrentLinkedQueue<ProgressListener>? = null
- ) : RequestBody() {
- private val progress = Progress()
- val contentLength by lazy { requestBody.contentLength() }
- override fun contentType(): MediaType? {
- return requestBody.contentType()
- }
- @Throws(IOException::class)
- override fun contentLength(): Long {
- return contentLength
- }
- @Throws(IOException::class)
- override fun writeTo(sink: BufferedSink) {
- if (sink is Buffer ||
- sink.toString().contains("com.android.tools.profiler.support.network.HttpTracker\$OutputStreamTracker")) {
- requestBody.writeTo(sink)
- } else {
- val bufferedSink: BufferedSink = sink.toProgress().buffer()
- requestBody.writeTo(bufferedSink)
- bufferedSink.close()
- }
- }
- /**
- * 复制一段指定长度的字符串内容
- * @param byteCount 复制的字节长度. 如果-1则返回完整的字符串内容
- * @param discard 如果实际长度大于指定长度则直接返回null. 可以保证数据完整性
- */
- fun peekString(byteCount: Long = 1024 * 1024, discard: Boolean = false): String {
- val buffer = Buffer()
- requestBody.writeTo(buffer)
- if (discard && buffer.size > byteCount) return ""
- val byteCountFinal = if (byteCount < 0) buffer.size else minOf(buffer.size, byteCount)
- return buffer.readUtf8(byteCountFinal)
- }
- private fun Sink.toProgress() = object : ForwardingSink(this) {
- var writeByteCount = 0L
- @Throws(IOException::class)
- override fun write(source: Buffer, byteCount: Long) {
- super.write(source, byteCount)
- writeByteCount += byteCount
- if (progressListeners != null) {
- val currentElapsedTime = SystemClock.elapsedRealtime()
- progressListeners.forEach { progressListener ->
- progressListener.intervalByteCount += byteCount
- val currentInterval = currentElapsedTime - progressListener.elapsedTime
- if (currentInterval >= progressListener.interval || writeByteCount == contentLength) {
- progressListener.onProgress(
- progress.apply {
- currentByteCount = writeByteCount
- totalByteCount = contentLength
- intervalByteCount = progressListener.intervalByteCount
- intervalTime = currentInterval
- }
- )
- progressListener.elapsedTime = currentElapsedTime
- progressListener.intervalByteCount = 0L
- }
- }
- }
- }
- }
- }
|