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 PetscDefined(HAVE_UNISTD_H)
 11:   #include <unistd.h>
 12: #endif

 14: /*
 15:   SYByteSwapInt - Swap bytes in an integer
 16: */
 17: static void SYByteSwapInt(int *buff, PetscCount n)
 18: {
 19:   int   tmp;
 20:   char *ptr1, *ptr2 = (char *)&tmp;
 21:   for (PetscCount j = 0; j < n; j++) {
 22:     ptr1 = (char *)(buff + j);
 23:     for (PetscCount i = 0; i < 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: static void SYByteSwapShort(short *buff, PetscCount n)
 31: {
 32:   short tmp;
 33:   char *ptr1, *ptr2 = (char *)&tmp;
 34:   for (PetscCount j = 0; j < n; j++) {
 35:     ptr1 = (char *)(buff + j);
 36:     for (PetscCount i = 0; i < sizeof(short); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i];
 37:     buff[j] = tmp;
 38:   }
 39: }
 40: /*
 41:   SYByteSwapScalar - Swap bytes in a double
 42:   Complex is dealt with as if array of double twice as long.
 43: */
 44: static void SYByteSwapScalar(PetscScalar *buff, PetscCount n)
 45: {
 46:   double tmp, *buff1 = (double *)buff;
 47:   char  *ptr1, *ptr2 = (char *)&tmp;
 48:   if (PetscDefined(USE_COMPLEX)) n *= 2;
 49:   for (PetscCount j = 0; j < n; j++) {
 50:     ptr1 = (char *)(buff1 + j);
 51:     for (PetscCount i = 0; i < sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i];
 52:     buff1[j] = tmp;
 53:   }
 54: }

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

 62: // PetscClangLinter pragma disable: -fdoc.*
 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 Parameter:
 72: . p - the buffer

 74:   Notes:
 75:   does byte swapping to work on all machines.
 76: */
 77: PetscErrorCode PetscBinaryRead(int fd, void *p, PetscCount n, PetscInt *dummy, PetscDataType type)
 78: {
 79:   int        maxblock, err;
 80:   char      *pp   = (char *)p;
 81:   PetscCount ntmp = n, wsize;
 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   = (int)read(fd, pp, (int)wsize);
 94:     if (err < 0 && errno == EINTR) continue;
 95:     if (!err && wsize > 0) return 1;
 96:     if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
 97:     n -= err;
 98:     pp += err;
 99:   }

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

109: /*
110:     PetscBinaryWrite - Writes to a socket, called from MATLAB

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

118:   Notes:
119:     does byte swapping to work on all machines.
120: */
121: PetscErrorCode PetscBinaryWrite(int fd, const void *p, PetscCount n, PetscDataType type)
122: {
123:   int        maxblock, err = 0, retv = 0;
124:   char      *pp   = (char *)p;
125:   PetscCount ntmp = n;
126:   void      *ptmp = (void *)p;
127:   PetscCount wsize;

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

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

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

156:   if (!PetscBinaryBigEndian()) {
157:     /* swap the data back if we swapped it before sending it */
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:   }

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