Actual source code: bread.c

petsc-3.3-p7 2013-05-11
  2: #include <stdio.h>
  3: #include <petscsys.h>
  4: #include <../src/sys/viewer/impls/socket/socket.h>


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

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

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

 81: /*
 82:     PetscBinaryRead - Reads from a socket, called from MATLAB

 84:   Input Parameters:
 85: .   fd - the file
 86: .   n  - the number of items to read 
 87: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

 89:   Output Parameters:
 90: .   p - the buffer

 92:   Notes: does byte swapping to work on all machines.
 93: */
 94: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
 95: {

 97:   int  maxblock,wsize,err;
 98:   char *pp = (char*)p;
 99: #if !defined(PETSC_WORDS_BIGENDIAN)
100:   int  ntmp = n;
101:   void *ptmp = p;
102: #endif

104:   maxblock = 65536;
105:   if (type == PETSC_INT)         n *= sizeof(int);
106:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
107:   else if (type == PETSC_SHORT)  n *= sizeof(short);
108:   else if (type == PETSC_CHAR)   n *= sizeof(char);
109:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
110: 

112:   while (n) {
113:     wsize = (n < maxblock) ? n : maxblock;
114:     err = read(fd,pp,wsize);
115: #if !defined(PETSC_MISSING_ERRNO_EINTR)
116:     if (err < 0 && errno == EINTR) continue;
117: #endif
118:     if (!err && wsize > 0) return 1;
119:     if (err < 0) {
120:       PETSC_MEX_ERROR("Error reading from socket\n");
121:     }
122:     n  -= err;
123:     pp += err;
124:   }

126: #if !defined(PETSC_WORDS_BIGENDIAN)
127:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
128:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
129:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
130: #endif
131:   return 0;
132: }

136: /*
137:     PetscBinaryWrite - Writes to a socket, called from MATLAB

139:   Input Parameters:
140: .   fd - the file
141: .   n  - the number of items to read 
142: .   p - the data
143: .   type - the type of items to read (PETSC_INT or PETSC_SCALAR)


146:   Notes: does byte swapping to work on all machines.
147: */
148: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscBool  dummy)
149: {

151:   int  maxblock,wsize,err;
152:   char *pp = (char*)p;
153: #if !defined(PETSC_WORDS_BIGENDIAN)
154:   int  ntmp = n;
155:   void *ptmp = p;
156: #endif

158:   maxblock = 65536;
159:   if (type == PETSC_INT)         n *= sizeof(int);
160:   else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
161:   else if (type == PETSC_SHORT)  n *= sizeof(short);
162:   else if (type == PETSC_CHAR)   n *= sizeof(char);
163:   else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");

165: #if !defined(PETSC_WORDS_BIGENDIAN)
166:   /* make sure data is in correct byte ordering before sending  */
167:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
168:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
169:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
170: #endif

172:   while (n) {
173:     wsize = (n < maxblock) ? n : maxblock;
174:     err = write(fd,pp,wsize);
175: #if !defined(PETSC_MISSING_ERRNO_EINTR)
176:     if (err < 0 && errno == EINTR) continue;
177: #endif
178:     if (!err && wsize > 0) return 1;
179:     if (err < 0) {
180:       PETSC_MEX_ERROR("Error reading from socket\n");
181:     }
182:     n  -= err;
183:     pp += err;
184:   }
185: #if !defined(PETSC_WORDS_BIGENDIAN)
186:   /* swap the data back if we swapped it before sending it */
187:   if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
188:   else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
189:   else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
190: #endif

192:   return 0;
193: }