Choco OS  V.0.16.9.0
Join to the chocolate world
oc_stream.c
Go to the documentation of this file.
1 
27 #include <oc_stream.h>
28 #include <oc_object.h>
29 #include <oc_streamman.h>
30 
36 #define _________________________________________TYPES_SECTION______________________________________________________________________________
37 
38 struct Stream_t
39 {
40  oC_ObjectControl_t ObjectControl;
41  oC_Stream_Type_t Type;
42  oC_Driver_t Driver;
43  const void * Config;
44  void * DriverContext;
45  const char * Name;
46 };
47 
48 #undef _________________________________________TYPES_SECTION______________________________________________________________________________
49 
55 #define _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
56 
57 //==========================================================================================================================================
58 //==========================================================================================================================================
59 oC_Stream_t oC_Stream_New( Allocator_t Allocator , AllocationFlags_t Flags , oC_Stream_Type_t Type , const char * Name , oC_Driver_t Driver , const void * Config )
60 {
61  oC_Stream_t stream = NULL;
62 
63  if(
64  ((Type & oC_Stream_Type_Input) || (Type & oC_Stream_Type_Output)) &&
65  isaddresscorrect(Config) &&
66  isaddresscorrect(Name)
67  )
68  {
69  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
70  void * context = NULL;
71 
72  errorCode = oC_Driver_Configure(Driver,Config,&context);
73 
74  if(oC_ErrorOccur(errorCode))
75  {
76  oC_SaveError(Driver->FileName , errorCode);
77  }
78  else
79  {
80  stream = kmalloc(sizeof(struct Stream_t) , Allocator , Flags);
81 
82  if(stream)
83  {
84  stream->ObjectControl = oC_CountObjectControl(stream,oC_ObjectId_Stream);
85  stream->Type = Type;
86  stream->Driver = Driver;
87  stream->Config = Config;
88  stream->DriverContext = context;
89  stream->Name = Name;
90  }
91  else
92  {
93  oC_SaveError(Driver->FileName,oC_ErrorCode_AllocationError);
94  }
95  }
96  }
97 
98  return stream;
99 }
100 
101 //==========================================================================================================================================
102 //==========================================================================================================================================
103 bool oC_Stream_Delete( oC_Stream_t * Stream )
104 {
105  bool deleted = false;
106 
107  if(oC_Stream_IsCorrect(*Stream))
108  {
109  (*Stream)->ObjectControl = 0;
110 
111  deleted = kfree(*Stream,AllocationFlags_CanWaitForever);
112 
113  if(deleted)
114  {
115  *Stream = NULL;
116  }
117  else
118  {
119  (*Stream)->ObjectControl = oC_CountObjectControl(*Stream,oC_ObjectId_Stream);
120  }
121  }
122 
123  return deleted;
124 }
125 
126 //==========================================================================================================================================
127 //==========================================================================================================================================
128 bool oC_Stream_IsCorrect( oC_Stream_t Stream )
129 {
130  return isram(Stream) && oC_CheckObjectControl(Stream,oC_ObjectId_Stream,Stream->ObjectControl);
131 }
132 
133 //==========================================================================================================================================
134 //==========================================================================================================================================
135 bool oC_Stream_IsType( oC_Stream_t Stream , oC_Stream_Type_t Type )
136 {
137  return oC_Stream_IsCorrect(Stream) && ((Stream->Type & Type) == Type);
138 }
139 
140 //==========================================================================================================================================
141 //==========================================================================================================================================
142 oC_ErrorCode_t oC_Stream_Write( oC_Stream_t Stream , const char * Buffer , uint32_t * Size , oC_IoFlags_t IoFlags )
143 {
144  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
145 
146  if(oC_Stream_IsCorrect(Stream) == false && (IoFlags & oC_IoFlags_WriteToStdError))
147  {
148  Stream = oC_StreamMan_GetStdErrorStream();
149  }
150 
151  if(
152  oC_AssignErrorCodeIfFalse(&errorCode , oC_Stream_IsCorrect(Stream) , oC_ErrorCode_ObjectNotCorrect ) &&
153  oC_AssignErrorCodeIfFalse(&errorCode , isram(Size) , oC_ErrorCode_OutputAddressNotInRAM ) &&
154  oC_AssignErrorCodeIfFalse(&errorCode , *Size > 0 , oC_ErrorCode_SizeNotCorrect ) &&
155  oC_AssignErrorCodeIfFalse(&errorCode , Stream->Type & oC_Stream_Type_Output , oC_ErrorCode_StreamTypeNotCorrect )
156  )
157  {
158  oC_Time_t timeout = oC_IoFlags_GetTimeout(IoFlags);
159  uint32_t bytesToSend = *Size;
160  uint32_t sentBytes = 0;
161 
162  while(sentBytes < (*Size))
163  {
164  errorCode = oC_Driver_Write(Stream->Driver,Stream->DriverContext,&Buffer[sentBytes],&bytesToSend,timeout);
165 
166  sentBytes += bytesToSend;
167  bytesToSend = (*Size) - sentBytes;
168 
169  if(oC_ErrorOccur(errorCode) &&
170  errorCode != oC_ErrorCode_Timeout &&
171  errorCode != oC_ErrorCode_NoAllBytesRead &&
172  errorCode != oC_ErrorCode_NotAllSent
173  )
174  {
175  break;
176  }
177  else
178  {
179  errorCode = oC_ErrorCode_None;
180  }
181 
182  if(oC_Bits_AreBitsSetU32(IoFlags,oC_IoFlags_WaitForAllElements))
183  {
184  continue;
185  }
186 
187  if(sentBytes == 0 && oC_Bits_IsAtLeastOneBitSetU32(IoFlags,oC_IoFlags_WaitForSomeElements | oC_IoFlags_WaitForAllElements))
188  {
189  continue;
190  }
191  else if(oC_Bits_AreBitsSetU32(IoFlags,oC_IoFlags_WaitForAllElements))
192  {
193  continue;
194  }
195  else if(oC_Bits_AreBitsSetU32(IoFlags,oC_IoFlags_NoTimeout))
196  {
197  continue;
198  }
199  }
200 
201  *Size = sentBytes;
202  }
203 
204  return errorCode;
205 }
206 
207 //==========================================================================================================================================
208 //==========================================================================================================================================
209 oC_ErrorCode_t oC_Stream_Read( oC_Stream_t Stream , char * outBuffer , uint32_t * Size , oC_IoFlags_t IoFlags )
210 {
211  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
212 
213  if(
214  oC_AssignErrorCodeIfFalse(&errorCode , oC_Stream_IsCorrect(Stream) , oC_ErrorCode_ObjectNotCorrect ) &&
215  oC_AssignErrorCodeIfFalse(&errorCode , Stream->Type & oC_Stream_Type_Input , oC_ErrorCode_StreamTypeNotCorrect ) &&
216  oC_AssignErrorCodeIfFalse(&errorCode , isram(Size) , oC_ErrorCode_OutputAddressNotInRAM ) &&
217  oC_AssignErrorCodeIfFalse(&errorCode , *Size > 0 , oC_ErrorCode_SizeNotCorrect )
218  )
219  {
220  oC_Time_t timeout = oC_IoFlags_GetTimeout(IoFlags);
221  uint32_t bytesToRead = *Size;
222  uint32_t readBytes = 0;
223 
224  while(readBytes < (*Size))
225  {
226  errorCode = oC_Driver_Read(Stream->Driver,Stream->DriverContext,&outBuffer[readBytes],&bytesToRead,timeout);
227 
228  readBytes += bytesToRead;
229  bytesToRead = (*Size) - readBytes;
230 
231  if(oC_ErrorOccur(errorCode) &&
232  errorCode != oC_ErrorCode_Timeout &&
233  errorCode != oC_ErrorCode_NoAllBytesRead &&
234  errorCode != oC_ErrorCode_NoneElementReceived
235  )
236  {
237  break;
238  }
239  else if(errorCode != oC_ErrorCode_Timeout)
240  {
241  errorCode = oC_ErrorCode_None;
242  }
243 
244  if(readBytes == 0 && oC_Bits_IsAtLeastOneBitSetU32(IoFlags,oC_IoFlags_WaitForSomeElements | oC_IoFlags_WaitForAllElements | oC_IoFlags_NoTimeout))
245  {
246  continue;
247  }
248  else if(oC_Bits_AreBitsSetU32(IoFlags,oC_IoFlags_WaitForAllElements))
249  {
250  continue;
251  }
252  else
253  {
254  break;
255  }
256  }
257 
258  *Size = readBytes;
259  }
260 
261  return errorCode;
262 }
263 
264 //==========================================================================================================================================
265 //==========================================================================================================================================
266 oC_ErrorCode_t oC_Stream_ClearReadBuffer( oC_Stream_t Stream )
267 {
268  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
269 
270  if(
271  ErrorCondition( oC_Stream_IsCorrect(Stream) , oC_ErrorCode_ObjectNotCorrect )
272  && ErrorCondition( Stream->Type & oC_Stream_Type_Input , oC_ErrorCode_StreamTypeNotCorrect )
273  && ErrorCondition( isaddresscorrect(Stream->Driver) , oC_ErrorCode_WrongAddress )
274  )
275  {
276  errorCode = oC_Driver_HandleIoctl(Stream->Driver, Stream->DriverContext, oC_IoCtl_SpecialCommand_ClearRxFifo, NULL);
277  }
278 
279  return errorCode;
280 }
281 
282 //==========================================================================================================================================
283 //==========================================================================================================================================
284 const char * oC_Stream_GetName( oC_Stream_t Stream )
285 {
286  const char * name = "unknown";
287 
288  if(oC_Stream_IsCorrect(Stream))
289  {
290  name = Stream->Name;
291  }
292 
293  return name;
294 }
295 
296 //==========================================================================================================================================
297 //==========================================================================================================================================
298 oC_Driver_t oC_Stream_GetDriver( oC_Stream_t Stream )
299 {
300  oC_Driver_t driver = NULL;
301 
302  if(oC_Stream_IsCorrect(Stream))
303  {
304  driver = Stream->Driver;
305  }
306 
307  return driver;
308 }
309 
310 
311 #undef _________________________________________FUNCTIONS_SECTION__________________________________________________________________________
static bool oC_Bits_AreBitsSetU32(uint32_t BitMask, uint32_t BitsToCheck)
checks if all bits in field are set
Definition: oc_bits.h:884
The file with interface for stream.
identifier for allocations
Definition: oc_stdlib.h:159
static bool oC_Bits_IsAtLeastOneBitSetU32(uint32_t BitMask, uint32_t BitsToCheck)
checks if at least one of bits in field is set
Definition: oc_bits.h:1020
The file with helper macros for managing objects.
The file with interface for stream manager.
uint32_t oC_ObjectControl_t
stores object control value
Definition: oc_object.h:141
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
Definition: oc_object.h:168
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
Definition: oc_object.h:203
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
#define NULL
pointer to a zero
Definition: oc_null.h:37