// Author: Sychov. A / 12/2020 #include "app/queue/queue_ex.h" int queue_pushback_payload(queue_t * self, queue_record_t * record, const void * payload ) { assert(self); assert(record); assert((int)record->size >= (int)record->payload + (int)sizeof(queue_record_t)); // [ queue record header ][ some data ][ payload ] // |<-- queue_record_t ->| |< size >| // |<-------------- record->size --------------->| int freeSpace = ringbuf_free_space(self); if(freeSpace < record->size) { return QUEUE_RC_NO_MEMORY; } // place common header int16_t rc = ringbuf_write(self, (void *)record, record->size - record->payload); assert((int)record->size - (int)record->payload == (int)rc); (void)rc; // place payload rc = ringbuf_write(self, (void *)payload, record->payload); assert(record->payload == rc); (void)rc; return QUEUE_RC_NOERROR; } int queue_peek_payload(const queue_t * self, queue_record_t * record, int16_t recordBufferSize, void * payload, int16_t payloadBufferSize ) { assert(self); assert(record); assert((int)sizeof(*record) <= recordBufferSize); if( sizeof(*record) > recordBufferSize) { return QUEUE_RC_NO_MEMORY; } // [ queue record header ][ some data ][ payload ] // |<-- queue_record_t ->| |< size >| // |<-------------- record->size --------------->| int rc = ringbuf_peek(self, (void *)record, sizeof(*record)); assert(sizeof(*record) == rc); if(sizeof(*record) != rc) { return QUEUE_RC_EMPTY; } assert(record->payload + sizeof(*record) <= record->size ); assert(record->size <= ringbuf_size(self)); assert(record->size >= sizeof(*record)); //assert(record->size <= recordBufferSize + payloadBufferSize ); //assert(record->payload <= payloadBufferSize ); if( (record->payload > record->size + sizeof(*record)) || record->size < sizeof(*record) ) { return QUEUE_RC_INTERNAL_ERROR; } if( payloadBufferSize > record->payload ) { payloadBufferSize = record->payload; } if( recordBufferSize > record->size - record->payload ) { recordBufferSize = record->size - record->payload; } rc = ringbuf_peek(self, (void *)record, recordBufferSize); assert(recordBufferSize == rc); if(recordBufferSize != rc) { return QUEUE_RC_INTERNAL_ERROR; } if( payloadBufferSize > 0 ) { assert(payload); if( NULL != payload ) { int prc = ringbuf_peek_offset(self, (void *)payload, payloadBufferSize, (record->size - record->payload) ); // payload offset assert(payloadBufferSize == prc); if(payloadBufferSize != prc) { return QUEUE_RC_INTERNAL_ERROR; } rc += prc; } } return rc; } #if 0 int queue_peek_n(const queue_t * self, queue_record_t * record, int16_t partSize) { // Reading t struct first and getting size of whole // record struct. Then reading a part of record struct. assert(self); assert(record); assert((int)sizeof(*record) <= partSize); int rc = ringbuf_peek(self, (void *)record, sizeof(*record)); assert(sizeof(*record) == rc); if(sizeof(*record) != rc) { return QUEUE_RC_EMPTY; } assert(record->size <= ringbuf_size(self)); if( partSize > record->size ) { partSize = record->size; } rc = ringbuf_peek(self, (void *)record, partSize); assert(partSize == rc); if(partSize != rc) { return QUEUE_RC_INTERNAL_ERROR; } return partSize; } #endif