diff --git a/zio-json/js/src/main/scala/zio/json/internal/SafeNumbers.scala b/zio-json/js/src/main/scala/zio/json/internal/SafeNumbers.scala index c6545de3..d37b1369 100644 --- a/zio-json/js/src/main/scala/zio/json/internal/SafeNumbers.scala +++ b/zio-json/js/src/main/scala/zio/json/internal/SafeNumbers.scala @@ -15,6 +15,8 @@ */ package zio.json.internal +import java.util.UUID + /** * Total, fast, number parsing. * @@ -75,13 +77,19 @@ object SafeNumbers { def toString(x: Double): String = { val out = new FastStringWrite(24) write(x, out) - out.toString + out.buffer.toString } def toString(x: Float): String = { val out = new FastStringWrite(16) write(x, out) - out.toString + out.buffer.toString + } + + def toString(x: UUID): String = { + val out = writes.get + write(x, out) + out.buffer.toString } // Based on the amazing work of Raffaello Giulietti @@ -303,6 +311,26 @@ object SafeNumbers { } } + def write(x: UUID, out: Write): Unit = { + val ds = lowerCaseHexDigits + val msb = x.getMostSignificantBits + val lsb = x.getLeastSignificantBits + val msb1 = (msb >> 32).toInt + out.write(ds(msb1 >>> 24), ds(msb1 >> 16 & 0xff), ds(msb1 >> 8 & 0xff), ds(msb1 & 0xff)) + out.write('-') + val msb2 = msb.toInt + out.write(ds(msb2 >>> 24), ds(msb2 >> 16 & 0xff)) + out.write('-') + out.write(ds(msb2 >> 8 & 0xff), ds(msb2 & 0xff)) + out.write('-') + val lsb1 = (lsb >>> 32).toInt + out.write(ds(lsb1 >>> 24), ds(lsb1 >> 16 & 0xff)) + out.write('-') + out.write(ds(lsb1 >> 8 & 0xff), ds(lsb1 & 0xff)) + val lsb2 = lsb.toInt + out.write(ds(lsb2 >>> 24), ds(lsb2 >> 16 & 0xff), ds(lsb2 >> 8 & 0xff), ds(lsb2 & 0xff)) + } + private[json] def writeNano(x: Int, out: Write): Unit = { out.write('.') var coeff = 100000000 @@ -549,6 +577,25 @@ object SafeNumbers { else 10 } + private final val lowerCaseHexDigits: Array[Short] = Array( + 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 26160, + 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, + 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, + 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, + 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164, + 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, + 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654, 25910, 26166, + 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, + 12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, + 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, + 12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, + 12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, + 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, + 12388, 12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, + 12389, 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, + 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 26214 + ) + private[this] val gs: Array[Long] = Array( 5696189077778435540L, 6557778377634271669L, 9113902524445496865L, 1269073367360058862L, 7291122019556397492L, 1015258693888047090L, 5832897615645117993L, 6346230177223303157L, 4666318092516094394L, 8766332956520552849L, diff --git a/zio-json/jvm/src/main/scala/zio/json/internal/SafeNumbers.scala b/zio-json/jvm/src/main/scala/zio/json/internal/SafeNumbers.scala index 67eec114..51d3d2a9 100644 --- a/zio-json/jvm/src/main/scala/zio/json/internal/SafeNumbers.scala +++ b/zio-json/jvm/src/main/scala/zio/json/internal/SafeNumbers.scala @@ -15,6 +15,8 @@ */ package zio.json.internal +import java.util.UUID + /** * Total, fast, number parsing. * @@ -75,13 +77,19 @@ object SafeNumbers { def toString(x: Double): String = { val out = new FastStringWrite(24) write(x, out) - out.toString + out.buffer.toString } def toString(x: Float): String = { val out = new FastStringWrite(16) write(x, out) - out.toString + out.buffer.toString + } + + def toString(x: UUID): String = { + val out = writes.get + write(x, out) + out.buffer.toString } // Based on the amazing work of Raffaello Giulietti @@ -294,6 +302,26 @@ object SafeNumbers { } } + def write(x: UUID, out: Write): Unit = { + val ds = lowerCaseHexDigits + val msb = x.getMostSignificantBits + val lsb = x.getLeastSignificantBits + val msb1 = (msb >> 32).toInt + out.write(ds(msb1 >>> 24), ds(msb1 >> 16 & 0xff), ds(msb1 >> 8 & 0xff), ds(msb1 & 0xff)) + out.write('-') + val msb2 = msb.toInt + out.write(ds(msb2 >>> 24), ds(msb2 >> 16 & 0xff)) + out.write('-') + out.write(ds(msb2 >> 8 & 0xff), ds(msb2 & 0xff)) + out.write('-') + val lsb1 = (lsb >>> 32).toInt + out.write(ds(lsb1 >>> 24), ds(lsb1 >> 16 & 0xff)) + out.write('-') + out.write(ds(lsb1 >> 8 & 0xff), ds(lsb1 & 0xff)) + val lsb2 = lsb.toInt + out.write(ds(lsb2 >>> 24), ds(lsb2 >> 16 & 0xff), ds(lsb2 >> 8 & 0xff), ds(lsb2 & 0xff)) + } + private[json] def writeNano(x: Int, out: Write): Unit = { out.write('.') var coeff = 100000000 @@ -482,6 +510,25 @@ object SafeNumbers { 576460752303423478L, 576460752303423478L, 576460752303423478L, 576460752303423478L, 576460752303423478L ) + private final val lowerCaseHexDigits: Array[Short] = Array( + 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 26160, + 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, + 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, + 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, + 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164, + 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, + 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654, 25910, 26166, + 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, + 12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, + 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, + 12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, + 12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, + 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, + 12388, 12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, + 12389, 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, + 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 26214 + ) + private[this] val gs: Array[Long] = Array( 5696189077778435540L, 6557778377634271669L, 9113902524445496865L, 1269073367360058862L, 7291122019556397492L, 1015258693888047090L, 5832897615645117993L, 6346230177223303157L, 4666318092516094394L, 8766332956520552849L, diff --git a/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala b/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala index 67eec114..51d3d2a9 100644 --- a/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala +++ b/zio-json/native/src/main/scala/zio/json/internal/SafeNumbers.scala @@ -15,6 +15,8 @@ */ package zio.json.internal +import java.util.UUID + /** * Total, fast, number parsing. * @@ -75,13 +77,19 @@ object SafeNumbers { def toString(x: Double): String = { val out = new FastStringWrite(24) write(x, out) - out.toString + out.buffer.toString } def toString(x: Float): String = { val out = new FastStringWrite(16) write(x, out) - out.toString + out.buffer.toString + } + + def toString(x: UUID): String = { + val out = writes.get + write(x, out) + out.buffer.toString } // Based on the amazing work of Raffaello Giulietti @@ -294,6 +302,26 @@ object SafeNumbers { } } + def write(x: UUID, out: Write): Unit = { + val ds = lowerCaseHexDigits + val msb = x.getMostSignificantBits + val lsb = x.getLeastSignificantBits + val msb1 = (msb >> 32).toInt + out.write(ds(msb1 >>> 24), ds(msb1 >> 16 & 0xff), ds(msb1 >> 8 & 0xff), ds(msb1 & 0xff)) + out.write('-') + val msb2 = msb.toInt + out.write(ds(msb2 >>> 24), ds(msb2 >> 16 & 0xff)) + out.write('-') + out.write(ds(msb2 >> 8 & 0xff), ds(msb2 & 0xff)) + out.write('-') + val lsb1 = (lsb >>> 32).toInt + out.write(ds(lsb1 >>> 24), ds(lsb1 >> 16 & 0xff)) + out.write('-') + out.write(ds(lsb1 >> 8 & 0xff), ds(lsb1 & 0xff)) + val lsb2 = lsb.toInt + out.write(ds(lsb2 >>> 24), ds(lsb2 >> 16 & 0xff), ds(lsb2 >> 8 & 0xff), ds(lsb2 & 0xff)) + } + private[json] def writeNano(x: Int, out: Write): Unit = { out.write('.') var coeff = 100000000 @@ -482,6 +510,25 @@ object SafeNumbers { 576460752303423478L, 576460752303423478L, 576460752303423478L, 576460752303423478L, 576460752303423478L ) + private final val lowerCaseHexDigits: Array[Short] = Array( + 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 26160, + 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, + 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, + 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, + 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164, + 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, + 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654, 25910, 26166, + 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, + 12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, + 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, + 12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, + 12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, + 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, + 12388, 12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, + 12389, 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, + 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 26214 + ) + private[this] val gs: Array[Long] = Array( 5696189077778435540L, 6557778377634271669L, 9113902524445496865L, 1269073367360058862L, 7291122019556397492L, 1015258693888047090L, 5832897615645117993L, 6346230177223303157L, 4666318092516094394L, 8766332956520552849L, diff --git a/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala b/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala index 339bc83d..6b5045a1 100644 --- a/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala +++ b/zio-json/shared/src/main/scala/zio/json/JsonEncoder.scala @@ -723,12 +723,12 @@ private[json] trait EncoderLowPriority3 extends EncoderLowPriority4 { implicit val zoneId: JsonEncoder[ZoneId] = new JsonEncoder[ZoneId] { def unsafeEncode(a: ZoneId, indent: Option[Int], out: Write): Unit = { out.write('"') - serializers.write(a, out) + out.write(a.getId) out.write('"') } override final def toJsonAST(a: ZoneId): Either[String, Json] = - new Right(new Json.Str(serializers.toString(a))) + new Right(new Json.Str(a.getId)) } implicit val zoneOffset: JsonEncoder[ZoneOffset] = new JsonEncoder[ZoneOffset] { @@ -742,7 +742,16 @@ private[json] trait EncoderLowPriority3 extends EncoderLowPriority4 { new Right(new Json.Str(serializers.toString(a))) } - implicit val uuid: JsonEncoder[UUID] = stringify(_.toString) + implicit val uuid: JsonEncoder[UUID] = new JsonEncoder[UUID] { + def unsafeEncode(a: UUID, indent: Option[Int], out: Write): Unit = { + out.write('"') + SafeNumbers.write(a, out) + out.write('"') + } + + override final def toJsonAST(a: UUID): Either[String, Json] = + new Right(new Json.Str(SafeNumbers.toString(a))) + } implicit val currency: JsonEncoder[java.util.Currency] = stringify(_.toString) }