typeconv.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Type conversion routines, these have been rewritten for portability.
  3. *
  4. * The only requirement is now that the u2_t and u4_t must be big enough.
  5. */
  6. #include "syshead.h"
  7. #include "const.h"
  8. #include "type.h"
  9. #include "globvar.h"
  10. void xxerr P((char *));
  11. void xxerr(x) char * x; { write(2, x, strlen(x)); }
  12. #ifdef __AS386_16__
  13. static int no_swap = 1;
  14. #endif
  15. static int long_off[4] = {0,1,2,3};
  16. static int int_off[2] = {0,1};
  17. PUBLIC bool_pt typeconv_init(big_endian, long_big_endian)
  18. bool_pt big_endian;
  19. bool_pt long_big_endian;
  20. {
  21. int i;
  22. #ifdef __AS386_16__
  23. no_swap = (!big_endian && !long_big_endian);
  24. #endif
  25. for(i=0; i<4; i++) long_off[i] = i;
  26. for(i=0; i<2; i++) int_off[i] = i;
  27. if( long_big_endian )
  28. {
  29. i = long_off[0]; long_off[0] = long_off[2]; long_off[2] = i;
  30. i = long_off[1]; long_off[1] = long_off[3]; long_off[3] = i;
  31. }
  32. if( big_endian )
  33. {
  34. i = long_off[2]; long_off[2] = long_off[3]; long_off[3] = i;
  35. i = long_off[0]; long_off[0] = long_off[1]; long_off[1] = i;
  36. i = int_off[0]; int_off[0] = int_off[1]; int_off[1] = i;
  37. }
  38. return 1;
  39. }
  40. PUBLIC void u2c2(buf, offset)
  41. char *buf;
  42. u2_pt offset;
  43. {
  44. #ifdef __AS386_16__
  45. if( no_swap )
  46. {
  47. *((unsigned short*)buf) = offset; /* UNALIGNED ACCESS! */
  48. return;
  49. }
  50. #endif
  51. buf[int_off[0]] = offset;
  52. buf[int_off[1]] = (offset>>8);
  53. }
  54. PUBLIC void u4c4(buf, offset)
  55. char *buf;
  56. u4_t offset;
  57. {
  58. int i;
  59. #ifdef __AS386_16__
  60. if( no_swap )
  61. {
  62. *((unsigned long*)buf) = offset; /* UNALIGNED ACCESS! */
  63. return;
  64. }
  65. #endif
  66. for(i=0; i<4; i++)
  67. {
  68. buf[long_off[i]] = offset;
  69. offset >>= 8;
  70. }
  71. }
  72. PUBLIC void u4cn(buf, offset, count)
  73. char *buf;
  74. u4_t offset;
  75. unsigned count;
  76. {
  77. switch(count)
  78. {
  79. case 1:
  80. buf[0] = (char) offset;
  81. return;
  82. case 2:
  83. u2c2(buf, (u2_pt) offset);
  84. return;
  85. case 4:
  86. u4c4(buf, (u4_t) offset);
  87. return;
  88. default:
  89. xxerr("WARNING: typeconv.c(u4cn) illegal count\n");
  90. return;
  91. }
  92. }
  93. PUBLIC void u2cn(buf, offset, count)
  94. char *buf;
  95. u2_pt offset;
  96. unsigned count;
  97. {
  98. switch(count)
  99. {
  100. case 1:
  101. buf[0] = (char) offset;
  102. return;
  103. case 2:
  104. u2c2(buf, (u2_pt) offset);
  105. return;
  106. case 4:
  107. u4c4(buf, (u4_t) offset);
  108. return;
  109. default:
  110. xxerr("WARNING: typeconv.c(u2cn) illegal count\n");
  111. return;
  112. }
  113. }
  114. PUBLIC u2_pt c2u2(buf)
  115. char *buf;
  116. {
  117. u2_pt res;
  118. #ifdef __AS386_16__
  119. if( no_swap ) return *((u2_pt *)buf); /* UNALIGNED ACCESS! */
  120. #endif
  121. res = ((unsigned char *)buf) [int_off[0]]
  122. + ((((unsigned char *)buf) [int_off[1]]) << 8);
  123. return res;
  124. }
  125. PUBLIC u4_t c4u4(buf)
  126. char *buf;
  127. {
  128. u4_t res;
  129. int i;
  130. #ifdef __AS386_16__
  131. if( no_swap ) return *((u4_t *)buf); /* UNALIGNED ACCESS! */
  132. #endif
  133. res = 0;
  134. for(i=3; i>=0; i--)
  135. {
  136. res = (res<<8) + ((unsigned char *)buf) [long_off[i]];
  137. }
  138. return res;
  139. }
  140. PUBLIC u4_t cnu4(buf, count)
  141. char *buf;
  142. unsigned count;
  143. {
  144. switch (count)
  145. {
  146. case 0:
  147. return 0;
  148. case 1:
  149. return buf[0] & 0xFF;
  150. case 2:
  151. return c2u2(buf);
  152. case 4:
  153. return c4u4(buf);
  154. default:
  155. xxerr("WARNING: typeconv.c(cnu4) illegal count\n");
  156. return 0;
  157. }
  158. }
  159. PUBLIC u2_pt cnu2(buf, count)
  160. char *buf;
  161. unsigned count;
  162. {
  163. switch (count)
  164. {
  165. case 0:
  166. return 0;
  167. case 1:
  168. return buf[0] & 0xFF;
  169. case 2:
  170. return c2u2(buf);
  171. case 4:
  172. return (u2_pt) c4u4(buf);
  173. default:
  174. xxerr("WARNING: typeconv.c(cnu2) illegal count\n");
  175. return 0;
  176. }
  177. }