You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

343 lines
9.4 KiB

2 months ago
  1. /**CFile**********************************************************************
  2. FileName [dddmpBinary.c]
  3. PackageName [dddmp]
  4. Synopsis [Input and output BDD codes and integers from/to file]
  5. Description [Input and output BDD codes and integers from/to file
  6. in binary mode.
  7. DD node codes are written as one byte.
  8. Integers of any length are written as sequences of "linked" bytes.
  9. For each byte 7 bits are used for data and one (MSBit) as link with
  10. a further byte (MSB = 1 means one more byte).
  11. Low level read/write of bytes filter <CR>, <LF> and <ctrl-Z>
  12. with escape sequences.
  13. ]
  14. Author [Gianpiero Cabodi and Stefano Quer]
  15. Copyright [
  16. Copyright (c) 2004 by Politecnico di Torino.
  17. All Rights Reserved. This software is for educational purposes only.
  18. Permission is given to academic institutions to use, copy, and modify
  19. this software and its documentation provided that this introductory
  20. message is not removed, that this software and its documentation is
  21. used for the institutions' internal research and educational purposes,
  22. and that no monies are exchanged. No guarantee is expressed or implied
  23. by the distribution of this code.
  24. Send bug-reports and/or questions to:
  25. {gianpiero.cabodi,stefano.quer}@polito.it.
  26. ]
  27. ******************************************************************************/
  28. #include "dddmpInt.h"
  29. /*---------------------------------------------------------------------------*/
  30. /* Stucture declarations */
  31. /*---------------------------------------------------------------------------*/
  32. /*---------------------------------------------------------------------------*/
  33. /* Type declarations */
  34. /*---------------------------------------------------------------------------*/
  35. /*---------------------------------------------------------------------------*/
  36. /* Variable declarations */
  37. /*---------------------------------------------------------------------------*/
  38. /*---------------------------------------------------------------------------*/
  39. /* Macro declarations */
  40. /*---------------------------------------------------------------------------*/
  41. /**AutomaticStart*************************************************************/
  42. /*---------------------------------------------------------------------------*/
  43. /* Static function prototypes */
  44. /*---------------------------------------------------------------------------*/
  45. static int WriteByteBinary(FILE *fp, unsigned char c);
  46. static int ReadByteBinary(FILE *fp, unsigned char *cp);
  47. /**AutomaticEnd***************************************************************/
  48. /*---------------------------------------------------------------------------*/
  49. /* Definition of exported functions */
  50. /*---------------------------------------------------------------------------*/
  51. /*---------------------------------------------------------------------------*/
  52. /* Definition of internal functions */
  53. /*---------------------------------------------------------------------------*/
  54. /**Function********************************************************************
  55. Synopsis [Writes 1 byte node code]
  56. Description [outputs a 1 byte node code using the following format:
  57. <pre>
  58. Unused : 1 bit;
  59. V : 2 bits; (variable code)
  60. T : 2 bits; (Then code)
  61. Ecompl : 1 bit; (Else complemented)
  62. E : 2 bits; (Else code)
  63. </pre>
  64. Ecompl is set with complemented edges.
  65. ]
  66. SideEffects [None]
  67. SeeAlso [DddmpReadCode()]
  68. ******************************************************************************/
  69. int
  70. DddmpWriteCode (
  71. FILE *fp /* IN: file where to write the code */,
  72. struct binary_dd_code code /* IN: the code to be written */
  73. )
  74. {
  75. unsigned char c;
  76. int retValue;
  77. c = (code.Unused<<7)|(code.V<<5)|(code.T<<3)|
  78. (code.Ecompl<<2)|(code.E);
  79. retValue = WriteByteBinary (fp, c);
  80. return (retValue);
  81. }
  82. /**Function********************************************************************
  83. Synopsis [Reads a 1 byte node code]
  84. Description [Reads a 1 byte node code. See DddmpWriteCode()
  85. for code description.]
  86. SideEffects [None]
  87. SeeAlso [DddmpWriteCode()]
  88. ******************************************************************************/
  89. int
  90. DddmpReadCode (
  91. FILE *fp /* IN: file where to read the code */,
  92. struct binary_dd_code *pcode /* OUT: the read code */
  93. )
  94. {
  95. unsigned char c;
  96. if (ReadByteBinary (fp, &c) == EOF) {
  97. return (0);
  98. }
  99. pcode->Unused = c>>7;
  100. pcode->V = (c>>5) & 3;
  101. pcode->T = (c>>3) & 3;
  102. pcode->Ecompl = (c>>2) & 1;
  103. pcode->E = c & 3;
  104. return (1);
  105. }
  106. /**Function********************************************************************
  107. Synopsis [Writes a "packed integer"]
  108. Description [Writes an integer as a sequence of bytes (MSByte first).
  109. For each byte 7 bits are used for data and one (LSBit) as link
  110. with a further byte (LSB = 1 means one more byte).
  111. ]
  112. SideEffects [None]
  113. SeeAlso [DddmpReadInt()]
  114. ******************************************************************************/
  115. int
  116. DddmpWriteInt (
  117. FILE *fp /* IN: file where to write the integer */,
  118. int id /* IN: integer to be written */
  119. )
  120. {
  121. char cvet[4];
  122. int i;
  123. for (i=0; i<4; i++) {
  124. cvet[i] = (char)((id & 0x0000007f) << 1);
  125. id >>= 7;
  126. }
  127. for (i=3; (i>0) && (cvet[i] == 0); i--);
  128. for (; i>0; i--) {
  129. cvet[i] |= (char)1;
  130. if (WriteByteBinary (fp, cvet[i]) == EOF)
  131. return (0);
  132. }
  133. if (WriteByteBinary (fp, cvet[0]) == EOF) {
  134. return (0);
  135. }
  136. return (1);
  137. }
  138. /**Function********************************************************************
  139. Synopsis [Reads a "packed integer"]
  140. Description [Reads an integer coded on a sequence of bytes. See
  141. DddmpWriteInt() for format.]
  142. SideEffects [None]
  143. SeeAlso [DddmpWriteInt()]
  144. ******************************************************************************/
  145. int
  146. DddmpReadInt (
  147. FILE *fp /* IN: file where to read the integer */,
  148. int *pid /* OUT: the read integer */
  149. )
  150. {
  151. unsigned char c;
  152. int i;
  153. unsigned int id;
  154. id = 0;
  155. for (i=0; i<4; i++) {
  156. if (ReadByteBinary (fp, &c) == EOF)
  157. return (0);
  158. id = (id<<7) | (c>>1);
  159. if ((c & 1) == 0)
  160. break;
  161. }
  162. /* Check for correct format: last char should
  163. be found before i = 4 */
  164. assert(i<4);
  165. *pid = id;
  166. return (i+1);
  167. }
  168. /*---------------------------------------------------------------------------*/
  169. /* Definition of static functions */
  170. /*---------------------------------------------------------------------------*/
  171. /**Function********************************************************************
  172. Synopsis [Writes a byte to file filtering <CR>, <LF> and <ctrl-Z>]
  173. Description [outputs a byte to file fp. Uses 0x00 as escape character
  174. to filter <CR>, <LF> and <ctrl-Z>.
  175. This is done for compatibility between unix and dos/windows systems.
  176. ]
  177. SideEffects [None]
  178. SeeAlso [ReadByteBinary()]
  179. ******************************************************************************/
  180. static int
  181. WriteByteBinary (
  182. FILE *fp /* IN: file where to write the byte */,
  183. unsigned char c /* IN: the byte to be written */
  184. )
  185. {
  186. unsigned char BinaryEscape;
  187. switch (c) {
  188. case 0x00: /* Escape */
  189. BinaryEscape = 0x00;
  190. if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char))
  191. return (0);
  192. c = 0x00;
  193. break;
  194. case 0x0a: /* <LF> */
  195. BinaryEscape = 0x00;
  196. if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char))
  197. return (0);
  198. c = 0x01;
  199. break;
  200. case 0x0d: /* <CR> */
  201. BinaryEscape = 0x00;
  202. if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char))
  203. return (0);
  204. c = 0x02;
  205. break;
  206. case 0x1a: /* <ctrl-Z> */
  207. BinaryEscape = 0x00;
  208. if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char))
  209. return (0);
  210. c = 0x03;
  211. break;
  212. }
  213. if (fwrite (&c, sizeof(char), 1, fp) != sizeof(char))
  214. return (0);
  215. return (1);
  216. }
  217. /**Function********************************************************************
  218. Synopsis [Reads a byte from file with escaped <CR>, <LF> and <ctrl-Z>]
  219. Description [inputs a byte to file fp. 0x00 has been used as escape character
  220. to filter <CR>, <LF> and <ctrl-Z>. This is done for
  221. compatibility between unix and dos/windows systems.
  222. ]
  223. SideEffects [None]
  224. SeeAlso [WriteByteBinary()]
  225. ******************************************************************************/
  226. static int
  227. ReadByteBinary (
  228. FILE *fp /* IN: file where to read the byte */,
  229. unsigned char *cp /* OUT: the read byte */
  230. )
  231. {
  232. if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) {
  233. return (0);
  234. }
  235. if (*cp == 0x00) { /* Escape */
  236. if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) {
  237. return (0);
  238. }
  239. switch (*cp) {
  240. case 0x00: /* Escape */
  241. break;
  242. case 0x01: /* <LF> */
  243. *cp = 0x0a;
  244. break;
  245. case 0x02: /* <CR> */
  246. *cp = 0x0d;
  247. break;
  248. case 0x03: /* <ctrl-Z> */
  249. *cp = 0x1a;
  250. break;
  251. }
  252. }
  253. return (1);
  254. }