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) \
 61:   { \
 62:     fprintf(stdout, "sread: %s \n", a); \
 63:     return PETSC_ERR_SYS; \
 64:   }

 66: /*
 67:     PetscBinaryRead - Reads from a socket, called from MATLAB

 69:   Input Parameters:
 70: +   fd - the file
 71: .   n  - the number of items to read
 72: -   type - the type of items to read (PETSC_INT or PETSC_SCALAR)

 74:   Output Parameter:
 75: .   p - the buffer

 77:   Notes:
 78:     does byte swapping to work on all machines.
 79: */
 80: PetscErrorCode PetscBinaryRead(int fd, void *p, int n, int *dummy, PetscDataType type)
 81: {
 82:   int   maxblock, wsize, err;
 83:   char *pp   = (char *)p;
 84:   int   ntmp = n;
 85:   void *ptmp = p;

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

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

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

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

117:   Input Parameters:
118: +   fd - the file
119: .   n  - the number of items to read
120: .   p - the data
121: -   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: {
128:   int   maxblock, wsize, err = 0, retv = 0;
129:   char *pp   = (char *)p;
130:   int   ntmp = n;
131:   void *ptmp = (void *)p;

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

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

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

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

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