byte.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #include <cinttypes>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cstring>
  5. #include "macro.h"
  6. #include "byte.h"
  7. using namespace aFuntool;
  8. namespace aFuntool {
  9. enum af_EndianType endian = little_endian;
  10. enum af_EndianType save_as = little_endian; // 默认以小端序存储
  11. }
  12. /**
  13. * 获取机器字节序
  14. */
  15. void aFuntool::getEndian() {
  16. union {
  17. int16_t a;//元素a,占2个字节
  18. int8_t b;//元素b,占1个字节,b在内存中的地址为a最低字节的地址
  19. } test = {.a = 0x1234};
  20. if (test.b == 0x34)
  21. endian = little_endian;
  22. else if (test.b == 0x12)
  23. endian = big_endian;
  24. else
  25. abort();
  26. }
  27. /**
  28. * 写入一个整数
  29. * @tparam T 整数类型
  30. * @param file FILE 结构体
  31. * @param num 整数
  32. * @return
  33. */
  34. template <typename T>
  35. bool aFuntool::byteWriteInt(FILE *file, T num) {
  36. if (endian != save_as) {
  37. const size_t len = sizeof(T) / sizeof(uint8_t); // NOLINT 允许 size(T) / size(T)
  38. union {
  39. T a;//元素a,占2个字节
  40. uint8_t b[len];//元素b,占1个字节,b在内存中的地址为a最低字节的地址
  41. } in {.a = num}, out {};
  42. for (int i = 0; i < len; i++)
  43. out.b[len - i] = in.b[i]; // 大小端序转换
  44. num = out.a;
  45. }
  46. return fwrite(&num, sizeof(T), 1, file) == 1;
  47. }
  48. /**
  49. * 读取一个整数
  50. * @tparam T 整数类型
  51. * @param file FILE 结构体
  52. * @param num 整数
  53. * @return
  54. */
  55. template <typename T>
  56. bool aFuntool::byteReadInt(FILE *file, T *num) {
  57. size_t re = fread(num, sizeof(T), 1, file);
  58. if (endian != save_as) {
  59. const size_t len = sizeof(T) / sizeof(uint8_t); // NOLINT 允许 size(T) / size(T)
  60. union {
  61. T a;//元素a,占2个字节
  62. uint8_t b[len];//元素b,占1个字节,b在内存中的地址为a最低字节的地址
  63. } in {.a = *num}, out {};
  64. for (int i = 0; i < len; i++)
  65. out.b[len - i] = in.b[i]; // 大小端序转换
  66. *num = out.a;
  67. }
  68. return re == 1;
  69. }
  70. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, int8_t num);
  71. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, int16_t num);
  72. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, int32_t num);
  73. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, int64_t num);
  74. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, uint8_t num);
  75. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, uint16_t num);
  76. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, uint32_t num);
  77. template AFUN_TOOL_EXPORT bool aFuntool::byteWriteInt(FILE *file, uint64_t num);
  78. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt<int8_t>(FILE *file, int8_t *num);
  79. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, int16_t *num);
  80. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, int32_t *num);
  81. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, int64_t *num);
  82. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, uint8_t *num);
  83. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, uint16_t *num);
  84. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, uint32_t *num);
  85. template AFUN_TOOL_EXPORT bool aFuntool::byteReadInt(FILE *file, uint64_t *num);
  86. /**
  87. * 写入一个C风格字符串
  88. */
  89. bool aFuntool::byteWriteStr(FILE *file, const char *str) {
  90. if (!byteWriteInt<uint16_t>(file, (uint16_t)strlen(str)))
  91. return false;
  92. return fwrite(str, sizeof(char), strlen(str), file) == strlen(str);
  93. }
  94. /**
  95. * 写入一个C++风格字符串
  96. */
  97. bool aFuntool::byteWriteStr(FILE *file, const std::string &str) {
  98. size_t size = str.size();
  99. if (!byteWriteInt<uint16_t>(file, (uint16_t)size))
  100. return false;
  101. return fwrite(str.c_str(), sizeof(char), size, file) == size;
  102. }
  103. /**
  104. * 读取一个C风格字符串
  105. */
  106. bool aFuntool::byteReadStr(FILE *file, char *&str) {
  107. uint16_t len;
  108. if (!byteReadInt<uint16_t>(file, &len))
  109. return false;
  110. if (len == 0) {
  111. str = nullptr;
  112. return true;
  113. }
  114. str = calloc(len + 1, char);
  115. return fread(str, sizeof(char), len, file) == len;
  116. }
  117. /**
  118. * 读取一个C++风格字符串
  119. */
  120. bool aFuntool::byteReadStr(FILE *file, std::string &str) {
  121. uint16_t len;
  122. if (!byteReadInt<uint16_t>(file, &len))
  123. return false;
  124. if (len == 0) {
  125. str = "";
  126. return true;
  127. }
  128. char *tmp = calloc(len + 1, char);
  129. size_t ret = fread(tmp, sizeof(char), len, file);
  130. str = tmp;
  131. free(tmp);
  132. return ret == len;
  133. }