@@ -17,7 +17,7 @@ internal enum class ObjectOperationAction(val code: Int) {
1717
1818/* *
1919 * An enum class representing the conflict-resolution semantics used by a Map object.
20- * Spec: MAP2
20+ * Spec: OMP2
2121 */
2222internal enum class MapSemantics (val code : Int ) {
2323 LWW (0 );
@@ -44,35 +44,54 @@ internal data class ObjectData(
4444 * String, number, boolean or binary - a concrete value of the object
4545 * Spec: OD2c
4646 */
47- val value : Any ? = null ,
47+ val value : ObjectValue ? = null ,
4848)
4949
50+ /* *
51+ * Represents a value that can be a String, Number, Boolean or Binary.
52+ * Performs a type check on initialization.
53+ * Spec: OD2c
54+ */
55+ internal data class ObjectValue (
56+ /* *
57+ * The concrete value of the object. Can be a String, Number, Boolean or Binary.
58+ * Spec: OD2c
59+ */
60+ val value : Any ,
61+ ) {
62+ init {
63+ require(value is String || value is Number || value is Boolean || value is Binary ) {
64+ " value must be String, Number, Boolean or Binary"
65+ }
66+ }
67+ }
68+
5069/* *
5170 * A MapOp describes an operation to be applied to a Map object.
52- * Spec: MOP1
71+ * Spec: OMO1
5372 */
54- internal data class MapOp (
73+ internal data class ObjectMapOp (
5574 /* *
5675 * The key of the map entry to which the operation should be applied.
57- * Spec: MOP2a
76+ * Spec: OMO2a
5877 */
5978 val key : String ,
6079
6180 /* *
6281 * The data that the map entry should contain if the operation is a MAP_SET operation.
63- * Spec: MOP2b
82+ * Spec: OMO2b
6483 */
6584 val data : ObjectData ? = null
6685)
6786
6887/* *
6988 * A CounterOp describes an operation to be applied to a Counter object.
70- * Spec: COP1
89+ * Spec: OCO1
7190 */
72- internal data class CounterOp (
91+ internal data class ObjectCounterOp (
7392 /* *
7493 * The data value that should be added to the counter
75- * Spec: COP2a
94+ * Spec: OCO2a
7695 */
7796 val amount : Double? = null
7897)
@@ -81,54 +100,54 @@ internal data class CounterOp(
81100 * A MapEntry represents the value at a given key in a Map object.
82101 * Spec: ME1
83102 */
84- internal data class MapEntry (
103+ internal data class ObjectMapEntry (
85104 /* *
86105 * Indicates whether the map entry has been removed.
87- * Spec: ME2a
106+ * Spec: OME2a
88107 */
89108 val tombstone : Boolean? = null ,
90109
91110 /* *
92111 * The serial value of the last operation that was applied to the map entry.
93112 * It is optional in a MAP_CREATE operation and might be missing, in which case the client should use a nullish value for it
94113 * and treat it as the "earliest possible" serial for comparison purposes.
95- * Spec: ME2b
114+ * Spec: OME2b
96115 */
97116 val timeserial : String? = null ,
98117
99118 /* *
100119 * The data that represents the value of the map entry.
101- * Spec: ME2c
120+ * Spec: OME2c
102121 */
103122 val data : ObjectData ? = null
104123)
105124
106125/* *
107126 * An ObjectMap object represents a map of key-value pairs.
108- * Spec: MAP1
127+ * Spec: OMP1
109128 */
110129internal data class ObjectMap (
111130 /* *
112131 * The conflict-resolution semantics used by the map object.
113- * Spec: MAP3a
132+ * Spec: OMP3a
114133 */
115134 val semantics : MapSemantics ? = null ,
116135
117136 /* *
118137 * The map entries, indexed by key.
119- * Spec: MAP3b
138+ * Spec: OMP3b
120139 */
121- val entries : Map <String , MapEntry >? = null
140+ val entries : Map <String , ObjectMapEntry >? = null
122141)
123142
124143/* *
125144 * An ObjectCounter object represents an incrementable and decrementable value
126- * Spec: CNT1
145+ * Spec: OCN1
127146 */
128147internal data class ObjectCounter (
129148 /* *
130149 * The value of the counter
131- * Spec: CNT2a
150+ * Spec: OCN2a
132151 */
133152 val count : Double? = null
134153)
@@ -154,13 +173,13 @@ internal data class ObjectOperation(
154173 * The payload for the operation if it is an operation on a Map object type.
155174 * Spec: OOP3c
156175 */
157- val mapOp : MapOp ? = null ,
176+ val mapOp : ObjectMapOp ? = null ,
158177
159178 /* *
160179 * The payload for the operation if it is an operation on a Counter object type.
161180 * Spec: OOP3d
162181 */
163- val counterOp : CounterOp ? = null ,
182+ val counterOp : ObjectCounterOp ? = null ,
164183
165184 /* *
166185 * The payload for the operation if the operation is MAP_CREATE.
@@ -321,7 +340,7 @@ internal data class ObjectMessage(
321340 * Spec: OM3
322341 */
323342internal fun ObjectMessage.size (): Int {
324- val clientIdSize = clientId?.length ? : 0 // Spec: OM3a
343+ val clientIdSize = clientId?.length ? : 0 // Spec: OM3f
325344 val operationSize = operation?.size() ? : 0 // Spec: OM3b, OOP4
326345 val objectStateSize = objectState?.size() ? : 0 // Spec: OM3c, OST3
327346 val extrasSize = extras?.let { Gson ().toJson(it).length } ? : 0 // Spec: OM3d
@@ -334,10 +353,10 @@ internal fun ObjectMessage.size(): Int {
334353 * Spec: OOP4
335354 */
336355private fun ObjectOperation.size (): Int {
337- val mapOpSize = mapOp?.size() ? : 0 // Spec: OOP4b, MOP3
338- val counterOpSize = counterOp?.size() ? : 0 // Spec: OOP4c, COP3
339- val mapSize = map?.size() ? : 0 // Spec: OOP4d, MAP4
340- val counterSize = counter?.size() ? : 0 // Spec: OOP4e, CNT3
356+ val mapOpSize = mapOp?.size() ? : 0 // Spec: OOP4b, OMO3
357+ val counterOpSize = counterOp?.size() ? : 0 // Spec: OOP4c, OCO3
358+ val mapSize = map?.size() ? : 0 // Spec: OOP4d, OMP4
359+ val counterSize = counter?.size() ? : 0 // Spec: OOP4e, OCN3
341360
342361 return mapOpSize + counterOpSize + mapSize + counterSize
343362}
@@ -347,48 +366,48 @@ private fun ObjectOperation.size(): Int {
347366 * Spec: OST3
348367 */
349368private fun ObjectState.size (): Int {
350- val mapSize = map?.size() ? : 0 // Spec: OST3b, MAP4
351- val counterSize = counter?.size() ? : 0 // Spec: OST3c, CNT3
369+ val mapSize = map?.size() ? : 0 // Spec: OST3b, OMP4
370+ val counterSize = counter?.size() ? : 0 // Spec: OST3c, OCN3
352371 val createOpSize = createOp?.size() ? : 0 // Spec: OST3d, OOP4
353372
354373 return mapSize + counterSize + createOpSize
355374}
356375
357376/* *
358377 * Calculates the size of an ObjectMap in bytes.
359- * Spec: MOP3
378+ * Spec: OMO3
360379 */
361- private fun MapOp .size (): Int {
362- val keySize = key.length // Spec: MOP3a - Size of the key
363- val dataSize = data?.size() ? : 0 // Size of the data, calculated per "OD3"
380+ private fun ObjectMapOp .size (): Int {
381+ val keySize = key.length // Spec: OMO3d - Size of the key
382+ val dataSize = data?.size() ? : 0 // Spec: OMO3b - Size of the data, calculated per "OD3"
364383 return keySize + dataSize
365384}
366385
367386/* *
368387 * Calculates the size of a CounterOp in bytes.
369- * Spec: COP3
388+ * Spec: OCO3
370389 */
371- private fun CounterOp .size (): Int {
390+ private fun ObjectCounterOp .size (): Int {
372391 // Size is 8 if amount is a number, 0 if amount is null or omitted
373- return if (amount != null ) 8 else 0 // Spec: COP3a, COP3b
392+ return if (amount != null ) 8 else 0 // Spec: OCO3a, OCO3b
374393}
375394
376395/* *
377396 * Calculates the size of an ObjectMap in bytes.
378- * Spec: MAP4
397+ * Spec: OMP4
379398 */
380399private fun ObjectMap.size (): Int {
381400 // Calculate the size of all map entries in the map property
382401 val entriesSize = entries?.entries?.sumOf {
383- it.key.length + it.value.size() // // Spec: MAP4a1, MAP4a2
402+ it.key.length + it.value.size() // // Spec: OMP4a1, OMP4a2
384403 } ? : 0
385404
386405 return entriesSize
387406}
388407
389408/* *
390409 * Calculates the size of an ObjectCounter in bytes.
391- * Spec: CNT3
410+ * Spec: OCN3
392411 */
393412private fun ObjectCounter.size (): Int {
394413 // Size is 8 if count is a number, 0 if count is null or omitted
@@ -397,9 +416,9 @@ private fun ObjectCounter.size(): Int {
397416
398417/* *
399418 * Calculates the size of a MapEntry in bytes.
400- * Spec: ME3
419+ * Spec: OME3
401420 */
402- private fun MapEntry .size (): Int {
421+ private fun ObjectMapEntry .size (): Int {
403422 // The size is equal to the size of the data property, calculated per "OD3"
404423 return data?.size() ? : 0
405424}
@@ -409,12 +428,19 @@ private fun MapEntry.size(): Int {
409428 * Spec: OD3
410429 */
411430private fun ObjectData.size (): Int {
431+ return value?.size() ? : 0 // Spec: OD3f
432+ }
433+
434+ /* *
435+ * Calculates the size of an ObjectValue in bytes.
436+ * Spec: OD3*
437+ */
438+ private fun ObjectValue.size (): Int {
412439 return when (value) {
413- is Binary -> value.size() // Spec: OD3b
414- is Number -> 8 // Spec: OD3c
415- is Boolean -> 1 // Spec: OD3d
416- is String -> value.length // TODO: no spec
417- null -> 0 // Spec: OD3e
418- else -> 0
440+ is Boolean -> 1 // Spec: OD3b
441+ is Binary -> value.size() // Spec: OD3c
442+ is Number -> 8 // Spec: OD3d
443+ is String -> value.length // Spec: OD3e
444+ else -> 0 // Spec: OD3f
419445 }
420446}
0 commit comments