-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbufx.cpp
137 lines (126 loc) · 3.44 KB
/
bufx.cpp
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
#include "bufx.h"
#include "typy.h"
#include <stdlib.h>
#include <string.h>
BufClass::BufClass(void)
{
BufLen = BUF_DEFSIZE; /* Domyślna wielkość bufora */
BufPtr = (Byte *) malloc(BufLen);
if(BufPtr != NULL)
{
BufEnd = BufPtr + BufLen;
FirstDataPtr = FirstFreePtr = BufPtr;
DataAmount = 0; /* Na razie brak danych w buforze */
InputState = STATE_ON; /* Bufor działa */
}
else /* Brakło pamięci na utworzenie bufora */
{
SygError("BufClass: Konstruktor -- brak pamięci.");
}
PrevProcess = NextProcess = NULL; /* Na początku nie ma powiązań */
}
/******************************************************************************/
BufClass::~BufClass(void)
{
if(BufPtr != NULL) /* Usuwamy przydzielony obszar pamięci */
{
free(BufPtr);
BufPtr = NULL;
}
}
/******************************************************************************/
/* Dopisuje do bufora bajty */
void BufClass::PutByteArea(Byte * obszar, int ile)
{
while(ile > 0)
{
FreeBytes = BufLen - DataAmount;
ToEnd = BufEnd - FirstFreePtr;
/* Spróbuj zapisać trochę danych do bufora */
Zapis = (ile < FreeBytes) ? ile : FreeBytes;
/* Próbujemy zapisać "Zapis" bajtów za tym razem */
Part1 = (Zapis < ToEnd) ? Zapis : ToEnd;
Part2 = Zapis - ToEnd; /* Liczba bajtów do zapisania w drugim buforze */
/* Zapis części "Part1" */
memcpy(FirstFreePtr, obszar, Part1);
if(Part2 >= 0)
{
/* Zapis na pewno zapełnił pierwszy etap bufora */
if(Part2 > 0) /* Jeśli są jeszcze jakieś dane, to je zapisujemy */
{
memcpy(BufPtr, obszar + Part1, Part2);
}
/* Poprawiamy wskaźniki */
FirstFreePtr = BufPtr + Part2;
}
else /* Zapis składał się tylko z jednej części zapisu */
{
/* Poprawiamy wskaźniki */
FirstFreePtr += Zapis;
}
obszar += Zapis;
ile -= Zapis;
DataAmount += Zapis;
/* Jeśli zapełniliśmy do końca bufor, to próbujemy popchnąć dane dalej */
if(DataAmount == BufLen)
{
NextProcess->Work();
}
}
}
/******************************************************************************/
/* Dopisuje do bufora bajty */
int BufClass::GetByteArea(Byte * obszar, int ile)
{
Zapis = ile < DataAmount ? ile : DataAmount; /* Tyle będziemy zapisywać */
if(Zapis > 0)
{
/* Tu mamy dane, które możemy przetransmitować do bufora */
ToEnd = BufEnd - FirstDataPtr;
Part1 = Zapis < ToEnd ? Zapis : ToEnd; /* Ile w pierwszej paczce */
Part2 = Zapis - ToEnd;
memcpy(obszar, FirstDataPtr, Part1);
if(Part2 >= 0) /* Mamy przynajmniej trochę dwuczęściową transmisję */
{
if(Part2 > 0)
{
memcpy(obszar + Part1, BufPtr, Part2);
}
FirstDataPtr = BufPtr + Part2;
}
else /* Tu będzie transmisja tylko z jednego bloku */
{
FirstDataPtr += Zapis;
}
DataAmount -= Zapis;
}
else
{
if(Zapis < 0)
{
/* To jest wywoływane, gdy w buforze jest "x" bajtów (x < 0) lub
gdy proces poprosił o "x" bajtów */
SygError("To jakiś WIELKI BŁĄD !!! To się nie powinno zdarzyć!!!");
}
if(InputState == STATE_ON)
{
Zapis = 0; /* Brak chwilowo danych */
}
else
{
Zapis = EOF; /* Więcej już nie będzie danych */
}
}
return Zapis;
}
/******************************************************************************/
/* Sygnalizacja, że już nie będzie danych */
void BufClass::SignalEndOfData(void)
{
InputState = EOF;
while( ! NextProcess->StateEOF())
{
NextProcess->Work();
}
}
/******************************************************************************/