All Downloads are FREE. Search and download functionalities are using the official Maven repository.

nonJvmMain.okio.HashingSource.kt Maven / Gradle / Ivy

There is a newer version: 2.0.0.0-RC3
Show newest version
/*
 * Copyright (C) 2020 Square, 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 okio

import okio.internal.HashFunction
import okio.internal.Hmac
import okio.internal.Md5
import okio.internal.Sha1
import okio.internal.Sha256
import okio.internal.Sha512

actual class HashingSource internal constructor(
  private val source: Source,
  private val hashFunction: HashFunction,
) : Source {

  override fun read(sink: Buffer, byteCount: Long): Long {
    val result = source.read(sink, byteCount)

    if (result != -1L) {
      var start = sink.size - result

      // Find the first segment that has new bytes.
      var offset = sink.size
      var s = sink.head!!
      while (offset > start) {
        s = s.prev!!
        offset -= (s.limit - s.pos).toLong()
      }

      // Hash that segment and all the rest until the end.
      while (offset < sink.size) {
        val pos = (s.pos + start - offset).toInt()
        hashFunction.update(s.data, pos, s.limit - pos)
        offset += s.limit - s.pos
        start = offset
        s = s.next!!
      }
    }

    return result
  }

  override fun timeout(): Timeout =
    source.timeout()

  override fun close() =
    source.close()

  actual val hash: ByteString
    get() {
      val result = hashFunction.digest()
      return ByteString(result)
    }

  actual companion object {

    /** Returns a source that uses the obsolete MD5 hash algorithm to produce 128-bit hashes. */
    actual fun md5(source: Source) = HashingSource(source, Md5())

    /** Returns a source that uses the obsolete SHA-1 hash algorithm to produce 160-bit hashes. */
    actual fun sha1(source: Source) = HashingSource(source, Sha1())

    /** Returns a source that uses the SHA-256 hash algorithm to produce 256-bit hashes. */
    actual fun sha256(source: Source) = HashingSource(source, Sha256())

    /** Returns a source that uses the SHA-512 hash algorithm to produce 512-bit hashes. */
    actual fun sha512(source: Source) = HashingSource(source, Sha512())

    /** Returns a source that uses the obsolete SHA-1 HMAC algorithm to produce 160-bit hashes. */
    actual fun hmacSha1(source: Source, key: ByteString) = HashingSource(source, Hmac.sha1(key))

    /** Returns a source that uses the SHA-256 HMAC algorithm to produce 256-bit hashes. */
    actual fun hmacSha256(source: Source, key: ByteString) = HashingSource(source, Hmac.sha256(key))

    /** Returns a source that uses the SHA-512 HMAC algorithm to produce 512-bit hashes. */
    actual fun hmacSha512(source: Source, key: ByteString) = HashingSource(source, Hmac.sha512(key))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy