]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - apps/tidep0084.git/blob - components/common/src/stream_mem.c
Updated TI Linux Sensor To Cloud to the latest TI 15.4-Stack v2.4, now with CC13x2...
[apps/tidep0084.git] / components / common / src / stream_mem.c
1 /******************************************************************************
2  @file stream_mem.c
4  @brief TIMAC 2.0 API Treat a chunk of memory as a stream
6  Group: WCS LPC
7  $Target Devices: Linux: AM335x, Embedded Devices: CC1310, CC1350, CC1352$
9  ******************************************************************************
10  $License: BSD3 2016 $
11   
12    Copyright (c) 2015, Texas Instruments Incorporated
13    All rights reserved.
14   
15    Redistribution and use in source and binary forms, with or without
16    modification, are permitted provided that the following conditions
17    are met:
18   
19    *  Redistributions of source code must retain the above copyright
20       notice, this list of conditions and the following disclaimer.
21   
22    *  Redistributions in binary form must reproduce the above copyright
23       notice, this list of conditions and the following disclaimer in the
24       documentation and/or other materials provided with the distribution.
25   
26    *  Neither the name of Texas Instruments Incorporated nor the names of
27       its contributors may be used to endorse or promote products derived
28       from this software without specific prior written permission.
29   
30    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
31    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
32    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
33    PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
34    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
35    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
36    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
37    OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
38    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
39    OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
40    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  ******************************************************************************
42  $Release Name: TI-15.4Stack Linux x64 SDK$
43  $Release Date: Sept 27, 2017 (2.04.00.13)$
44  *****************************************************************************/
46 #include "compiler.h"
48 #include "stream.h"
49 #include "void_ptr.h"
50 #define _STREAM_IMPLIMENTOR_ 1
51 #include "stream_private.h"
53 #include <string.h>
54 #include <malloc.h>
56 /*!
57  * @var mem_check
58  * @brief [private] Used to verify the details pointe is valid
59  */
60 static const int mem_check = 'M';
62 /*!
63  * @struct mem_stream_details
64  * @brief Details about the memory buffer for the stream.
65  */
67 struct mem_stream_details
68 {
69     /*! Used to verify the structure is valid */
70     const int *check_ptr;
72     /*! Owning parent stream */
73     struct io_stream *pParent;
75     /* True if this buffer can be written */
76     bool is_wr;
78     /* True if this buffer can be read */
79     bool is_rd;
81     /* points to the buffer */
82     void *pBytes;
84     /* True if the buffer was allocated */
85     bool alloc;
87     /* Rd/Wr cursor (index) within buffer where IO will occur */
88     size_t cursor;
90     /* Size in bytes of the buffer. */
91     size_t bufsiz;
92 };
94 /*!
95  * @brief extract & validate the memory stream details from this stream.
96  * @param pIO - the io stream
97  * @returns NULL on error, or a details pointer.
98  */
99 static struct mem_stream_details *getM(struct io_stream *pIO)
101     struct mem_stream_details *pM;
103     /* cast it */
104     pM = (struct mem_stream_details *)(pIO->opaque_ptr);
106     /* perform our checks */
107     if(pM)
108     {
109         if(pM->check_ptr != &mem_check)
110         {
111             pM = NULL;
112         }
113     }
114     return (pM);
117 /*!
118  * @brief [private] Method function for the memory buffer stream to close
119  * @param pIO - the io stream we are closing.
120  * @returns NULL
121  */
122 static void mem_close(struct io_stream *pIO)
124     struct mem_stream_details *pM;
126     /* Extract */
127     pM = getM(pIO);
129     /* and zap */
130     if(pM)
131     {
132         if(pM->alloc)
133         {
134             if(pM->pBytes)
135             {
136                 memset((void *)(pM->pBytes), 0, pM->bufsiz);
137                 free((void *)(pM->pBytes));
138                 pM->pBytes = NULL;
139             }
140             memset((void*)(pM), 0, sizeof(*pM));
141         }
142         memset((void *)(pIO), 0, sizeof(*pIO));
143     }
146 /*!
147  * @brief [private] Method function for the memory buffer stream to write
148  * @param pIO - the io stream we are writing
149  * @param pBytes - pointer to the transfer buffer
150  * @param nbytes - count in bytes we are transfering
151  * @param timeout_mSecs - timeout [not used in this implmentation]
152  * @returns negative on error, or 0..actual bytes written.
153  */
154 static int mem_wr(struct io_stream *pIO,
155                    const void *pBytes,
156                    size_t nbytes,
157                    int timeout_mSecs)
159     struct mem_stream_details *pM;
161     (void)(timeout_mSecs);
163     /* extract */
164     pM = getM(pIO);
165     if(pM == NULL)
166     {
167         return (-1);
168     }
170     /* is this legal? */
171     if(!(pM->is_wr))
172     {
173         return (-1);
174     }
176     /* check space */
177     size_t space;
178     /* bufsiz is fixed at startup, cursor will not go beyond */
179     space = pM->bufsiz - pM->cursor;
181     /* don't go beyond our buffer */
182     if(nbytes > space)
183     {
184         nbytes = space;
185     }
187     /* if so, write */
188     if(nbytes)
189     {
190         memcpy(void_ptr_add(pM->pBytes, pM->cursor), pBytes, nbytes);
191         pM->cursor += nbytes;
192     }
194     /* return actual */
195     return ((int)nbytes);
198 /*!
199  * @brief [privatge] Method function for the memory buffer stream to reading
200  * @param pIO - the io stream we are reading
201  * @param pBytes - pointer to the transfer buffer
202  * @param nbytes - count in bytes we are transfering
203  * @param timeout_mSecs - timeout [not used in this implmentation]
204  * @returns negative on error, or 0..actual bytes read
205  */
206 static int mem_rd(struct io_stream *pIO,
207                    void *pBytes,
208                    size_t nbytes,
209                    int timeout_mSecs)
211     struct mem_stream_details *pM;
213     (void)(timeout_mSecs);
215     /* extract */
216     pM = getM(pIO);
217     if(pM == NULL)
218     {
219         return (-1);
220     }
222     /* sanity check */
223     if(!(pM->is_rd))
224     {
225         return (-1);
226     }
228     /* don't go beyond our buffer */
229     size_t avail;
230     /* bufsiz is fixed at startup, cursor will not go beyond */
231     avail = pM->bufsiz - pM->cursor;
233     if(nbytes > avail)
234     {
235         nbytes = avail;
236     }
238     /* transfer */
239     if(nbytes)
240     {
241         memcpy(pBytes, void_ptr_add(pM->pBytes, pM->cursor), nbytes);
242         pM->cursor += nbytes;
243     }
245     /* return actual */
246     return ((int)nbytes);
249 /*!
250  * @brief [private] determine if we can poll (rd) this memory buffer
251  * @param pIO - the io stream
252  * @param timeout_mSec - not used in this implimentation.
253  * @returns true if no error and not at the end of the buffer space
254  */
255 static bool mem_poll(struct io_stream *pIO, int timeout_mSec)
257     struct mem_stream_details *pM;
259     (void)(timeout_mSec);
261     /* extract */
262     pM = getM(pIO);
263     if(pM == NULL)
264     {
265         return (-1);
266     }
268     /* is it readable, and are we not at the end? */
269     if(pM->is_rd && (pM->cursor < pM->bufsiz))
270     {
271         /* then we can read */
272         return (true);
273     }
274     else
275     {
276         return (false);
277     }
280 /*!
281  * @brief [private] method to flush, we have no buffer.. this is not a FILE
282  * @param pIO - the io stream
283  */
284 static int mem_flush(struct io_stream *pIO)
286     (void)(pIO);
287     /* nothing to flush */
288     return (0);
291 /*!
292  * @var mem_funcs
293  * @brief Method function table for the memory IO routines
294  */
295 static const struct io_stream_funcs mem_funcs = {
296     .name = "string",
297     .close_fn = mem_close,
298     .wr_fn = mem_wr,
299     .rd_fn = mem_rd,
300     .poll_fn = mem_poll,
301     .flush_fn = mem_flush
302 };
304 /*!
305  * @brief [private] Common routine to create a memory buffer stream
306  * @param pBytes - the io buffer
307  * @param nBytes - the size in bytes of the io buffer
308  * @param is_wr - boolean true if this is writeable
309  * @param is_rd - boolean true if this is readable
310  * @param Returns non-zero handle on success
311  */
312 static intptr_t _mem_create(void *pBytes,
313                              size_t nbytes,
314                              bool is_wr,
315                              bool is_rd)
317     struct mem_stream_details *pM;
319     pM = calloc(1, sizeof(*pM));
320     if(!pM)
321     {
322         return (0);
323     }
325     pM->check_ptr   = &mem_check;
326     pM->is_wr       = is_wr;
327     pM->is_rd       = is_rd;
328     pM->pBytes      = pBytes;
329     if(pM->pBytes == NULL)
330     {
331         pM->alloc = true;
332         pM->pBytes = calloc(1, nbytes+1);
333         if(pM->pBytes == NULL)
334         {
335             goto fail;
336         }
337     }
339     pM->cursor      = 0;
340     pM->bufsiz      = nbytes;
342     pM->pParent = STREAM_createPrivate(&mem_funcs, (intptr_t)(pM));
343     if(pM->pParent != NULL)
344     {
345         return (STREAM_structToH(pM->pParent));
346     }
347  fail:
348     if(pM->alloc)
349     {
350         free((void *)(pM->pBytes));
351         pM->pBytes = NULL;
352     }
353     memset((void*)(pM), 0, sizeof(*pM));
354     free((void *)(pM));
355     return (0);
358 /*
359  * Create a stream from a null terminated string
360  *
361  * Public function defined in stream.h
362  */
363 intptr_t STREAM_stringCreate(const char *s)
365 #if defined(__linux__)
366 #pragma GCC diagnostic push
367 #pragma GCC diagnostic ignored "-Wcast-qual"
368 #endif
369     return (_mem_create((void *)s, strlen(s), 0, 1));
370 #if defined(__linux__)
371 #pragma GCC diagnostic pop
372 #endif
375 /*
376  * Create a stream from a chunk of memory
377  *
378  * Public function defined in stream.h
379  */
380 intptr_t STREAM_memCreate(void *pBytes, size_t nbytes)
382     return (_mem_create(pBytes, nbytes, 1, 1));
385 /*
386  *  ========================================
387  *  Texas Instruments Micro Controller Style
388  *  ========================================
389  *  Local Variables:
390  *  mode: c
391  *  c-file-style: "bsd"
392  *  tab-width: 4
393  *  c-basic-offset: 4
394  *  indent-tabs-mode: nil
395  *  End:
396  *  vim:set  filetype=c tabstop=4 shiftwidth=4 expandtab=true
397  */