typeconv.c 3.4 KB

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