summaryrefslogtreecommitdiff
path: root/plugins/!NotAdopted/IMO2sProxy/src/common/fifo.c
blob: d703ac33d46fe928adfbab5eea15051decd7cedb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include <stdlib.h>
#include <string.h>
#include "fifo.h"

struct _tagFIFO
{
	unsigned int    uiCount;
	unsigned int    uiCapacity;
	unsigned int	uiActInd;
	char			*acStorage;
};


TYP_FIFO *Fifo_Init(unsigned int uiCapacity)
{
	TYP_FIFO *pstHandle;

	pstHandle = (TYP_FIFO *)malloc(sizeof(TYP_FIFO));
	if (!pstHandle) return NULL;
	pstHandle->uiCount = pstHandle->uiActInd = 0;
	pstHandle->uiCapacity = uiCapacity;
	if (uiCapacity == 0)
		pstHandle->acStorage = NULL;
	else
	{
		pstHandle->acStorage = (char *)malloc(uiCapacity);
		if (!pstHandle->acStorage)
		{
			free (pstHandle);
			return NULL;
		}
	}
	return pstHandle;
}

void Fifo_Exit(TYP_FIFO *pstHandle)
{
	if (pstHandle->acStorage)
		free (pstHandle->acStorage);
	free (pstHandle);
}

char *Fifo_AllocBuffer(TYP_FIFO *pstHandle, unsigned int uiPCount)
{
	unsigned int uiCount = pstHandle->uiCount;
	
	if (!Fifo_Add (pstHandle, NULL, uiPCount)) return NULL;
	return &pstHandle->acStorage[pstHandle->uiActInd+uiCount];
	
}

BOOL Fifo_Add(TYP_FIFO *pstHandle, char *acPBytes, unsigned int uiPCount)
{
	unsigned int uiFree;

	if (uiPCount == 0) return TRUE;
	if (pstHandle->uiCapacity == 0)
	{
		if (!(pstHandle->acStorage = (char *)calloc(1, uiPCount)))
			return FALSE;
		if (acPBytes)
			memcpy(pstHandle->acStorage, acPBytes, uiPCount);
		else
			memset(pstHandle->acStorage, 0, uiPCount);
		pstHandle->uiCapacity = pstHandle->uiCount = uiPCount;
		pstHandle->uiActInd = 0;
	}
	else
	{
		uiFree = pstHandle->uiCapacity-(pstHandle->uiActInd+pstHandle->uiCount);
		if (uiFree < uiPCount)
		{
			if (pstHandle->uiActInd>=uiPCount && pstHandle->uiActInd*4>pstHandle->uiCount)
			{
				memmove(pstHandle->acStorage, pstHandle->acStorage+pstHandle->uiActInd, pstHandle->uiCount);
				pstHandle->uiActInd = 0;
			}
			else
			{
				char *acBuf;
				unsigned int uiNewLen;

				if (pstHandle->uiCapacity*2 <
					pstHandle->uiCount+pstHandle->uiActInd+uiPCount)
					uiNewLen = pstHandle->uiCount+pstHandle->uiActInd+uiPCount;
				else
					uiNewLen = pstHandle->uiCapacity*2;
				acBuf = realloc(pstHandle->acStorage, uiNewLen);
				if (acBuf == NULL) return FALSE;
				pstHandle->acStorage = acBuf;
				memset (acBuf+pstHandle->uiCapacity, 0, uiNewLen-pstHandle->uiCapacity);
				pstHandle->uiCapacity = uiNewLen;
			}
		}
		if (acPBytes)
			memcpy (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], acPBytes, uiPCount);
		else
			memset (&pstHandle->acStorage[pstHandle->uiActInd+pstHandle->uiCount], 0, uiPCount);

		pstHandle->uiCount += uiPCount;
	}

	return TRUE;
}

BOOL Fifo_AddString(TYP_FIFO *pstHandle, char *pszString)
{
	BOOL bRet;

	while (pstHandle->uiCount && pstHandle->acStorage[pstHandle->uiCount+pstHandle->uiActInd-1]==0)
		pstHandle->uiCount--;
	bRet = Fifo_Add (pstHandle, pszString, strlen(pszString)+1);
	return bRet;
}

char *Fifo_Get (TYP_FIFO *pstHandle, unsigned int *uiPCount)
{
	unsigned int uiCount;
	char *pRet;

	if (!uiPCount) uiCount = pstHandle->uiCount;
	else
	{
		if (pstHandle->uiCount < *uiPCount)
			*uiPCount = pstHandle->uiCount;
		uiCount = *uiPCount;
	}
	if (!uiCount) return NULL;

	pRet = &pstHandle->acStorage[pstHandle->uiActInd];
	pstHandle->uiActInd += uiCount;
	pstHandle->uiCount -= uiCount;
	return pRet;
}

void Fifo_Reset (TYP_FIFO *pstHandle)
{
	pstHandle->uiCount = pstHandle->uiActInd = 0;
}

unsigned int Fifo_Count (TYP_FIFO *pstHandle)
{
	return pstHandle->uiCount;
}