byte.cpp 4.4 KB

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