選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

endianness.c 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. * endian.c:
  20. * stuff to handle endianess mischief.
  21. */
  22. #include "includes.h"
  23. #include "common.h"
  24. #include "log.h"
  25. #include "endianness.h"
  26. #ifdef DEBUG
  27. /* Call fatal if `i' is equal to IINFO_DYNAMIC_VALUE.
  28. * Note: this is needed only for debugging purpose */
  29. #define IS_DYNAMIC(i) \
  30. ({ \
  31. if((i) == IINFO_DYNAMIC_VALUE) \
  32. fatal("%s:%d: IINFO_DYNAMIC_VALUE encountered", ERROR_POS); \
  33. })
  34. #else
  35. #define IS_DYNAMIC(i) ({do_nothing();})
  36. #endif /*DEBUG*/
  37. void *int_info_copy(int_info *dst, const int_info *src)
  38. {
  39. return memcpy(dst, src, sizeof(int_info));
  40. }
  41. void ints_array_ntohl(int *hostlong, int nmemb)
  42. {
  43. #if BYTE_ORDER == LITTLE_ENDIAN
  44. int i;
  45. for(i=0; i<nmemb; i++)
  46. hostlong[i]=ntohl(hostlong[i]);
  47. #endif
  48. }
  49. void ints_array_htonl(int *netlong, int nmemb)
  50. {
  51. #if BYTE_ORDER == LITTLE_ENDIAN
  52. int i;
  53. for(i=0; i<nmemb; i++)
  54. netlong[i]=htonl(netlong[i]);
  55. #endif
  56. }
  57. void ints_array_ntohs(short *hostshort, int nmemb)
  58. {
  59. #if BYTE_ORDER == LITTLE_ENDIAN
  60. int i;
  61. for(i=0; i<nmemb; i++)
  62. hostshort[i]=ntohs(hostshort[i]);
  63. #endif
  64. }
  65. void ints_array_htons(short *netshort, int nmemb)
  66. {
  67. #if BYTE_ORDER == LITTLE_ENDIAN
  68. int i;
  69. for(i=0; i<nmemb; i++)
  70. netshort[i]=htons(netshort[i]);
  71. #endif
  72. }
  73. /*
  74. * ints_network_to_host: converts all the int/short variables present in the
  75. * struct `s' from network order to host order. The `s' struct must be
  76. * described in the `iinfo' struct.
  77. */
  78. void ints_network_to_host(void *s, int_info iinfo)
  79. {
  80. #if BYTE_ORDER == LITTLE_ENDIAN
  81. int i;
  82. char *p;
  83. IS_DYNAMIC(iinfo.total_ints);
  84. for(i=0; i < iinfo.total_ints; i++) {
  85. if(!iinfo.int_type[i])
  86. continue;
  87. IS_DYNAMIC(iinfo.int_offset[i]);
  88. p=(char *)s + iinfo.int_offset[i];
  89. IS_DYNAMIC(iinfo.int_nmemb[i]);
  90. IS_DYNAMIC(iinfo.int_type[i]);
  91. /*
  92. * Swap the entire array if it is a single integer and if we
  93. * are on a little endian machine.
  94. */
  95. if(iinfo.int_type[i] & INT_TYPE_WORDS) {
  96. if(iinfo.int_type[i] & INT_TYPE_32BIT)
  97. swap_ints(iinfo.int_nmemb[i], (u_int *)p,
  98. (u_int *)p);
  99. else
  100. swap_shorts(iinfo.int_nmemb[i], (u_short *)p,
  101. (u_short *)p);
  102. }
  103. if(iinfo.int_type[i] & INT_TYPE_32BIT)
  104. ints_array_ntohl((int *)p, iinfo.int_nmemb[i]);
  105. else
  106. ints_array_ntohs((short *)p, iinfo.int_nmemb[i]);
  107. }
  108. #endif
  109. }
  110. /*
  111. * ints_host_to_network: converts all the int/short variables present in the
  112. * struct `s' from host order to network order. The `s' struct must be
  113. * described in the `iinfo' struct.
  114. */
  115. void ints_host_to_network(void *s, int_info iinfo)
  116. {
  117. #if BYTE_ORDER == LITTLE_ENDIAN
  118. int i;
  119. char *p;
  120. IS_DYNAMIC(iinfo.total_ints);
  121. for(i=0; i < iinfo.total_ints; i++) {
  122. if(!iinfo.int_type[i])
  123. continue;
  124. IS_DYNAMIC(iinfo.int_offset[i]);
  125. p=(char *)s + iinfo.int_offset[i];
  126. IS_DYNAMIC(iinfo.int_nmemb[i]);
  127. IS_DYNAMIC(iinfo.int_type[i]);
  128. /*
  129. * Swap the entire array if it is a single integer and if we
  130. * are on a little endian machine.
  131. */
  132. if(iinfo.int_type[i] & INT_TYPE_WORDS) {
  133. if(iinfo.int_type[i] & INT_TYPE_32BIT)
  134. swap_ints(iinfo.int_nmemb[i], (u_int *)p, (u_int *)p);
  135. else
  136. swap_shorts(iinfo.int_nmemb[i], (u_short *)p, (u_short *)p);
  137. }
  138. if(iinfo.int_type[i] & INT_TYPE_32BIT)
  139. ints_array_htonl((int *)p, iinfo.int_nmemb[i]);
  140. else
  141. ints_array_htons((short *)p, iinfo.int_nmemb[i]);
  142. }
  143. #endif
  144. }
  145. /*
  146. * ints_printf: prints all the int/short vars present in the `s' struct
  147. * described by `iinfo'. It uses `print_func' as the the printing function
  148. */
  149. void ints_printf(void *s, int_info iinfo, void(*print_func(const char *, ...)))
  150. {
  151. int i, e, *i32;
  152. short *i16;
  153. char *p;
  154. IS_DYNAMIC(iinfo.total_ints);
  155. for(i=0; i < iinfo.total_ints; i++) {
  156. if(!iinfo.int_type[i])
  157. continue;
  158. IS_DYNAMIC(iinfo.int_offset[i]);
  159. p=(char *)s + iinfo.int_offset[i];
  160. IS_DYNAMIC(iinfo.int_nmemb[i]);
  161. IS_DYNAMIC(iinfo.int_type[i]);
  162. for(e=0; e < iinfo.int_nmemb[i]; e++) {
  163. print_func("ints_printf: offset %d, nmemb %d, ",
  164. iinfo.int_offset[i], e);
  165. if(iinfo.int_type[i] & INT_TYPE_32BIT) {
  166. i32 = (int *)(p + (sizeof(int) * e));
  167. print_func("32bit value %d\n", *i32);
  168. } else {
  169. i16 = (short *)(p + (sizeof(short) * e));
  170. print_func("16bit value %d\n", *i16);
  171. }
  172. }
  173. }
  174. }