93 lines
2.7 KiB
Kotlin
93 lines
2.7 KiB
Kotlin
/*
|
|
* 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()
|
|
}
|
|
}
|