/**CFile********************************************************************** FileName [dddmpBinary.c] PackageName [dddmp] Synopsis [Input and output BDD codes and integers from/to file] Description [Input and output BDD codes and integers from/to file in binary mode. DD node codes are written as one byte. Integers of any length are written as sequences of "linked" bytes. For each byte 7 bits are used for data and one (MSBit) as link with a further byte (MSB = 1 means one more byte). Low level read/write of bytes filter , and with escape sequences. ] Author [Gianpiero Cabodi and Stefano Quer] Copyright [ Copyright (c) 2004 by Politecnico di Torino. All Rights Reserved. This software is for educational purposes only. Permission is given to academic institutions to use, copy, and modify this software and its documentation provided that this introductory message is not removed, that this software and its documentation is used for the institutions' internal research and educational purposes, and that no monies are exchanged. No guarantee is expressed or implied by the distribution of this code. Send bug-reports and/or questions to: {gianpiero.cabodi,stefano.quer}@polito.it. ] ******************************************************************************/ #include "dddmpInt.h" /*---------------------------------------------------------------------------*/ /* Stucture declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Type declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Variable declarations */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Macro declarations */ /*---------------------------------------------------------------------------*/ /**AutomaticStart*************************************************************/ /*---------------------------------------------------------------------------*/ /* Static function prototypes */ /*---------------------------------------------------------------------------*/ static int WriteByteBinary(FILE *fp, unsigned char c); static int ReadByteBinary(FILE *fp, unsigned char *cp); /**AutomaticEnd***************************************************************/ /*---------------------------------------------------------------------------*/ /* Definition of exported functions */ /*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/ /* Definition of internal functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Writes 1 byte node code] Description [outputs a 1 byte node code using the following format:
     Unused      : 1 bit;
     V           : 2 bits;     (variable code)
     T           : 2 bits;     (Then code)
     Ecompl      : 1 bit;      (Else complemented)
     E           : 2 bits;     (Else code)
    
Ecompl is set with complemented edges. ] SideEffects [None] SeeAlso [DddmpReadCode()] ******************************************************************************/ int DddmpWriteCode ( FILE *fp /* IN: file where to write the code */, struct binary_dd_code code /* IN: the code to be written */ ) { unsigned char c; int retValue; c = (code.Unused<<7)|(code.V<<5)|(code.T<<3)| (code.Ecompl<<2)|(code.E); retValue = WriteByteBinary (fp, c); return (retValue); } /**Function******************************************************************** Synopsis [Reads a 1 byte node code] Description [Reads a 1 byte node code. See DddmpWriteCode() for code description.] SideEffects [None] SeeAlso [DddmpWriteCode()] ******************************************************************************/ int DddmpReadCode ( FILE *fp /* IN: file where to read the code */, struct binary_dd_code *pcode /* OUT: the read code */ ) { unsigned char c; if (ReadByteBinary (fp, &c) == EOF) { return (0); } pcode->Unused = c>>7; pcode->V = (c>>5) & 3; pcode->T = (c>>3) & 3; pcode->Ecompl = (c>>2) & 1; pcode->E = c & 3; return (1); } /**Function******************************************************************** Synopsis [Writes a "packed integer"] Description [Writes an integer as a sequence of bytes (MSByte first). For each byte 7 bits are used for data and one (LSBit) as link with a further byte (LSB = 1 means one more byte). ] SideEffects [None] SeeAlso [DddmpReadInt()] ******************************************************************************/ int DddmpWriteInt ( FILE *fp /* IN: file where to write the integer */, int id /* IN: integer to be written */ ) { char cvet[4]; int i; for (i=0; i<4; i++) { cvet[i] = (char)((id & 0x0000007f) << 1); id >>= 7; } for (i=3; (i>0) && (cvet[i] == 0); i--); for (; i>0; i--) { cvet[i] |= (char)1; if (WriteByteBinary (fp, cvet[i]) == EOF) return (0); } if (WriteByteBinary (fp, cvet[0]) == EOF) { return (0); } return (1); } /**Function******************************************************************** Synopsis [Reads a "packed integer"] Description [Reads an integer coded on a sequence of bytes. See DddmpWriteInt() for format.] SideEffects [None] SeeAlso [DddmpWriteInt()] ******************************************************************************/ int DddmpReadInt ( FILE *fp /* IN: file where to read the integer */, int *pid /* OUT: the read integer */ ) { unsigned char c; int i; unsigned int id; id = 0; for (i=0; i<4; i++) { if (ReadByteBinary (fp, &c) == EOF) return (0); id = (id<<7) | (c>>1); if ((c & 1) == 0) break; } /* Check for correct format: last char should be found before i = 4 */ assert(i<4); *pid = id; return (i+1); } /*---------------------------------------------------------------------------*/ /* Definition of static functions */ /*---------------------------------------------------------------------------*/ /**Function******************************************************************** Synopsis [Writes a byte to file filtering , and ] Description [outputs a byte to file fp. Uses 0x00 as escape character to filter , and . This is done for compatibility between unix and dos/windows systems. ] SideEffects [None] SeeAlso [ReadByteBinary()] ******************************************************************************/ static int WriteByteBinary ( FILE *fp /* IN: file where to write the byte */, unsigned char c /* IN: the byte to be written */ ) { unsigned char BinaryEscape; switch (c) { case 0x00: /* Escape */ BinaryEscape = 0x00; if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) return (0); c = 0x00; break; case 0x0a: /* */ BinaryEscape = 0x00; if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) return (0); c = 0x01; break; case 0x0d: /* */ BinaryEscape = 0x00; if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) return (0); c = 0x02; break; case 0x1a: /* */ BinaryEscape = 0x00; if (fwrite (&BinaryEscape, sizeof(char), 1, fp) != sizeof(char)) return (0); c = 0x03; break; } if (fwrite (&c, sizeof(char), 1, fp) != sizeof(char)) return (0); return (1); } /**Function******************************************************************** Synopsis [Reads a byte from file with escaped , and ] Description [inputs a byte to file fp. 0x00 has been used as escape character to filter , and . This is done for compatibility between unix and dos/windows systems. ] SideEffects [None] SeeAlso [WriteByteBinary()] ******************************************************************************/ static int ReadByteBinary ( FILE *fp /* IN: file where to read the byte */, unsigned char *cp /* OUT: the read byte */ ) { if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { return (0); } if (*cp == 0x00) { /* Escape */ if (fread (cp, sizeof(char), 1, fp) != sizeof(char)) { return (0); } switch (*cp) { case 0x00: /* Escape */ break; case 0x01: /* */ *cp = 0x0a; break; case 0x02: /* */ *cp = 0x0d; break; case 0x03: /* */ *cp = 0x1a; break; } } return (1); }