Skip to content

Commit 2932667

Browse files
committed
grpc-native: Add float and double encode/decode
Signed-off-by: Johannes Zottele <[email protected]>
1 parent 14f0db3 commit 2932667

File tree

7 files changed

+87
-1
lines changed

7 files changed

+87
-1
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/WireDecoder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ internal interface WireDecoder: AutoCloseable {
4141
fun readFixed64(): ULong?
4242
fun readSFixed32(): Int?
4343
fun readSFixed64(): Long?
44+
fun readFloat(): Float?
45+
fun readDouble(): Double?
4446
fun readEnum(): Int?
4547
fun readString(): String?
4648
fun readBytes(): ByteArray?

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/internal/WireEncoder.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ internal interface WireEncoder {
2626
fun writeFixed64(fieldNr: Int, value: ULong): Boolean
2727
fun writeSFixed32(fieldNr: Int, value: Int): Boolean
2828
fun writeSFixed64(fieldNr: Int, value: Long): Boolean
29+
fun writeFloat(fieldNr: Int, value: Float): Boolean
30+
fun writeDouble(fieldNr: Int, value: Double): Boolean
2931
fun writeEnum(fieldNr: Int, value: Int): Boolean
3032
fun writeString(fieldNr: Int, value: String): Boolean
3133
fun flush()

grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/WireDecoder.native.kt

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import libprotowire.*
1010
import kotlin.experimental.ExperimentalNativeApi
1111

1212
@OptIn(ExperimentalForeignApi::class, ExperimentalNativeApi::class)
13-
internal class WireDecoderNative(private val source: Buffer): WireDecoder {
13+
internal class WireDecoderNative(source: Buffer): WireDecoder {
1414

1515
// wraps the source in a class that allows to pass data from the source buffer to the C++ encoder
1616
// without copying it to an intermediate byte array.
@@ -144,6 +144,22 @@ internal class WireDecoderNative(private val source: Buffer): WireDecoder {
144144
return null
145145
}
146146

147+
override fun readFloat(): Float? = memScoped {
148+
val value = alloc<FloatVar>()
149+
if (pw_decoder_read_float(raw, value.ptr)) {
150+
return value.value
151+
}
152+
return null
153+
}
154+
155+
override fun readDouble(): Double? = memScoped {
156+
val value = alloc<DoubleVar>()
157+
if (pw_decoder_read_double(raw, value.ptr)) {
158+
return value.value
159+
}
160+
return null
161+
}
162+
147163
override fun readEnum(): Int? = memScoped {
148164
val value = alloc<IntVar>()
149165
if (pw_decoder_read_enum(raw, value.ptr)) {
@@ -164,8 +180,11 @@ internal class WireDecoderNative(private val source: Buffer): WireDecoder {
164180
}
165181
}
166182

183+
// TODO: Should readBytes return a buffer? The current approach is dangerous as one could send a
184+
// huge length (max 2GB) and we would just allocate the array of that length.
167185
override fun readBytes(): ByteArray? {
168186
val length = readInt32() ?: return null
187+
if (length < 0) return null
169188
if (length == 0) return ByteArray(0)
170189
val bytes = ByteArray(length)
171190
bytes.usePinned {

grpc/grpc-core/src/nativeMain/kotlin/kotlinx/rpc/grpc/internal/WireEncoder.native.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ internal class WireEncoderNative(private val sink: Sink): WireEncoder {
9292
return pw_encoder_write_sfixed64(raw, fieldNr, value)
9393
}
9494

95+
override fun writeFloat(fieldNr: Int, value: Float): Boolean {
96+
return pw_encoder_write_float(raw, fieldNr, value)
97+
}
98+
99+
override fun writeDouble(fieldNr: Int, value: Double): Boolean {
100+
return pw_encoder_write_double(raw, fieldNr, value)
101+
}
102+
95103
override fun writeEnum(fieldNr: Int, value: Int): Boolean {
96104
return pw_encoder_write_enum(raw, fieldNr, value)
97105
}

grpc/grpc-core/src/nativeTest/kotlin/kotlinx/rpc/grpc/internal/WireCodecTest.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,4 +610,54 @@ class WireCodecTest {
610610
assertEquals(1, tag.fieldNr)
611611
assertEquals(WireType.LENGTH_DELIMITED, tag.wireType)
612612
}
613+
614+
@Test
615+
fun testDoubleEncodeDecode() {
616+
val fieldNr = 21
617+
val testValue = 3.14159265359
618+
val buffer = Buffer()
619+
620+
val encoder = WireEncoder(buffer)
621+
assertTrue(encoder.writeDouble(fieldNr, testValue))
622+
encoder.flush()
623+
624+
val decoder = WireDecoder(buffer)
625+
626+
val tag = decoder.readTag()
627+
assertNotNull(tag)
628+
assertEquals(WireType.FIXED64, tag.wireType)
629+
assertEquals(fieldNr, tag.fieldNr)
630+
631+
val value = decoder.readDouble()
632+
assertNotNull(value)
633+
assertEquals(testValue, value)
634+
635+
decoder.close()
636+
assertTrue(buffer.exhausted())
637+
}
638+
639+
@Test
640+
fun testFloatEncodeDecode() {
641+
val fieldNr = 22
642+
val testValue = 3.14159f
643+
val buffer = Buffer()
644+
645+
val encoder = WireEncoder(buffer)
646+
assertTrue(encoder.writeFloat(fieldNr, testValue))
647+
encoder.flush()
648+
649+
val decoder = WireDecoder(buffer)
650+
651+
val tag = decoder.readTag()
652+
assertNotNull(tag)
653+
assertEquals(WireType.FIXED32, tag.wireType)
654+
assertEquals(fieldNr, tag.fieldNr)
655+
656+
val value = decoder.readFloat()
657+
assertNotNull(value)
658+
assertEquals(testValue, value)
659+
660+
decoder.close()
661+
assertTrue(buffer.exhausted())
662+
}
613663
}

grpc/grpcpp-c/include/protowire.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ extern "C" {
9898
// To read an actual bytes field, you must combine read_int32 and this function
9999
bool pw_decoder_read_raw_bytes(pw_decoder_t *self, void* buffer, int size);
100100

101+
101102
#ifdef __cplusplus
102103
}
103104
#endif

grpc/grpcpp-c/src/protowire.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ extern "C" {
166166
WRITE_FIELD_FUNC( fixed64, Fixed64, uint64_t)
167167
WRITE_FIELD_FUNC( sfixed32, SFixed32, int32_t)
168168
WRITE_FIELD_FUNC( sfixed64, SFixed64, int64_t)
169+
WRITE_FIELD_FUNC( float, Float, float)
170+
WRITE_FIELD_FUNC( double, Double, double)
169171
WRITE_FIELD_FUNC( enum, Enum, int)
170172

171173
bool pw_encoder_write_string(pw_encoder_t *self, int field_no, const char *data, int size) {
@@ -206,6 +208,8 @@ extern "C" {
206208
READ_VAL_FUNC( fixed64, FIXED64, uint64_t)
207209
READ_VAL_FUNC( sfixed32, SFIXED32, int32_t)
208210
READ_VAL_FUNC( sfixed64, SFIXED64, int64_t)
211+
READ_VAL_FUNC( float, FLOAT, float)
212+
READ_VAL_FUNC( double, DOUBLE, double)
209213
READ_VAL_FUNC( enum, ENUM, int)
210214

211215
bool pw_decoder_read_string(pw_decoder_t *self, pw_string_t **string_ref) {

0 commit comments

Comments
 (0)