Actual source code: bread.c
petsc-3.7.1 2016-05-15
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: */
     22: void SYByteSwapInt(int *buff,int n)
     23: {
     24:   int  i,j,tmp;
     25:   char *ptr1,*ptr2 = (char*)&tmp;
     26:   for (j=0; j<n; j++) {
     27:     ptr1 = (char*)(buff + j);
     28:     for (i=0; i<(int)sizeof(int); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
     29:     buff[j] = tmp;
     30:   }
     31: }
     32: /*
     33:   SYByteSwapShort - Swap bytes in a short
     34: */
     37: void SYByteSwapShort(short *buff,int n)
     38: {
     39:   int   i,j;
     40:   short tmp;
     41:   char  *ptr1,*ptr2 = (char*)&tmp;
     42:   for (j=0; j<n; j++) {
     43:     ptr1 = (char*)(buff + j);
     44:     for (i=0; i<(int)sizeof(short); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
     45:     buff[j] = tmp;
     46:   }
     47: }
     48: /*
     49:   SYByteSwapScalar - Swap bytes in a double
     50:   Complex is dealt with as if array of double twice as long.
     51: */
     54: void SYByteSwapScalar(PetscScalar *buff,int n)
     55: {
     56:   int    i,j;
     57:   double tmp,*buff1 = (double*)buff;
     58:   char   *ptr1,*ptr2 = (char*)&tmp;
     59: #if defined(PETSC_USE_COMPLEX)
     60:   n *= 2;
     61: #endif
     62:   for (j=0; j<n; j++) {
     63:     ptr1 = (char*)(buff1 + j);
     64:     for (i=0; i<(int)sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i];
     65:     buff1[j] = tmp;
     66:   }
     67: }
     68: #endif

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

     74: /*
     75:     PetscBinaryRead - Reads from a socket, called from MATLAB

     77:   Input Parameters:
     78: .   fd - the file
     79: .   n  - the number of items to read
     80: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

     82:   Output Parameters:
     83: .   p - the buffer

     85:   Notes: does byte swapping to work on all machines.
     86: */
     87: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
     88: {

     90:   int  maxblock,wsize,err;
     91:   char *pp = (char*)p;
     92: #if !defined(PETSC_WORDS_BIGENDIAN)
     93:   int  ntmp  = n;
     94:   void *ptmp = p;
     95: #endif

     97:   maxblock = 65536;
     98:   if (type == PETSC_INT)         n *= sizeof(int);
     99:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
    100:   else if (type == PETSC_SHORT)  n *= sizeof(short);
    101:   else if (type == PETSC_CHAR)   n *= sizeof(char);
    102:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

    105:   while (n) {
    106:     wsize = (n < maxblock) ? n : maxblock;
    107:     err   = read(fd,pp,wsize);
    108: #if !defined(PETSC_MISSING_ERRNO_EINTR)
    109:     if (err < 0 && errno == EINTR) continue;
    110: #endif
    111:     if (!err && wsize > 0) return 1;
    112:     if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
    113:     n  -= err;
    114:     pp += err;
    115:   }

    117: #if !defined(PETSC_WORDS_BIGENDIAN)
    118:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
    119:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
    120:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
    121: #endif
    122:   return 0;
    123: }

    127: /*
    128:     PetscBinaryWrite - Writes to a socket, called from MATLAB

    130:   Input Parameters:
    131: .   fd - the file
    132: .   n  - the number of items to read
    133: .   p - the data
    134: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

    137:   Notes: does byte swapping to work on all machines.
    138: */
    139: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscBool dummy)
    140: {

    142:   int  maxblock,wsize,err;
    143:   char *pp = (char*)p;
    144: #if !defined(PETSC_WORDS_BIGENDIAN)
    145:   int  ntmp  = n;
    146:   void *ptmp = p;
    147: #endif

    149:   maxblock = 65536;
    150:   if (type == PETSC_INT)         n *= sizeof(int);
    151:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
    152:   else if (type == PETSC_SHORT)  n *= sizeof(short);
    153:   else if (type == PETSC_CHAR)   n *= sizeof(char);
    154:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

    156: #if !defined(PETSC_WORDS_BIGENDIAN)
    157:   /* make sure data is in correct byte ordering before sending  */
    158:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
    159:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
    160:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
    161: #endif

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

    181:   return 0;
    182: }