@@ -27,15 +27,28 @@ import kotlinx.serialization.encoding.AbstractDecoder
27
27
import kotlinx.serialization.encoding.CompositeDecoder
28
28
import kotlinx.serialization.encoding.CompositeDecoder.Companion.DECODE_DONE
29
29
import kotlinx.serialization.encoding.CompositeDecoder.Companion.UNKNOWN_NAME
30
+ import kotlinx.serialization.json.Json
31
+ import kotlinx.serialization.json.JsonArray
32
+ import kotlinx.serialization.json.JsonDecoder
33
+ import kotlinx.serialization.json.JsonElement
34
+ import kotlinx.serialization.json.JsonNull
35
+ import kotlinx.serialization.json.JsonObject
36
+ import kotlinx.serialization.json.JsonPrimitive
37
+ import kotlinx.serialization.json.buildJsonArray
38
+ import kotlinx.serialization.json.buildJsonObject
30
39
import kotlinx.serialization.modules.SerializersModule
31
40
import org.bson.AbstractBsonReader
41
+ import org.bson.BsonBinarySubType
32
42
import org.bson.BsonInvalidOperationException
33
43
import org.bson.BsonReader
34
44
import org.bson.BsonType
35
45
import org.bson.BsonValue
46
+ import org.bson.UuidRepresentation
36
47
import org.bson.codecs.BsonValueCodec
37
48
import org.bson.codecs.DecoderContext
49
+ import org.bson.internal.UuidHelper
38
50
import org.bson.types.ObjectId
51
+ import java.util.Base64
39
52
40
53
/* *
41
54
* The BsonDecoder interface
@@ -58,7 +71,14 @@ internal open class DefaultBsonDecoder(
58
71
internal val reader : AbstractBsonReader ,
59
72
override val serializersModule : SerializersModule ,
60
73
internal val configuration : BsonConfiguration
61
- ) : BsonDecoder, AbstractDecoder() {
74
+ ) : BsonDecoder, JsonDecoder, AbstractDecoder() {
75
+
76
+ override val json = Json {
77
+ explicitNulls = configuration.explicitNulls
78
+ encodeDefaults = configuration.encodeDefaults
79
+ classDiscriminator = configuration.classDiscriminator
80
+ serializersModule = this @DefaultBsonDecoder.serializersModule
81
+ }
62
82
63
83
private data class ElementMetadata (val name : String , val nullable : Boolean , var processed : Boolean = false )
64
84
private var elementsMetadata: Array <ElementMetadata >? = null
@@ -178,8 +198,82 @@ internal open class DefaultBsonDecoder(
178
198
179
199
override fun decodeObjectId (): ObjectId = readOrThrow({ reader.readObjectId() }, BsonType .OBJECT_ID )
180
200
override fun decodeBsonValue (): BsonValue = bsonValueCodec.decode(reader, DecoderContext .builder().build())
201
+
202
+ override fun decodeJsonElement (): JsonElement = reader.run {
203
+
204
+ if (state == AbstractBsonReader .State .INITIAL ||
205
+ state == AbstractBsonReader .State .SCOPE_DOCUMENT ||
206
+ state == AbstractBsonReader .State .TYPE ) {
207
+ readBsonType()
208
+ }
209
+
210
+ if (state == AbstractBsonReader .State .NAME ) {
211
+ // ignore name
212
+ skipName()
213
+ }
214
+ // @formatter:off
215
+ return when (currentBsonType) {
216
+ BsonType .NULL -> { readNull(); JsonNull } // We have to read null
217
+ BsonType .BOOLEAN -> JsonPrimitive (readBoolean())
218
+ BsonType .INT32 -> JsonPrimitive (readInt32())
219
+ BsonType .INT64 -> JsonPrimitive (readInt64())
220
+ BsonType .DOUBLE -> JsonPrimitive (readDouble())
221
+ BsonType .DECIMAL128 -> JsonPrimitive (readDecimal128())
222
+ BsonType .STRING -> JsonPrimitive (readString())
223
+ BsonType .DOCUMENT -> readJsonObject()
224
+ BsonType .ARRAY -> readJsonArray()
225
+ BsonType .OBJECT_ID -> JsonPrimitive (readObjectId().toHexString())
226
+ BsonType .DATE_TIME -> JsonPrimitive (readDateTime())
227
+ BsonType .TIMESTAMP -> JsonPrimitive (readTimestamp().value)
228
+ BsonType .REGULAR_EXPRESSION -> JsonPrimitive (readRegularExpression().pattern)
229
+ BsonType .BINARY -> {
230
+ val subtype = peekBinarySubType()
231
+ val data = readBinaryData().data
232
+ when (subtype) {
233
+ BsonBinarySubType .UUID_LEGACY .value ->
234
+ JsonPrimitive (UuidHelper .decodeBinaryToUuid(data, subtype, UuidRepresentation .JAVA_LEGACY ).toString())
235
+ BsonBinarySubType .UUID_STANDARD .value ->
236
+ JsonPrimitive (UuidHelper .decodeBinaryToUuid(data, subtype, UuidRepresentation .STANDARD ).toString())
237
+ else -> JsonPrimitive (Base64 .getEncoder().encodeToString(data))
238
+ }
239
+ }
240
+ else -> error(" unsupported json type: $currentBsonType " )
241
+ }
242
+ // @formatter:on
243
+ }
244
+
181
245
override fun reader (): BsonReader = reader
182
246
247
+ private fun BsonReader.readJsonObject (): JsonObject {
248
+
249
+ readStartDocument()
250
+ val obj = buildJsonObject {
251
+ var type = readBsonType()
252
+ while (type != BsonType .END_OF_DOCUMENT ) {
253
+ put(readName(), decodeJsonElement())
254
+ type = readBsonType()
255
+ }
256
+ }
257
+
258
+ readEndDocument()
259
+ return obj
260
+ }
261
+
262
+ private fun BsonReader.readJsonArray (): JsonArray {
263
+
264
+ readStartArray()
265
+ val array = buildJsonArray {
266
+ var type = readBsonType()
267
+ while (type != BsonType .END_OF_DOCUMENT ) {
268
+ add(decodeJsonElement())
269
+ type = readBsonType()
270
+ }
271
+ }
272
+
273
+ readEndArray()
274
+ return array
275
+ }
276
+
183
277
private inline fun <T > readOrThrow (action : () -> T , bsonType : BsonType ): T {
184
278
return try {
185
279
action()
0 commit comments