/************************************************************
* Details: 网络队列
* Encode: UTF-8
* Platform: Android & Linux
* Author: R&D 2
* Date: 2018-4-2
************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "gtnetworkqueue.h"

GtNetworkQueue::GtNetworkQueue()
{
    _networkQueue = NULL;
}

GtNetworkQueue::~GtNetworkQueue()
{
    releaseNetworkQueue();
}

/************************************************************
*功能：插入网络节点到网络队列末尾
*输入：node网络节点
*输出：无
*返回：true or false
*/
bool GtNetworkQueue::appendNode(stNetworkQueue *node)
{
    stNetworkQueue *tmpNode = NULL;
    if(node == NULL)
    {
        return false;
    }
    if(_networkQueue == NULL)
    {
        _networkQueue = node;
        _networkQueue->next = NULL;
    }
    else
    {
        tmpNode = _networkQueue;
        while(tmpNode->next != NULL)
        {
            tmpNode = tmpNode->next;
        }
        node->next = NULL;
        tmpNode->next = node;
    }
    return true;
}

/************************************************************
*功能：构建网络队列
*输入：maxSize网络队列最大长度
*输出：无
*返回：true or false
*/
bool GtNetworkQueue::initNetworkQueue(int maxSize)
{
    int i = 0;
    stNetworkQueue *node = NULL;

    for(i = 0; i < maxSize; i++)
    {
        node = (stNetworkQueue*)malloc(sizeof(stNetworkQueue));
        if(node == NULL)
        {
            return false;
        }
        else
        {
            memset(node, 0, sizeof(stNetworkQueue));
            node->item.nSocketFd = -1;
            node->next = NULL;
            if(!appendNode(node))
            {
                return false;
            }
        }
    }
    return true;
}

/************************************************************
*功能：释放网络队列
*输入：无
*输出：无
*返回：无
*/
void GtNetworkQueue::releaseNetworkQueue()
{
    stNetworkQueue *prevNode = NULL;
    stNetworkQueue *tmpNode = NULL;

    tmpNode = _networkQueue;
    if(tmpNode == NULL)
    {
        return;
    }
    while(tmpNode != NULL)
    {
        prevNode = tmpNode;
        tmpNode = tmpNode->next;
        if(prevNode->item.nSocketFd > -1)
        {
            close(prevNode->item.nSocketFd);
        }
        free(prevNode);
        prevNode = NULL;
    }
    _networkQueue = NULL;
}

/************************************************************
*功能：获取网络队列中空的节点
*输入：无
*输出：无
*返回：true or false
*/
bool GtNetworkQueue::getEmptyNode(int *offset, stNetworkItem *item)
{
    int index = 0;
    stNetworkQueue *node = NULL;

    node = _networkQueue;
    if(node == NULL)
    {
        return false;
    }
    while(node != NULL)
    {
        if(node->item.nSocketFd == -1)
        {
            memcpy(&(node->item), item, sizeof(stNetworkItem));
            *offset = index;
            return true;
        }
        else
        {
            node = node->next;
            index++;
        }
    }
    return false;
}

/************************************************************
*功能：获取指定位置的网络队列节点
*输入：index网络队列索引
*输出：attr网络队列节点属性
*返回：true or false
*/
bool GtNetworkQueue::getNode(int index, stNetworkItem *item)
{
    int sn = 0;
    stNetworkQueue *node = NULL;

    if(item == NULL || index < 0)
    {
        return false;
    }
    node = _networkQueue;
    while(node != NULL)
    {
        if(index == sn)
        {
            memcpy(item, &node->item, sizeof(stNetworkItem));
            return true;
        }
        else
        {
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：设置指定位置的网络队列节点
*输入：index网络队列索引
*输入：attr网络队列节点属性
*输出：无
*返回：true or false
*/
bool GtNetworkQueue::setNode(int index, stNetworkItem *item)
{
    int sn = 0;
    stNetworkQueue *node = NULL;

    if(index < 0 || item == NULL)
    {
        return false;
    }
    node = _networkQueue;
    while(node != NULL)
    {
        if(index == sn)
        {
            memcpy(&node->item, item, sizeof(stNetworkItem));
            return true;
        }
        else
        {
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：将指定位置的网络节点移动到网络队列末尾，并清除其属性数据
*输入：index网络队列索引
*输出：无
*返回：true or false
*/
bool GtNetworkQueue::recycleNode(int index)
{
    int sn = 0;
    stNetworkQueue *node = NULL;
    stNetworkQueue *prevNode = NULL;
    stNetworkQueue *endNode = NULL;

    if(index < 0)
    {
        return false;
    }
    node = _networkQueue;
    if(node != NULL && node->next == NULL)
    {
        memset(&node->item, 0, sizeof(stNetworkItem));
        node->item.nSocketFd = -1;
        return true;
    }
    while(node != NULL)
    {
        if(index == sn)
        {
            if(sn == 0)
            {
                _networkQueue = _networkQueue->next;
            }
            else
            {
                prevNode->next = node->next;
            }
            endNode = _networkQueue;
            while(endNode->next != NULL)
            {
                endNode = endNode->next;
            }
            endNode->next = node;
            node->next = NULL;
            memset(&node->item, 0, sizeof(stNetworkItem));
            node->item.nSocketFd = -1;
            return true;
        }
        else
        {
            prevNode = node;
            node = node->next;
            sn++;
        }
    }
    return false;
}

/************************************************************
*功能：获取网络队列长度
*输入：无
*输出：无
*返回：队列长度
*/
int GtNetworkQueue::size()
{
    int size = 0;
    stNetworkQueue *node = NULL;

    node = _networkQueue;
    while(node != NULL)
    {
        size++;
        node = node->next;
    }
    return size;
}

/************************************************************
*功能：获取网络有效的节点数
*输入：无
*输出：无
*返回：节点数
*/
int GtNetworkQueue::validNodeSize()
{
    int size = 0;
    stNetworkQueue *node = NULL;

    node = _networkQueue;
    while(node != NULL)
    {
        if(node->item.nSocketFd > -1)
        {
            size++;
        }
        node = node->next;
    }
    return size;
}
