
.10.dp.source-code.byte.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core_2.10 Show documentation
Show all versions of core_2.10 Show documentation
Core drx utilities that have no other dependencies other than the core scala lib
The newest version!
/*
Copyright 2010 Aaron J. Radke
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 cc.drx
trait Unsigned extends Any{
//---required
def depth:Int
def toLong:Long
//--optimizable
def mask:Long = depth.iterate(0L){_ << 1 | 1}
def signed:Long = {val shift = 64 - depth; toLong << shift >> shift} //move sign bit up then pull it back down if it is signed
def hex = s"0x%0${depth/4}x" format toLong
override def toString = hex
}
trait UnsignedObject{
// def depth:Int
/*
//TODO make better byte compositions to avoid java 2's complement integer assumptions oddities
type US = Iterable[Unsigned]
trait Pack[A] { def pack(xs:US):A }
object Pack{
def packLong(us:US):Long = us.toList.reverse.foldLeft( (0,0L) ){case ((d,v), u) => (d + u.depth, u.toLong << d) }._2
implicit object PackInt extends Pack[Int]{ def pack(xs:US):Int = packLong(xs).toInt}
implicit object PackLong extends Pack[Long]{ def pack(xs:US):Long = packLong(xs) }
implicit object PackByte extends Pack[Byte]{ def pack(xs:US):Byte = packLong(xs).toByte }
}
def pack[A](us:US)(implicit packer:Pack[A]):A = packer.pack(us)
*/
}
//TODO add assertions bounds for the constructions: i.e. Ints should not be bigger than an Byte if an unsigned byte is constructed
//the following classes make using unsigned integer types more first class
object U4 extends UnsignedObject{
val MinValue = U4(0x0)
val MaxValue = U4(0xF)
val byteWidth = 1 // 4bits
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Int):U4 = new U4((v & 0xF).toByte)
@inline final def apply(v:Byte):U4 = new U4((v & 0xF).toByte) //warning: bytes could be lost here
// def fromByteArray(bytes:Array[Bytes],offset:Int=0):U4 = new U4( bytes(offset) )
}
object U8{
val MinValue = U8(0x00)
val MaxValue = U8(0xFF)
val byteWidth = 1 // 8bits
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Byte):U8 = new U8(v)
@inline final def apply(v:Int):U8 = new U8(v.toByte) //TODO maybe make these over determined constructors unsafe?
@inline final def apply(h:U4,l:U4):U8 = new U8( ( h.toInt<<4 | l.toInt).toByte )
def fromByteArray(bytes:Array[Byte],offset:Int=0):U4 = U4(bytes(offset))
}
object U12{
val MinValue = U12(0x000)
val MaxValue = U12(0xFFF)
val byteWidth = 2
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Short):U12 = new U12((v & 0x0FFF).toShort)
@inline final def apply(v:Int):U12 = new U12((v & 0x0FFF).toShort)
@inline final def apply(hh:U4, h:U4,l:U4):U12 = new U12( ((hh.toInt << 8 | h.toInt<<4 | l.toInt)&0x0FFF).toShort )
}
object U16{
val MinValue = U16(0x0000)
val MaxValue = U16(0xFFFF)
val byteWidth = 2
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Short):U16 = new U16(v)
@inline final def apply(v:Int):U16 = new U16(v.toShort)
@inline final def apply(h:U8,l:U8):U16 = new U16( (h.toInt<<8 | l.toInt ).toShort )
@inline final def apply(a:U4,b:U4,c:U4,d:U4):U16 = new U16(( a.toInt<<12 | b.toInt<<8 | c.toInt<<4 | d.toInt).toShort)
}
object U24{
val MinValue = U24(0x00000000)
val MaxValue = U24(0x00FFFFFF)
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Int):U24 = new U24((v & 0x00FFFFFF).toInt)
val byteWidth = 3
}
/**Int constructor*/
object U32{
val MinValue = U32(0x00000000L)
val MaxValue = U32(0xFFFFFFFFL)
val byteWidth = 4
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Int):U32 = new U32(v)
@inline final def apply(v:Long):U32 = new U32((v & 0xFFFFFFFFL).toInt)
@inline final def apply(h:U16,l:U16):U32 = new U32( h.toInt<<16 | l.toInt )
@inline final def apply(a:U8,b:U8,c:U8,d:U8):U32 = new U32(( a.toInt<<24 | b.toInt<<16 | c.toInt<<8 | d.toInt).toShort)
def fromByteArray(bytes:Array[Byte],offset:Int=0):U32 = {
@inline def b(i:Int):U8 = U8(bytes(i+offset))
U32(b(0), b(1), b(2), b(3))
}
}
/**Long constructor*/
object U64{
val MinValue = U64(0x0L)
val MaxValue = U64(0xFFFFFFFFFFFFFFFFL)
val byteWidth = 8
// val bound = Bound(MinValue,MaxValue)
@inline final def apply(v:Long):U64 = new U64(v)
@inline final def apply(h:U32,l:U32):U64 = new U64( h.toLong<<32 | l.toLong)
}
//--classes
/**Nibble wrapper*/
class U4(val value:Byte) extends AnyVal with Unsigned{
def depth:Int = 4
def toByte = value
def toShort = value.toShort
def toInt = value & 0xF
def toLong = value & 0xFL
def +(that:U4):U4 = U4(this.value + that.value)
}
/**Byte wrapper*/
class U8(val value:Byte) extends AnyVal with Unsigned{
def depth:Int = 8
def toShort = value.toShort
def toInt = value & 0xFF
def toLong = value & 0xFFL
def hi:U4 = U4(value >> 4)
def lo:U4 = U4(value)
def +(that:U8):U8 = U8(this.value + that.value)
}
class U12(val value:Short) extends AnyVal with Unsigned{
def depth:Int = 12
def toShort = value
def toInt = value & 0x0FFF
def toLong = value & 0x0FFFL
def +(that:U12):U12 = U12(this.value + that.value) //TODO optimize so no masking is required
}
/**Short wrapper*/
class U16(val value:Short) extends AnyVal with Unsigned{
def depth:Int = 16
def toChar = value.toChar
def toInt = value & 0xFFFF
def toLong = value & 0xFFFFL
def hi:Byte = (value >> 8).toByte
def lo:Byte = value.toByte
def +(that:U16):U16 = U16(this.value + that.value)
}
class U24(val value:Int) extends AnyVal with Unsigned{
def depth:Int = 24
def toInt = value & 0x00FFFFFF
def toLong = value & 0x00FFFFFFL
def +(that:U24):U24 = U24(this.value + that.value) //TODO optimize
}
/**Int wrapper*/
class U32(val value:Int) extends AnyVal with Unsigned{
def depth:Int = 32
//toInt is not safe here because the value could be negative
def toLong = value & 0xFFFFFFFFL
def hi:Short = (value >> 16).toShort
def lo:Short = value.toShort
def +(that:U32):U32 = U32(this.value + that.value)
// def toByteArray:Array[Byte] = { //--implicit from DrxInt
// @inline def b(shift:Int):Byte = ((value >> shift) & 0xFF).toByte
// Array( b(24), b(16), b(8), b(0) )
// }
}
/**Long wrapper*/
class U64(val value:Long) extends AnyVal with Unsigned{
def depth:Int = 64
def toLong = value
def hi:Int = (value >> 32).toInt
def lo:Int = value.toInt
def +(that:U64):U64 = U64(this.value + that.value)
}