Actual source code: bread.c

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

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

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

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

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

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

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

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

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

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

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

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

111: /*
112:     PetscBinaryWrite - Writes to a socket, called from MATLAB

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

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

126:   int  maxblock,wsize,err,retv=0;
127:   char *pp = (char*)p;
128:   int  ntmp  = n;
129:   void *ptmp = (void*)p;

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

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

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

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

164:   if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
165:   return retv;
166: }