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

dorkbox.bytes.ByteArrayWrapper.kt Maven / Gradle / Ivy

There is a newer version: 2.1
Show newest version
/*
 * Copyright 2023 dorkbox, llc
 *
 * 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 dorkbox.bytes

/**
 * Necessary to provide equals and hashcode methods on a byte arrays, if they are to be used as keys in a map/set/etc
 */
class ByteArrayWrapper(
    data: ByteArray,

    /**
     * if TRUE, then the byteArray is copied. if FALSE, the byte array is used as-is.
     *
     * Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well.
     */
    copyBytes: Boolean = true
) {
    companion object {
        /**
         * Gets the version number.
         */
        const val version = BytesInfo.version

        /**
         * Makes a safe copy of the byte array, so that changes to the original do not affect the wrapper.
         * One side effect is that additional memory is used.
         */
        fun copy(data: ByteArray): ByteArrayWrapper {
            return ByteArrayWrapper(data, true)
        }

        /**
         * Does not make a copy of the data, so changes to the original will also affect the wrapper.
         * One side effect is that no extra memory is needed.
         */
        fun wrap(data: ByteArray): ByteArrayWrapper {
            return ByteArrayWrapper(data, false)
        }
    }


    val bytes: ByteArray
    private var hashCode: Int? = null


    init {
        val length = data.size

        if (copyBytes) {
            bytes = ByteArray(length)
            // copy so it's immutable as a key.
            System.arraycopy(data, 0, bytes, 0, length)
        } else {
            bytes = data
        }
    }

    override fun hashCode(): Int {
        // might be null for a thread because it's stale. who cares, get the value again
        var hashCode = hashCode
        if (hashCode == null) {
            hashCode = bytes.contentHashCode()
            this.hashCode = hashCode
        }
        return hashCode
    }

    override fun equals(other: Any?): Boolean {
        return if (other !is ByteArrayWrapper) {
            false
        } else bytes.contentEquals(other.bytes)

        // CANNOT be null, so we don't have to null check!
    }

    override fun toString(): String {
        return "ByteArrayWrapper " + bytes.contentToString()
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy