forked from jmcardon/tsec
-
Notifications
You must be signed in to change notification settings - Fork 3
/
package.scala
107 lines (78 loc) · 3.96 KB
/
package.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package tsec
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets
import java.util.Base64
import cats.effect.Sync
import org.apache.commons.codec.binary.{Hex, Base64 => AB64}
import scala.util.control.NoStackTrace
package object common {
trait TSecError extends Exception with NoStackTrace {
def cause: String
override def getMessage: String = cause
}
/** Convenience alias since
* Either[Throwable, *] is really annoying
* to write over and over
*/
type CatchE[A] = Either[Throwable, A]
sealed trait TSecPrimitiveEncoder[T] {
def encode(v: T): Array[Byte]
}
// ByteBuffer capacity based on https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
implicit val intPrimitiveEncoder: TSecPrimitiveEncoder[Int] = new TSecPrimitiveEncoder[Int] {
def encode(v: Int) = ByteBuffer.allocate(4).putInt(v).array()
}
implicit val longPrimitiveEncoder: TSecPrimitiveEncoder[Long] = new TSecPrimitiveEncoder[Long] {
def encode(v: Long) = ByteBuffer.allocate(8).putLong(v).array()
}
implicit val shortPrimitiveEncoder: TSecPrimitiveEncoder[Short] = new TSecPrimitiveEncoder[Short] {
def encode(v: Short) = ByteBuffer.allocate(4).putShort(v).array()
}
implicit val floatPrimitiveEncoder: TSecPrimitiveEncoder[Float] = new TSecPrimitiveEncoder[Float] {
def encode(v: Float) = ByteBuffer.allocate(4).putFloat(v).array()
}
implicit val doublePrimitiveEncoder: TSecPrimitiveEncoder[Double] = new TSecPrimitiveEncoder[Double] {
def encode(v: Double) = ByteBuffer.allocate(8).putDouble(v).array()
}
implicit final class JerryStringer(val s: String) extends AnyVal {
def utf8Bytes: Array[Byte] = s.getBytes(StandardCharsets.UTF_8)
def asciiBytes: Array[Byte] = s.getBytes(StandardCharsets.US_ASCII)
def b64Bytes: Option[Array[Byte]] =
try {
Some(Base64.getDecoder.decode(s))
} catch { case t: Throwable if NonFatal(t) => None }
def b64UrlBytes: Option[Array[Byte]] =
try {
Some(AB64.decodeBase64(s))
} catch { case t: Throwable if NonFatal(t) => None }
@deprecated("use .b64Bytes functions. This is unsafe", "0.0.1-M12")
def base64Bytes: Array[Byte] = Base64.getDecoder.decode(s)
@deprecated("use .b64UrlBytes functions. This is unsafe", "0.0.1-M12")
def base64UrlBytes: Array[Byte] = AB64.decodeBase64(s)
def hexBytes[F[_]](implicit F: Sync[F]): F[Array[Byte]] = F.delay(Hex.decodeHex(s))
def hexBytesUnsafe: Array[Byte] = Hex.decodeHex(s)
}
implicit final class ByteSyntaxHelpers(val array: Array[Byte]) extends AnyVal {
def toUtf8String = new String(array, StandardCharsets.UTF_8)
def toAsciiString = new String(array, StandardCharsets.US_ASCII)
def toB64UrlString: String = AB64.encodeBase64URLSafeString(array)
def toB64String: String = Base64.getEncoder.encodeToString(array)
def toHexString: String = Hex.encodeHexString(array)
def toFloatUnsafe: Float = ByteBuffer.wrap(array).getFloat
def toDoubleUnsafe: Double = ByteBuffer.wrap(array).getDouble
def toLongUnsafe: Long = ByteBuffer.wrap(array).getLong
def toShortUnsafe: Short = ByteBuffer.wrap(array).getShort
def toIntUnsafe: Int = ByteBuffer.wrap(array).getInt
def toFloat[F[_]](implicit F: Sync[F]): F[Float] = F.delay(toFloatUnsafe)
def toDouble[F[_]](implicit F: Sync[F]): F[Double] = F.delay(toDoubleUnsafe)
def toLong[F[_]](implicit F: Sync[F]): F[Long] = F.delay(toLongUnsafe)
def toShort[F[_]](implicit F: Sync[F]): F[Short] = F.delay(toShortUnsafe)
def toInt[F[_]](implicit F: Sync[F]): F[Int] = F.delay(toIntUnsafe)
}
// implicit final def byteSyntaxOps(array: Array[Byte]): By = new ByteSyntaxHelpers(array)
// implicit final def costanzaOps(jerry: String) = new JerryStringer(jerry)
implicit final class primitiveEncoderOps[T](v: T)(implicit E: TSecPrimitiveEncoder[T]) {
def toBytes: Array[Byte] = E.encode(v)
}
type SecureRandomId <: String
}