/*
* Copyright (c) 2023 Harshmohan Kulkarni
* Copyright (c) 2015-2023 Free Software Foundation, Inc.
*
* This file is part of libwget.
*
* Libwget is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Libwget is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libwget. If not, see .
*
*
* Queue using linked list routines
*
*/
#include
#include
#include
#include
#include "private.h"
struct wget_queue_st{
struct wget_queue_node *head;
struct wget_queue_node *tail;
};
wget_queue
*wget_queue_init()
{
wget_queue *queue = wget_malloc(sizeof(wget_queue));
if (queue){
queue->head = NULL;
queue->tail = NULL;
}
return queue;
}
void
wget_queue_deinit(wget_queue *queue)
{
if (queue){
wget_queue_node *fn = queue->head;
wget_queue_node *next = queue->head;
while (fn){
next = fn->next;
xfree(fn);
fn = next;
}
fn = NULL;
next = NULL;
xfree(queue);
}
}
int
wget_queue_is_empty(wget_queue *queue)
{
return (queue->head == NULL);
}
void*
wget_queue_enqueue(wget_queue *queue, const void *data, size_t size)
{
struct wget_queue_node *node = wget_malloc(sizeof(struct wget_queue_node));
if (!node)
return NULL;
if (!data) {
xfree(node);
return NULL;
}
node->data = data;
node->next = NULL;
if (wget_queue_is_empty(queue)) {
node->prev = NULL;
queue->head = node;
queue->tail = node;
} else {
node->prev = queue->tail;
queue->tail->next = node;
queue->tail = node;
}
return node + 1;
}
void*
wget_queue_dequeue(wget_queue *queue)
{
if (wget_queue_is_empty(queue)) {
return NULL;
}
struct wget_queue_node *node = queue->head;
void *data = node->data;
queue->head = queue->head->next;
if (queue->head != NULL) {
queue->head->prev = NULL;
} else {
queue->tail = NULL;
}
xfree(node);
return data;
}
wget_byte *
wget_queue_peek(wget_queue *queue)
{
if (wget_queue_is_empty(queue)) {
return NULL;
}
return queue->head->data;
}
wget_byte *
wget_queue_peek_transmitted_node(wget_queue *queue)
{
if (wget_queue_is_empty(queue))
return NULL;
wget_queue_node *temp = queue->head;
while(temp) {
wget_byte *data = (wget_byte *)(temp->data);
if (wget_byte_get_transmitted(data) && wget_byte_get_type(data) == REQUEST_BYTE) {
return data;
}
temp = temp->next;
}
return NULL;
}
wget_queue_node *
wget_queue_dequeue_transmitted_node(wget_queue *queue)
{
if (wget_queue_is_empty(queue))
return;
wget_queue_node *temp = queue->head;
while(temp) {
wget_byte *data = (wget_byte *)(temp->data);
if (wget_byte_get_transmitted(data) && wget_byte_get_type(data) == REQUEST_BYTE) {
if (temp->prev)
temp->prev->next = temp->next;
else
queue->head = temp->next;
if (temp->next)
temp->next->prev = temp->prev;
else
queue->tail = temp->prev;
return temp;
}
temp = temp->next;
}
return;
}
wget_queue_node *
wget_queue_dequeue_data_node(wget_queue *queue)
{
if (wget_queue_is_empty(queue))
return NULL;
wget_queue_node *temp = queue->head;
while(temp) {
wget_byte *data = (wget_byte *)(temp->data);
if (!wget_byte_get_transmitted(data) && wget_byte_get_type(data) == RESPONSE_DATA_BYTE) {
if (temp->prev)
temp->prev->next = temp->next;
else
queue->head = temp->next;
if (temp->next)
temp->next->prev = temp->prev;
else
queue->tail = temp->prev;
return temp;
}
temp = temp->next;
}
return NULL;
}
wget_byte *
wget_queue_peek_untransmitted_node(wget_queue *queue)
{
if (wget_queue_is_empty(queue))
return NULL;
wget_queue_node *temp = queue->head;
while(temp) {
wget_byte *data = (wget_byte *)(temp->data);
if (!wget_byte_get_transmitted(data) && wget_byte_get_type(data) == REQUEST_BYTE) {
return data;
}
temp = temp->next;
}
return NULL;
}
void wget_queue_free_node(wget_queue_node *node,
void (*data_free_func)(void *))
{
if (node) {
if (node->data && data_free_func)
data_free_func(node->data);
xfree(node);
}
}