@@ -7,12 +7,16 @@ fun squeeze_int(v: Int): ByteArray
77{
88 if (v == 0 ) return byteArrayOf(0 )
99 val neg = v < 0
10- var pos = if (neg) - v else v
10+ var pos = if (neg) {
11+ if (v == Int .MIN_VALUE ) 0x80000000u
12+ else (- v).toUInt()
13+ } else v.toUInt()
14+
1115 val b = mutableListOf<Byte >()
12- while (pos != 0 )
16+ while (pos != 0u )
1317 {
14- b.add(0 , (pos and 0xFF ).toByte())
15- pos = pos ushr 8
18+ b.add(0 , (pos and 0xFFu ).toByte())
19+ pos = pos shr 8
1620 }
1721 var len = b.size.toByte()
1822 if (neg) len = (len.toInt() or 0x80 ).toByte()
@@ -54,11 +58,39 @@ fun expand_int(v: ByteArray): Pair<Varint, ByteArray>
5458 val data = v.sliceArray(1 until 1 + len)
5559 val rest = v.sliceArray(1 + len until v.size)
5660 var i = expand_int_from_bytes(data)
57- if (neg) i = when (i)
61+
62+ if (neg)
5863 {
59- is Varint .IonInt -> Varint .IonInt (- i.value)
60- is Varint .IonInts -> Varint .IonInts (listOf (- i.value.first()) + i.value.drop(1 ))
64+ i = when (i)
65+ {
66+ is Varint .IonInt -> Varint .IonInt (- i.value)
67+ is Varint .IonInts ->
68+ {
69+ // Check if this bigint can actually fit as a negative Int
70+ if (i.value.size == 1 )
71+ {
72+ val uval = i.value[0 ].toUInt()
73+ // Special case: 0x80000000 unsigned = Int.MIN_VALUE when negated
74+ if (uval == 0x80000000u )
75+ {
76+ Varint .IonInt (Int .MIN_VALUE )
77+ }
78+ else
79+ {
80+ // This shouldn't happen - expand_int_from_bytes should have returned IonInt
81+ // But if it does, add negative flag to bigint
82+ Varint .IonInts (listOf (1 ) + i.value)
83+ }
84+ }
85+ else
86+ {
87+ // Multiple limbs - add negative flag (1) to front
88+ Varint .IonInts (listOf (1 ) + i.value)
89+ }
90+ }
91+ }
6192 }
93+
6294 return Pair (i, rest)
6395}
6496
@@ -106,8 +138,12 @@ fun expand_int_from_bytes(b: ByteArray): Varint
106138 }
107139 }
108140 }
109- return if (ints.size == 1 && ints[0 ].toUInt() <= Int .MAX_VALUE .toUInt())
110- Varint .IonInt (ints[0 ]) else Varint .IonInts (ints)
141+ return if (ints.size == 1 &&
142+ (ints[0 ].toUInt() <= Int .MAX_VALUE .toUInt() ||
143+ ints[0 ].toUInt() == 0x80000000u ))
144+ Varint .IonInt (ints[0 ])
145+ else
146+ Varint .IonInts (ints)
111147}
112148
113149fun squeeze_floating (v : Floating ): ByteArray = when (v)
@@ -160,33 +196,6 @@ fun squeeze_ints(v: List<Int>): ByteArray = if (v.isEmpty()) byteArrayOf(0) else
160196 squeeze_int(v.size).toList().plus(v.flatMap
161197 { it: Int -> squeeze_int(it).toList() }).toByteArray()
162198
163- fun expand_ints (v : ByteArray ): Pair <List <Int >, ByteArray>
164- {
165- if (v.isEmpty()) return Pair (emptyList(), v)
166- val (sz, rest1) = expand_int(v)
167- return when (sz)
168- {
169- is Varint .IonInt ->
170- {
171- if (sz.value == 0 ) return Pair (emptyList(), rest1)
172- var r = rest1
173- val ints = mutableListOf<Int >()
174- for (i in 0 until sz.value)
175- {
176- val (int, rest2) = expand_int(r)
177- r = rest2
178- when (int)
179- {
180- is Varint .IonInt -> ints.add(int.value)
181- else -> return Pair (emptyList(), byteArrayOf())
182- }
183- }
184- Pair (ints.toList(), r)
185- }
186- else -> Pair (emptyList(), byteArrayOf())
187- }
188- }
189-
190199fun squeeze_floats (v : List <Float >): ByteArray = if (v.isEmpty()) byteArrayOf(0 ) else
191200 squeeze_int(v.size).toList().plus(v.flatMap
192201 { it: Float -> squeeze_floating(Floating .IonFloat (it)).toList() }).toByteArray()
0 commit comments