/* * This file is part of the PikaPython project. * http://github.com/pikastech/pikapython * * MIT License * * Copyright (c) 2021 lyon liang6516@outlook.com * Copyright (c) 2023 Gorgon Meducer embedded_zhuroan@hotmail.com * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ #define __DATA_QUEUE_CLASS_IMPLEMENT__ #include "dataQueue.h" #include "PikaPlatform.h" #include "dataArgs.h" void queue_init(Queue* queue) { args_setInt(queue, "__t", 0); args_setInt(queue, "__b", 0); } Queue* New_queue(void) { Args* args = New_args(NULL); queue_init(args); return (Queue*)args; } int32_t queue_deinit(Queue* queue) { Args* args = queue; args_deinit(args); return 0; } int32_t queue_pushArg(Queue* queue, Arg* arg) { Args* args = queue; uint64_t top = args_getInt(args, "__t"); /* add top */ args_setInt(args, "__t", top + 1); char buff[11]; arg = arg_setName(arg, fast_itoa(buff, top)); return args_setArg(args, arg); } Arg* __queue_popArg_noRmoveArg(Queue* queue) { Args* args = queue; uint64_t top = args_getInt(args, "__t"); uint64_t bottom = args_getInt(args, "__b"); if (top - bottom < 1) { return NULL; } /* add bottom */ args_setInt(args, "__b", bottom + 1); char buff[11]; Arg* res = args_getArg(args, fast_itoa(buff, bottom)); /* not deinit arg to keep str buff */ return res; } int32_t queue_pushInt(Queue* queue, int val) { return queue_pushArg(queue, arg_newInt(val)); } int64_t queue_popInt(Queue* queue) { return arg_getInt(__queue_popArg_noRmoveArg(queue)); } int32_t queue_pushFloat(Queue* queue, pika_float val) { return queue_pushArg(queue, arg_newFloat(val)); } pika_float queue_popFloat(Queue* queue) { return arg_getFloat(__queue_popArg_noRmoveArg(queue)); } int32_t queue_pushStr(Queue* queue, char* str) { return queue_pushArg(queue, arg_newStr(str)); } char* queue_popStr(Queue* queue) { return arg_getStr(__queue_popArg_noRmoveArg(queue)); } ByteQueue* byteQueue_init(ByteQueue* queue, void* buffer, uint_fast16_t size, pika_bool is_queue_full) { pika_assert(NULL != queue); pika_assert(NULL != buffer); pika_assert(size > 0); pika_platform_memset(queue, 0, sizeof(ByteQueue)); queue->buffer = buffer; queue->buffer_size = size; if (is_queue_full) { queue->count = size; queue->peek_count = size; } return queue; } pika_bool byteQueue_readOne(ByteQueue* queue, uint8_t* byte_ptr) { pika_assert(NULL != queue); uint8_t byte; pika_bool result = pika_false; /* ------------------atomicity sensitive start---------------- */ do { if ((queue->head == queue->tail) && (0 == queue->count)) { /* empty */ break; } byte = queue->buffer[queue->head++]; queue->count--; if (queue->head >= queue->buffer_size) { queue->head = 0; } /* reset peek */ queue->peek_count = queue->count; queue->peek = queue->head; if (NULL != byte_ptr) { *byte_ptr = byte; } result = pika_true; } while (0); /* ------------------atomicity sensitive end ---------------- */ return result; } pika_bool byteQueue_peekOne(ByteQueue* queue, uint8_t* byte_ptr) { pika_assert(NULL != queue); uint8_t byte; pika_bool result = pika_false; /* ------------------atomicity sensitive start---------------- */ do { if ((queue->peek == queue->tail) && (0 == queue->peek_count)) { /* empty */ break; } byte = queue->buffer[queue->peek++]; queue->peek_count--; if (queue->peek >= queue->buffer_size) { queue->peek = 0; } if (NULL != byte_ptr) { *byte_ptr = byte; } result = pika_true; } while (0); /* ------------------atomicity sensitive end ---------------- */ return result; } void byteQueue_resetPeek(ByteQueue* queue) { pika_assert(NULL != queue); /* ------------------atomicity sensitive start---------------- */ queue->peek_count = queue->count; queue->peek = queue->head; /* ------------------atomicity sensitive end ---------------- */ } uint_fast16_t byteQueue_getPeekedNumber(ByteQueue* queue) { return queue->count - queue->peek_count; } uint_fast16_t byteQueue_peekAvailableCount(ByteQueue* queue) { return queue->peek_count; } void byteQueue_dropAllPeeked(ByteQueue* queue) { pika_assert(NULL != queue); /* ------------------atomicity sensitive start---------------- */ queue->count = queue->peek_count; queue->head = queue->peek; /* ------------------atomicity sensitive end ---------------- */ } pika_bool byteQueue_writeOne(ByteQueue* queue, uint8_t byte) { pika_assert(NULL != queue); pika_bool result = pika_false; /* ------------------atomicity sensitive start---------------- */ do { if ((queue->head == queue->tail) && (0 != queue->count)) { /* full */ break; } queue->buffer[queue->tail++] = byte; queue->count++; queue->peek_count++; if (queue->tail >= queue->buffer_size) { queue->tail = 0; } result = pika_true; } while (0); /* ------------------atomicity sensitive end ---------------- */ return result; }