cf_unwrapper.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "../common/cf_unwrapper.h"
  2. #include <assert.h>
  3. #define UINT32_MAX_VAL 0XFFFFFFFF
  4. #define UINT16_MAX_VAL 0XFFFF
  5. #define IS_NEWER(type, bp, val, prev_val) do{ \
  6. if (val - prev_val == (bp)) \
  7. return (val > prev_val ? 0 : -1); \
  8. if (val != prev_val && ((type)(val - prev_val)) < (bp)) \
  9. return 0; \
  10. return -1; \
  11. }while (0)
  12. void init_unwrapper16(cf_unwrapper_t* wrap)
  13. {
  14. wrap->size = sizeof(uint16_t);
  15. wrap->last_value = 0;
  16. }
  17. static int wrap16_is_newer(uint16_t val, uint16_t prev_val)
  18. {
  19. IS_NEWER(uint16_t, (UINT16_MAX_VAL >> 1) + 1, val, prev_val);
  20. }
  21. static int64_t wrap16_update(cf_unwrapper_t* wrap, uint16_t val)
  22. {
  23. int64_t max_plus = (int64_t)UINT16_MAX_VAL + 1;
  24. uint16_t cropped_last = (uint16_t)(wrap->last_value);
  25. int64_t delta = val - cropped_last;
  26. if (wrap16_is_newer(val, cropped_last) == 0){
  27. if (delta < 0)
  28. delta += max_plus;
  29. }
  30. else if (delta > 0 && wrap->last_value + delta - max_plus >= 0){
  31. delta -= max_plus;
  32. }
  33. return wrap->last_value + delta;
  34. }
  35. int64_t wrap_uint16(cf_unwrapper_t* wrap, uint16_t val)
  36. {
  37. assert(wrap->size == sizeof(uint16_t));
  38. wrap->last_value = wrap16_update(wrap, val);
  39. return wrap->last_value;
  40. }
  41. void init_unwrapper32(cf_unwrapper_t* wrap)
  42. {
  43. wrap->size = sizeof(uint32_t);
  44. wrap->last_value = 0;
  45. }
  46. static int wrap32_is_newer(uint32_t val, uint32_t prev_val)
  47. {
  48. IS_NEWER(uint32_t, (UINT32_MAX_VAL >> 1) + 1, val, prev_val);
  49. }
  50. static int64_t wrap32_update(cf_unwrapper_t* wrap, uint32_t val)
  51. {
  52. int64_t max_plus = (int64_t)UINT32_MAX_VAL + 1;
  53. uint32_t cropped_last = (uint32_t)(wrap->last_value);
  54. int64_t delta = val - cropped_last;
  55. if (wrap32_is_newer(val, cropped_last) == 0){
  56. if (delta < 0)
  57. delta += max_plus;
  58. }
  59. else if (delta > 0 && wrap->last_value + delta - max_plus >= 0){
  60. delta -= max_plus;
  61. }
  62. return wrap->last_value + delta;
  63. }
  64. int64_t wrap_uint32(cf_unwrapper_t* wrap, uint32_t val)
  65. {
  66. assert(wrap->size == sizeof(uint32_t));
  67. wrap->last_value = wrap32_update(wrap, val);
  68. return wrap->last_value;
  69. }