Actual source code: bread.c

petsc-3.14.2 2020-12-03
Report Typos and Errors
  1: #include <petscsys.h>
  2: #include <../src/sys/classes/viewer/impls/socket/socket.h>


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

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

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

 63: /*
 64:     PetscBinaryRead - Reads from a socket, called from MATLAB

 66:   Input Parameters:
 67: .   fd - the file
 68: .   n  - the number of items to read
 69: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

 71:   Output Parameters:
 72: .   p - the buffer

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

 80:   int  maxblock,wsize,err;
 81:   char *pp = (char*)p;
 82:   int  ntmp  = n;
 83:   void *ptmp = p;

 85:   maxblock = 65536;
 86:   if (type == PETSC_INT)         n *= sizeof(int);
 87:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
 88:   else if (type == PETSC_SHORT)  n *= sizeof(short);
 89:   else if (type == PETSC_CHAR)   n *= sizeof(char);
 90:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");


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

105:   if (!PetscBinaryBigEndian()) {
106:     if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
107:     else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
108:     else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
109:   }
110:   return 0;
111: }

113: /*
114:     PetscBinaryWrite - Writes to a socket, called from MATLAB

116:   Input Parameters:
117: .   fd - the file
118: .   n  - the number of items to read
119: .   p - the data
120: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)


123:   Notes:
124:     does byte swapping to work on all machines.
125: */
126: PetscErrorCode PetscBinaryWrite(int fd,const void *p,int n,PetscDataType type)
127: {

129:   int  maxblock,wsize,err,retv=0;
130:   char *pp = (char*)p;
131:   int  ntmp  = n;
132:   void *ptmp = (void*)p;

134:   maxblock = 65536;
135:   if (type == PETSC_INT)         n *= sizeof(int);
136:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
137:   else if (type == PETSC_SHORT)  n *= sizeof(short);
138:   else if (type == PETSC_CHAR)   n *= sizeof(char);
139:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

141:   if (!PetscBinaryBigEndian()) {
142:     /* make sure data is in correct byte ordering before sending  */
143:     if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
144:     else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
145:     else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
146:   }

148:   while (n) {
149:     wsize = (n < maxblock) ? n : maxblock;
150:     err   = write(fd,pp,wsize);
151: #if !defined(PETSC_MISSING_ERRNO_EINTR)
152:     if (err < 0 && errno == EINTR) continue;
153: #endif
154:     if (!err && wsize > 0) { retv = 1; break; };
155:     if (err < 0) break;
156:     n  -= err;
157:     pp += err;
158:   }

160:   if (!PetscBinaryBigEndian()) {
161:     /* swap the data back if we swapped it before sending it */
162:     if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
163:     else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
164:     else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
165:   }

167:   if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
168:   return retv;
169: }