
pickle-core_sjs1_3.3.1.0.source-code.CharUtils.scala Maven / Gradle / Ivy
package upickle.core
import scala.annotation.switch
object CharUtils{
def appendEscapedChar(charBuilder: CharBuilder, c: Char, i: Int): Boolean = {
(c: @switch) match {
case '"' => escapeSingleChar(charBuilder, i, '"'); true
case '\\' => escapeSingleChar(charBuilder, i, '\\'); true
case '\b' => escapeSingleChar(charBuilder, i, 'b'); true
case '\f' => escapeSingleChar(charBuilder, i, 'f'); true
case '\n' => escapeSingleChar(charBuilder, i, 'n'); true
case '\r' => escapeSingleChar(charBuilder, i, 'r'); true
case '\t' => escapeSingleChar(charBuilder, i, 't'); true
case _ => false
}
}
def escapeSingleChar(charBuilder: CharBuilder, i: Int, c: Char) = {
charBuilder.ensureLength(2);
val length = charBuilder.length
val arr = charBuilder.arr
arr(length) = '\\'.toChar
arr(length + 1) = c.toChar
charBuilder.length += 2
}
def escapeSingleCharUnicodeEscape(charBuilder: CharBuilder, i: Int, c: Char) = {
charBuilder.ensureLength(6)
val arr = charBuilder.arr
val length = charBuilder.length
arr(length) = '\\'.toChar
arr(length + 1) = 'u'.toChar
arr(length + 2) = RenderUtils.toHex((c >> 12) & 15).toChar
arr(length + 3) = RenderUtils.toHex((c >> 8) & 15).toChar
arr(length + 4) = RenderUtils.toHex((c >> 4) & 15).toChar
arr(length + 5) = RenderUtils.toHex(c & 15).toChar
charBuilder.length += 6
}
def appendSimpleStringSection(charBuilder: CharBuilder,
i0: Int,
len: Int,
s: CharSequence) = {
charBuilder.ensureLength(len - i0)
val i = appendSimpleStringSection0(charBuilder.arr, charBuilder.length, i0, len, s)
charBuilder.length = charBuilder.length + (i - i0) + 1
i
}
def appendSimpleStringSectionNoUnicode(charBuilder: CharBuilder,
i0: Int,
len: Int,
s: CharSequence) = {
charBuilder.ensureLength(len - i0)
val i = appendSimpleStringSectionNoUnicode0(charBuilder.arr, charBuilder.length, i0, len, s)
charBuilder.length = charBuilder.length + (i - i0) + 1
i
}
private def appendSimpleStringSection0(arr: Array[Char],
arrOffset: Int,
i0: Int,
len: Int,
s: CharSequence) = {
var i = i0
while (
if (i >= len) false
else {
val c2 = s.charAt(i)
if (c2 < ' ' | c2 == '"' | c2 == '\\') false
else {
arr(arrOffset + i - i0) = c2.toChar
i += 1
true
}
}
) ()
i - 1
}
private def appendSimpleStringSectionNoUnicode0(arr: Array[Char],
arrOffset: Int,
i0: Int,
len: Int,
s: CharSequence) = {
var i = i0
while (
if (i >= len) false
else {
val c2 = s.charAt(i)
if (c2 < ' ' || c2 > 127 || c2 == '"' || c2 == '\\') false
else {
arr(arrOffset + i - i0) = c2.toChar
i += 1
true
}
}
) ()
i - 1
}
def parseIntegralNum(arr: Array[Char], arrOffset: Int, arrLength: Int, decIndex: Int, expIndex: Int) = {
val expMul =
if (expIndex == -1) 1
else {
var mult = 1
val e = parseLong(arr, arrOffset + expIndex + 1, arrOffset + arrLength)
var i = 0
while (i < e) {
if (mult >= Long.MaxValue / 10) throw new Abort("expected integer")
mult = mult * 10
i += 1
}
mult
}
val intPortion = {
val end =
if (decIndex != -1) decIndex
else if (expIndex != -1) expIndex
else arrLength
parseLong(arr, arrOffset, arrOffset + end) * expMul
}
val decPortion =
if (decIndex == -1) 0
else {
val end = if (expIndex != -1) expIndex else arrLength
var value = parseLong(arr, arrOffset + decIndex + 1, arrOffset + end) * expMul
var i = end - (decIndex + 1)
while (i > 0) {
value = value / 10
i -= 1
}
if (arr(arrOffset) == '-') -value else value
}
intPortion + decPortion
}
def parseLong(cs0: Array[Char], start0: Int, end0: Int): Long = {
if ((start0 | end0 | end0 - start0 | (cs0.length - end0)) < 0) throw new IndexOutOfBoundsException
// If we do not copy the data from `cs0` into our own local array before
// parsing it, we take a significant performance penalty in the
// `integers Read` benchmarks, but *only* when run together with the rest
// of the benchmarks! When `integers Read` isrun alone, this does not
// happen, and is presumably something to do with the JIT compiler.
// Since any real world use case would exercise all sorts of code paths,
// it would more closely resemble the "all benchmarks together" case
// rather, and so we leave this copy in-place to optimize performance
// for that scenario.
val cs = new Array[Char](end0 - start0)
System.arraycopy(cs0, start0, cs, 0, end0 - start0)
// we store the inverse of the positive sum, to ensure we don't
// incorrectly overflow on Long.MinValue. for positive numbers
// this inverse sum will be inverted before being returned.
var inverseSum: Long = 0L
var inverseSign: Long = -1L
var i: Int = 0
val end = end0 - start0
if (cs(0) == '-') {
inverseSign = 1L
i += 1
}
val size = end - i
if (size <= 0 || size > 19) throw new NumberFormatException(new String(cs))
while (i < end) {
val digit = cs(i).toInt - 48
if (digit < 0 || 9 < digit) throw new NumberFormatException(new String(cs))
inverseSum = inverseSum * 10L - digit
i += 1
}
// detect and throw on overflow
if (size == 19 && (inverseSum >= 0 || (inverseSum == Long.MinValue && inverseSign < 0))) {
throw new NumberFormatException(new String(cs))
}
inverseSum * inverseSign
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy