ByteUtilities/src/dorkbox/bytes/ByteArrayWrapper.kt

93 lines
2.7 KiB
Kotlin
Raw Normal View History

/*
2023-01-24 20:37:56 +01:00
* 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.
*/
2021-08-20 07:42:50 +02:00
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
*/
2021-08-20 07:42:50 +02:00
class ByteArrayWrapper(
data: ByteArray,
/**
2021-08-20 07:42:50 +02:00
* if TRUE, then the byteArray is copied. if FALSE, the byte array is used as-is.
2023-01-24 20:37:56 +01:00
*
2021-08-20 07:42:50 +02:00
* Using FALSE IS DANGEROUS!!!! If the underlying byte array is modified, this changes as well.
*/
2021-08-20 07:42:50 +02:00
copyBytes: Boolean = true
) {
companion object {
2023-07-02 11:27:49 +02:00
/**
* Gets the version number.
*/
const val version = BytesInfo.version
2021-08-20 07:42:50 +02:00
/**
* 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)
}
2021-08-20 07:42:50 +02:00
/**
* 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)
}
}
2021-08-20 07:42:50 +02:00
val bytes: ByteArray
private var hashCode: Int? = null
2021-08-20 07:42:50 +02:00
init {
val length = data.size
2023-01-24 20:37:56 +01:00
2021-08-20 07:42:50 +02:00
if (copyBytes) {
bytes = ByteArray(length)
// copy so it's immutable as a key.
System.arraycopy(data, 0, bytes, 0, length)
} else {
bytes = data
}
}
2021-08-20 07:42:50 +02:00
override fun hashCode(): Int {
// might be null for a thread because it's stale. who cares, get the value again
2021-08-20 07:42:50 +02:00
var hashCode = hashCode
if (hashCode == null) {
2023-01-24 20:37:56 +01:00
hashCode = bytes.contentHashCode()
2021-08-20 07:42:50 +02:00
this.hashCode = hashCode
}
2021-08-20 07:42:50 +02:00
return hashCode
}
2021-08-20 07:42:50 +02:00
override fun equals(other: Any?): Boolean {
return if (other !is ByteArrayWrapper) {
false
2023-01-24 20:37:56 +01:00
} else bytes.contentEquals(other.bytes)
// CANNOT be null, so we don't have to null check!
}
2021-08-20 07:42:50 +02:00
override fun toString(): String {
2023-01-24 20:37:56 +01:00
return "ByteArrayWrapper " + bytes.contentToString()
}
}