uint32_t CBInventoryBroadcastSerialise(CBInventoryBroadcast * self){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->events->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_NULL_BYTES,"Attempting to serialise a CBInventoryBroadcast with no bytes."); return 0; } CBVarInt num = CBVarIntFromUInt64(self->itemNum); if (bytes->length < num.size + 36 * self->itemNum) { CBGetMessage(self)->events->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_BAD_BYTES,"Attempting to deserialise a CBInventoryBroadcast with less bytes than required."); return 0; } CBVarIntEncode(bytes, 0, num); uint16_t cursor = num.size; for (uint16_t x = 0; x < num.val; x++) { CBGetMessage(self->items[x])->bytes = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); uint32_t len = CBInventoryItemSerialise(self->items[x]); if (NOT len) { CBGetMessage(self)->events->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_BAD_BYTES,"CBInventoryBroadcast cannot be serialised because of an error with the CBInventoryItem number %u.",x); // Release CBByteArray objects to avoid problems overwritting pointer without release, if serialisation is tried again. for (uint8_t y = 0; y < x + 1; y++) { CBReleaseObject(CBGetMessage(self->items[y])->bytes); } return 0; } CBGetMessage(self->items[x])->bytes->length = len; cursor += len; } return cursor; }
uint32_t CBInventoryBroadcastSerialise(CBInventoryBroadcast * self, bool force){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_NULL_BYTES,"Attempting to serialise a CBInventoryBroadcast with no bytes."); return 0; } CBVarInt num = CBVarIntFromUInt64(self->itemNum); if (bytes->length < num.size + 36 * self->itemNum) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_BAD_BYTES,"Attempting to deserialise a CBInventoryBroadcast with less bytes than required."); return 0; } CBVarIntEncode(bytes, 0, num); uint16_t cursor = num.size; for (uint16_t x = 0; x < num.val; x++) { if (force && CBGetMessage(self->items[x])->serialised) CBReleaseObject(CBGetMessage(self->items[x])->bytes); if (NOT CBGetMessage(self->items[x])->serialised || force) { CBGetMessage(self->items[x])->bytes = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (NOT CBGetMessage(self->items[x])->bytes) { CBGetMessage(self)->onErrorReceived(CB_ERROR_INIT_FAIL,"Cannot create a new CBByteArray sub reference in CBInventoryBroadcastSerialise"); return 0; } uint32_t len = CBInventoryItemSerialise(self->items[x]); if (NOT len) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_BAD_BYTES,"CBInventoryBroadcast cannot be serialised because of an error with the CBInventoryItem number %u.",x); // Release CBByteArray objects to avoid problems overwritting pointer without release, if serialisation is tried again. for (uint8_t y = 0; y < x + 1; y++) CBReleaseObject(CBGetMessage(self->items[y])->bytes); return 0; } CBGetMessage(self->items[x])->bytes->length = len; }else if (CBGetMessage(self->items[x])->bytes->sharedData != bytes->sharedData){ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, cursor, CBGetMessage(self->items[x])->bytes); CBByteArrayChangeReference(CBGetMessage(self->items[x])->bytes, bytes, cursor); } cursor += CBGetMessage(self->items[x])->bytes->length; } CBGetMessage(self)->serialised = true; return cursor; }
int CBInventorySerialise(CBInventory * self, bool force) { CBByteArray * bytes = CBGetMessage(self)->bytes; if (! bytes) { CBLogError("Attempting to serialise a CBInventory with no bytes."); return 0; } CBVarInt num = CBVarIntFromUInt64(self->itemNum); if (bytes->length < num.size + 36 * self->itemNum) { CBLogError("Attempting to deserialise a CBInventory with less bytes than required."); return 0; } CBByteArraySetVarInt(bytes, 0, num); int cursor = num.size; for (CBInventoryItem * item = self->itemFront; item != NULL; item = item->next) { if (! CBGetMessage(item)->serialised // Serialise if not serialised yet. // Serialise if force is true. || force // If the data shares the same data as the inventory boradcast, re-serialise the inventory item, in case it got overwritten. || CBGetMessage(item)->bytes->sharedData == bytes->sharedData) { if (CBGetMessage(item)->serialised) // Release old byte array CBReleaseObject(CBGetMessage(item)->bytes); CBGetMessage(item)->bytes = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (! CBInventoryItemSerialise(item)) { CBLogError("CBInventory cannot be serialised because of an error with an CBInventoryItem."); // Release CBByteArray objects to avoid problems overwritting pointer without release, if serialisation is tried again. for (CBInventoryItem * item2 = self->itemFront; ; item2 = item->next){ CBReleaseObject(item2); if (item2 == item) break; } return 0; } }else{ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, cursor, CBGetMessage(item)->bytes); CBByteArrayChangeReference(CBGetMessage(item)->bytes, bytes, cursor); } cursor += CBGetMessage(item)->bytes->length; } // Ensure length is correct bytes->length = cursor; // Is now serialised. CBGetMessage(self)->serialised = true; return cursor; }