Actual source code: bread.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      2:  #include <petscsys.h>
      3:  #include <../src/sys/classes/viewer/impls/socket/socket.h>

      6: /*
      7:    TAKEN from src/sys/fileio/sysio.c The swap byte routines are
      8:   included here because the MATLAB programs that use this do NOT
      9:   link to the PETSc libraries.
     10: */
     11: #include <errno.h>
     12: #if defined(PETSC_HAVE_UNISTD_H)
     13: #include <unistd.h>
     14: #endif

     16: #if !defined(PETSC_WORDS_BIGENDIAN)
     17: /*
     18:   SYByteSwapInt - Swap bytes in an integer
     19: */
     20: void SYByteSwapInt(int *buff,int n)
     21: {
     22:   int  i,j,tmp;
     23:   char *ptr1,*ptr2 = (char*)&tmp;
     24:   for (j=0; j<n; j++) {
     25:     ptr1 = (char*)(buff + j);
     26:     for (i=0; i<(int)sizeof(int); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
     27:     buff[j] = tmp;
     28:   }
     29: }
     30: /*
     31:   SYByteSwapShort - Swap bytes in a short
     32: */
     33: void SYByteSwapShort(short *buff,int n)
     34: {
     35:   int   i,j;
     36:   short tmp;
     37:   char  *ptr1,*ptr2 = (char*)&tmp;
     38:   for (j=0; j<n; j++) {
     39:     ptr1 = (char*)(buff + j);
     40:     for (i=0; i<(int)sizeof(short); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
     41:     buff[j] = tmp;
     42:   }
     43: }
     44: /*
     45:   SYByteSwapScalar - Swap bytes in a double
     46:   Complex is dealt with as if array of double twice as long.
     47: */
     48: void SYByteSwapScalar(PetscScalar *buff,int n)
     49: {
     50:   int    i,j;
     51:   double tmp,*buff1 = (double*)buff;
     52:   char   *ptr1,*ptr2 = (char*)&tmp;
     53: #if defined(PETSC_USE_COMPLEX)
     54:   n *= 2;
     55: #endif
     56:   for (j=0; j<n; j++) {
     57:     ptr1 = (char*)(buff1 + j);
     58:     for (i=0; i<(int)sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i];
     59:     buff1[j] = tmp;
     60:   }
     61: }
     62: #endif

     64: #define PETSC_MEX_ERROR(a) {fprintf(stdout,"sread: %s \n",a); return PETSC_ERR_SYS;}

     66: /*
     67:     PetscBinaryRead - Reads from a socket, called from MATLAB

     69:   Input Parameters:
     70: .   fd - the file
     71: .   n  - the number of items to read
     72: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

     74:   Output Parameters:
     75: .   p - the buffer

     77:   Notes:
     78:     does byte swapping to work on all machines.
     79: */
     80: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
     81: {

     83:   int  maxblock,wsize,err;
     84:   char *pp = (char*)p;
     85: #if !defined(PETSC_WORDS_BIGENDIAN)
     86:   int  ntmp  = n;
     87:   void *ptmp = p;
     88: #endif

     90:   maxblock = 65536;
     91:   if (type == PETSC_INT)         n *= sizeof(int);
     92:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
     93:   else if (type == PETSC_SHORT)  n *= sizeof(short);
     94:   else if (type == PETSC_CHAR)   n *= sizeof(char);
     95:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

     98:   while (n) {
     99:     wsize = (n < maxblock) ? n : maxblock;
    100:     err   = read(fd,pp,wsize);
    101: #if !defined(PETSC_MISSING_ERRNO_EINTR)
    102:     if (err < 0 && errno == EINTR) continue;
    103: #endif
    104:     if (!err && wsize > 0) return 1;
    105:     if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
    106:     n  -= err;
    107:     pp += err;
    108:   }

    110: #if !defined(PETSC_WORDS_BIGENDIAN)
    111:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
    112:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
    113:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
    114: #endif
    115:   return 0;
    116: }

    118: /*
    119:     PetscBinaryWrite - Writes to a socket, called from MATLAB

    121:   Input Parameters:
    122: .   fd - the file
    123: .   n  - the number of items to read
    124: .   p - the data
    125: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

    128:   Notes:
    129:     does byte swapping to work on all machines.
    130: */
    131: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscBool dummy)
    132: {

    134:   int  maxblock,wsize,err;
    135:   char *pp = (char*)p;
    136: #if !defined(PETSC_WORDS_BIGENDIAN)
    137:   int  ntmp  = n;
    138:   void *ptmp = p;
    139: #endif

    141:   maxblock = 65536;
    142:   if (type == PETSC_INT)         n *= sizeof(int);
    143:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
    144:   else if (type == PETSC_SHORT)  n *= sizeof(short);
    145:   else if (type == PETSC_CHAR)   n *= sizeof(char);
    146:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

    148: #if !defined(PETSC_WORDS_BIGENDIAN)
    149:   /* make sure data is in correct byte ordering before sending  */
    150:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
    151:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
    152:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
    153: #endif

    155:   while (n) {
    156:     wsize = (n < maxblock) ? n : maxblock;
    157:     err   = write(fd,pp,wsize);
    158: #if !defined(PETSC_MISSING_ERRNO_EINTR)
    159:     if (err < 0 && errno == EINTR) continue;
    160: #endif
    161:     if (!err && wsize > 0) return 1;
    162:     if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
    163:     n  -= err;
    164:     pp += err;
    165:   }
    166: #if !defined(PETSC_WORDS_BIGENDIAN)
    167:   /* swap the data back if we swapped it before sending it */
    168:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
    169:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
    170:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
    171: #endif

    173:   return 0;
    174: }