osi_byte_buf.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef _OSI_BYTE_BUF_H_
  13. #define _OSI_BYTE_BUF_H_
  14. #include <stdint.h>
  15. #include <stdbool.h>
  16. #include <stddef.h>
  17. #include <string.h>
  18. #include "drv_config.h"
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. /**
  23. * \brief byte buffer with external assigned memory
  24. */
  25. typedef struct
  26. {
  27. uint8_t *buff; ///< memory
  28. unsigned size; ///< memory byte count
  29. unsigned len; ///< valid data length
  30. } osiByteBuf_t;
  31. /**
  32. * \brief decrease buffer data length, return the byte at tail
  33. *
  34. * At buffer empty, data length is unchanged and return 0
  35. *
  36. * \param p byte buffer
  37. * \return byte at tail, or 0 at buffer empty
  38. */
  39. static inline uint8_t osiByteBufPop(osiByteBuf_t *p)
  40. {
  41. if (p->len > 0)
  42. {
  43. p->len--;
  44. return p->buff[p->len];
  45. }
  46. return 0;
  47. }
  48. /**
  49. * \brief incease buffer data length, set the byte at tail
  50. *
  51. * At buffer full, nothing will be done
  52. *
  53. * \param p byte buffer
  54. * \param c byte to be put to the end of buffer
  55. */
  56. static inline void osiByteBufPush(osiByteBuf_t *p, uint8_t c)
  57. {
  58. if (p->len < p->size)
  59. p->buff[p->len++] = c;
  60. }
  61. /**
  62. * \brief get last byte of the buffer
  63. *
  64. * \param p byte buffer
  65. * \return byte at the end, or 0 at buffer empty
  66. */
  67. static inline uint8_t osiByteBufTail(osiByteBuf_t *p, uint16_t ch)
  68. {
  69. return p->len > 0 ? p->buff[p->len - 1] : 0;
  70. }
  71. /**
  72. * \brief clear data in buffer
  73. *
  74. * \param p byte buffer
  75. */
  76. static inline void osiByteBufClear(osiByteBuf_t *p)
  77. {
  78. p->len = 0;
  79. }
  80. /**
  81. * \brief whether the buffer is full
  82. *
  83. * \param p byte buffer
  84. * \return true if the buffer is full
  85. */
  86. static inline bool osiByteBufIsFull(osiByteBuf_t *p)
  87. {
  88. return p->len >= p->size;
  89. }
  90. /**
  91. * \brief whether the buffer is empty
  92. *
  93. * \param p byte buffer
  94. * \return true if the buffer is empty
  95. */
  96. static inline bool osiByteBufIsEmpty(osiByteBuf_t *p)
  97. {
  98. return (p->len == 0);
  99. }
  100. /**
  101. * \brief set a bit in bitmap
  102. *
  103. * Bitmap will use 32bits word, and each word holds 32 bits.
  104. * Caller should ensure parameters are valid.
  105. *
  106. * \param bitmap word array for bitmap
  107. * \param n the bit to be set
  108. */
  109. static inline void osiBitmapSet(uint32_t *bitmap, int n)
  110. {
  111. bitmap[n / 32] |= (1 << (n % 32));
  112. }
  113. /**
  114. * \brief clear a bit in bitmap
  115. *
  116. * Bitmap will use 32bits word, and each word holds 32 bits.
  117. * Caller should ensure parameters are valid.
  118. *
  119. * \param bitmap word array for bitmap
  120. * \param n the bit to be cleared
  121. */
  122. static inline void osiBitmapClear(uint32_t *bitmap, int n)
  123. {
  124. bitmap[n / 32] |= (1 << (n % 32));
  125. }
  126. /**
  127. * \brief check whether a bit in bitmap is set
  128. *
  129. * Bitmap will use 32bits word, and each word holds 32 bits.
  130. * Caller should ensure parameters are valid.
  131. *
  132. * \param bitmap word array for bitmap
  133. * \param n the bit to be checked
  134. */
  135. static inline bool osiBitmapIsSet(uint32_t *bitmap, int n)
  136. {
  137. return bitmap[n / 32] & (1 << (n % 32));
  138. }
  139. /**
  140. * \brief get a byte (8bits) from a pointer
  141. *
  142. * Caller should ensure parameters are valid.
  143. *
  144. * \param ptr the pointer
  145. * \return the byte value
  146. */
  147. static inline uint8_t osiBytesGet8(const void *ptr)
  148. {
  149. const uint8_t *p = (const uint8_t *)ptr;
  150. return p[0];
  151. }
  152. /**
  153. * \brief put a byte (8bits) to a pointer
  154. *
  155. * Caller should ensure parameters are valid.
  156. *
  157. * \param ptr the pointer
  158. * \param v the byte value
  159. */
  160. static inline void osiBytesPut8(void *ptr, uint8_t v)
  161. {
  162. uint8_t *p = (uint8_t *)ptr;
  163. p[0] = v;
  164. }
  165. /**
  166. * \brief get a big endian short (16bits) from a pointer
  167. *
  168. * Caller should ensure parameters are valid.
  169. *
  170. * \param ptr the pointer, may be unaligned
  171. * \return the short value
  172. */
  173. static inline uint16_t osiBytesGetBe16(const void *ptr)
  174. {
  175. const uint8_t *p = (const uint8_t *)ptr;
  176. return (p[0] << 8) | p[1];
  177. }
  178. /**
  179. * \brief put a big endian short (16bits) to a pointer
  180. *
  181. * Caller should ensure parameters are valid.
  182. *
  183. * \param ptr the pointer, may be unaligned
  184. * \param v the short value
  185. */
  186. static inline void osiBytesPutBe16(void *ptr, uint16_t v)
  187. {
  188. uint8_t *p = (uint8_t *)ptr;
  189. p[0] = (v >> 8) & 0xff;
  190. p[1] = v & 0xff;
  191. }
  192. /**
  193. * \brief get a big endian word (32bits) from a pointer
  194. *
  195. * Caller should ensure parameters are valid.
  196. *
  197. * \param ptr the pointer, may be unaligned
  198. * \return the word value
  199. */
  200. static inline uint32_t osiBytesGetBe32(const void *ptr)
  201. {
  202. const uint8_t *p = (const uint8_t *)ptr;
  203. return (p[0] << 24) | (p[1] << 24) | (p[2] << 8) | p[3];
  204. }
  205. /**
  206. * \brief put a big endian word (32bits) to a pointer
  207. *
  208. * Caller should ensure parameters are valid.
  209. *
  210. * \param ptr the pointer, may be unaligned
  211. * \param v the word value
  212. */
  213. static inline void osiBytesPutBe32(void *ptr, uint16_t v)
  214. {
  215. uint8_t *p = (uint8_t *)ptr;
  216. p[0] = (v >> 24) & 0xff;
  217. p[1] = (v >> 16) & 0xff;
  218. p[2] = (v >> 8) & 0xff;
  219. p[3] = v & 0xff;
  220. }
  221. /**
  222. * \brief get a little endian short (16bits) from a pointer
  223. *
  224. * Caller should ensure parameters are valid.
  225. *
  226. * \param ptr the pointer, may be unaligned
  227. * \return the short value
  228. */
  229. static inline uint16_t osiBytesGetLe16(const void *ptr)
  230. {
  231. const uint8_t *p = (const uint8_t *)ptr;
  232. return p[0] | (p[1] << 8);
  233. }
  234. /**
  235. * \brief put a little endian short (16bits) to a pointer
  236. *
  237. * Caller should ensure parameters are valid.
  238. *
  239. * \param ptr the pointer, may be unaligned
  240. * \param v the short value
  241. */
  242. static inline void osiBytesPutLe16(void *ptr, uint16_t v)
  243. {
  244. uint8_t *p = (uint8_t *)ptr;
  245. p[0] = v & 0xff;
  246. p[1] = (v >> 8) & 0xff;
  247. }
  248. /**
  249. * \brief get a little endian word (32bits) from a pointer
  250. *
  251. * Caller should ensure parameters are valid.
  252. *
  253. * \param ptr the pointer, may be unaligned
  254. * \return the word value
  255. */
  256. static inline uint32_t osiBytesGetLe32(const void *ptr)
  257. {
  258. const uint8_t *p = (const uint8_t *)ptr;
  259. return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  260. }
  261. /**
  262. * \brief put a little endian word (32bits) to a pointer
  263. *
  264. * Caller should ensure parameters are valid.
  265. *
  266. * \param ptr the pointer, may be unaligned
  267. * \param v the word value
  268. */
  269. static inline void osiBytesPutLe32(void *ptr, uint32_t v)
  270. {
  271. uint8_t *p = (uint8_t *)ptr;
  272. p[0] = v & 0xff;
  273. p[1] = (v >> 8) & 0xff;
  274. p[2] = (v >> 16) & 0xff;
  275. p[3] = (v >> 24) & 0xff;
  276. }
  277. /**
  278. * \brief get a little endian long long (64bits) from a pointer
  279. *
  280. * Caller should ensure parameters are valid.
  281. *
  282. * \param ptr the pointer, may be unaligned
  283. * \return the long long value
  284. */
  285. static inline uint64_t osiBytesGetLe64(const void *ptr)
  286. {
  287. const uint8_t *p = (const uint8_t *)ptr;
  288. return osiBytesGetLe32(p) | ((uint64_t)osiBytesGetLe32(p + 4) << 32);
  289. }
  290. /**
  291. * \brief put a little endian long long (64bits) to a pointer
  292. *
  293. * Caller should ensure parameters are valid.
  294. *
  295. * \param ptr the pointer, may be unaligned
  296. * \param v the long long value
  297. */
  298. static inline void osiBytesPutLe64(void *ptr, uint64_t v)
  299. {
  300. uint8_t *p = (uint8_t *)ptr;
  301. osiBytesPutLe32(p, v & 0xffffffff);
  302. osiBytesPutLe32(p + 4, (v >> 32) & 0xffffffff);
  303. }
  304. /**
  305. * \brief get a block memory from a pointer
  306. *
  307. * Caller should ensure parameters are valid. It is just \p memcpy,
  308. * and just for similar style.
  309. *
  310. * \param ptr the pointer, may be unaligned
  311. * \param data memory for get
  312. * \param size get size
  313. */
  314. static inline void osiBytesGetMem(const void *ptr, void *data, unsigned size)
  315. {
  316. memcpy(data, ptr, size);
  317. }
  318. /**
  319. * \brief put a block memory to a pointer
  320. *
  321. * Caller should ensure parameters are valid. It is just \p memcpy,
  322. * and just for similar style.
  323. *
  324. * \param ptr the pointer, may be unaligned
  325. * \param data memory for put
  326. * \param size put size
  327. */
  328. static inline void osiBytesPutMem(void *ptr, const void *data, unsigned size)
  329. {
  330. memcpy(ptr, data, size);
  331. }
  332. /**
  333. * \brief read byte from stream, and increase pointer afterward
  334. *
  335. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  336. * \return byte value
  337. */
  338. #define OSI_STRM_R8(p) ({ const void *_orig = (const void*)(p); (p) += 1; osiBytesGet8(_orig); })
  339. /**
  340. * \brief read big endian short from stream, and increase pointer afterward
  341. *
  342. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  343. * \return short value
  344. */
  345. #define OSI_STRM_RBE16(p) ({ const void *_orig = (const void*)(p); (p) += 2; osiBytesGetBe16(_orig); })
  346. /**
  347. * \brief read big endian word from stream, and increase pointer afterward
  348. *
  349. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  350. * \return word value
  351. */
  352. #define OSI_STRM_RBE32(p) ({ const void *_orig = (const void*)(p); (p) += 4; osiBytesGetBe32(_orig); })
  353. /**
  354. * \brief read little endian short from stream, and increase pointer afterward
  355. *
  356. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  357. * \return short value
  358. */
  359. #define OSI_STRM_RLE16(p) ({ const void *_orig = (const void*)(p); (p) += 2; osiBytesGetLe16(_orig); })
  360. /**
  361. * \brief read little endian word from stream, and increase pointer afterward
  362. *
  363. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  364. * \return word value
  365. */
  366. #define OSI_STRM_RLE32(p) ({ const void *_orig = (const void*)(p); (p) += 4; osiBytesGetLe32(_orig); })
  367. /**
  368. * \brief read little endian long long from stream, and increase pointer afterward
  369. *
  370. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  371. * \return long long value
  372. */
  373. #define OSI_STRM_RLE64(p) ({ const void *_orig = (const void*)(p); (p) += 8; osiBytesGetLe64(_orig); })
  374. /**
  375. * \brief write byte to stream, and increase pointer afterward
  376. *
  377. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  378. * \param v byte value
  379. */
  380. #define OSI_STRM_W8(p, v) ({ void *_orig = (void*)(p); (p) += 1; osiBytesPut8(_orig, v); })
  381. /**
  382. * \brief write big endian short to stream, and increase pointer afterward
  383. *
  384. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  385. * \param v short value
  386. */
  387. #define OSI_STRM_WBE16(p, v) ({ void *_orig = (void*)(p); (p) += 2; osiBytesPutBe16(_orig, v); })
  388. /**
  389. * \brief write big endian word to stream, and increase pointer afterward
  390. *
  391. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  392. * \param v word value
  393. */
  394. #define OSI_STRM_WBE32(p, v) ({ void *_orig = (void*)(p); (p) += 4; osiBytesPutBe32(_orig, v); })
  395. /**
  396. * \brief write little endian short to stream, and increase pointer afterward
  397. *
  398. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  399. * \param v short value
  400. */
  401. #define OSI_STRM_WLE16(p, v) ({ void *_orig = (void*)(p); (p) += 2; osiBytesPutLe16(_orig, v); })
  402. /**
  403. * \brief write little endian word to stream, and increase pointer afterward
  404. *
  405. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  406. * \param v word value
  407. */
  408. #define OSI_STRM_WLE32(p, v) ({ void *_orig = (void*)(p); (p) += 4; osiBytesPutLe32(_orig, v); })
  409. /**
  410. * \brief write little endian long long to stream, and increase pointer afterward
  411. *
  412. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  413. * \param v long long value
  414. */
  415. #define OSI_STRM_WLE64(p, v) ({ void *_orig = (void*)(p); (p) += 8; osiBytesPutLe64(_orig, v); })
  416. /**
  417. * \brief write memory to stream, and increase pointer afterward
  418. *
  419. * \param p pointer, which can be <tt>char*, uintptr_t</tt>
  420. * \param v memory pointer
  421. * \param s memory size
  422. */
  423. #define OSI_STRM_WMEM(p, v, s) ({ unsigned _s = (s); memcpy((void*)p, (v), _s); (p) += _s; })
  424. #ifdef __cplusplus
  425. }
  426. #endif
  427. #endif