Skip to content

Commit 4ce8c5b

Browse files
committed
[ECO-5380] Updated message size spec annoatations as per updated spec
1 parent 9d6e5b4 commit 4ce8c5b

2 files changed

Lines changed: 74 additions & 48 deletions

File tree

lib/src/main/java/io/ably/lib/types/Message.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ protected void read(final JsonObject map) throws MessageDecodeException {
525525
*/
526526
protected int size() {
527527
// Spec: TM6a - Sum of sizes of name, data, clientId, and extras
528-
int nameSize = name != null ? name.length() : 0; // Spec: TM6e
528+
int nameSize = name != null ? name.length() : 0; // Spec: TM6a
529529
int dataSize = 0;
530530

531531
if (data != null) {
@@ -536,7 +536,7 @@ protected int size() {
536536
}
537537
}
538538

539-
int clientIdSize = clientId != null ? clientId.length() : 0; // Spec: TM6e
539+
int clientIdSize = clientId != null ? clientId.length() : 0; // Spec: TM6f
540540
int extrasSize = extras != null ? Serialisation.gson.toJson(extras).length() : 0; // Spec: TM6d
541541

542542
return nameSize + dataSize + clientIdSize + extrasSize;

live-objects/src/main/kotlin/io/ably/lib/objects/ObjectMessage.kt

Lines changed: 72 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
2222
internal 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
*/
110129
internal 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
*/
128147
internal 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
*/
323342
internal 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
*/
336355
private 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
*/
349368
private 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
*/
380399
private 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
*/
393412
private 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
*/
411430
private 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

Comments
 (0)