1*b75c6efcSBarry Smith #include <petscsys.h> 2*b75c6efcSBarry Smith #include <../src/sys/classes/viewer/impls/socket/socket.h> 3*b75c6efcSBarry Smith 4*b75c6efcSBarry Smith /* 5*b75c6efcSBarry Smith TAKEN from src/sys/fileio/sysio.c The swap byte routines are 6*b75c6efcSBarry Smith included here because the MATLAB programs that use this do NOT 7*b75c6efcSBarry Smith link to the PETSc libraries. 8*b75c6efcSBarry Smith */ 9*b75c6efcSBarry Smith #include <errno.h> 10*b75c6efcSBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 11*b75c6efcSBarry Smith #include <unistd.h> 12*b75c6efcSBarry Smith #endif 13*b75c6efcSBarry Smith 14*b75c6efcSBarry Smith /* 15*b75c6efcSBarry Smith SYByteSwapInt - Swap bytes in an integer 16*b75c6efcSBarry Smith */ 17*b75c6efcSBarry Smith void SYByteSwapInt(int *buff, int n) 18*b75c6efcSBarry Smith { 19*b75c6efcSBarry Smith int i, j, tmp; 20*b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp; 21*b75c6efcSBarry Smith for (j = 0; j < n; j++) { 22*b75c6efcSBarry Smith ptr1 = (char *)(buff + j); 23*b75c6efcSBarry Smith for (i = 0; i < (int)sizeof(int); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i]; 24*b75c6efcSBarry Smith buff[j] = tmp; 25*b75c6efcSBarry Smith } 26*b75c6efcSBarry Smith } 27*b75c6efcSBarry Smith /* 28*b75c6efcSBarry Smith SYByteSwapShort - Swap bytes in a short 29*b75c6efcSBarry Smith */ 30*b75c6efcSBarry Smith void SYByteSwapShort(short *buff, int n) 31*b75c6efcSBarry Smith { 32*b75c6efcSBarry Smith int i, j; 33*b75c6efcSBarry Smith short tmp; 34*b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp; 35*b75c6efcSBarry Smith for (j = 0; j < n; j++) { 36*b75c6efcSBarry Smith ptr1 = (char *)(buff + j); 37*b75c6efcSBarry Smith for (i = 0; i < (int)sizeof(short); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i]; 38*b75c6efcSBarry Smith buff[j] = tmp; 39*b75c6efcSBarry Smith } 40*b75c6efcSBarry Smith } 41*b75c6efcSBarry Smith /* 42*b75c6efcSBarry Smith SYByteSwapScalar - Swap bytes in a double 43*b75c6efcSBarry Smith Complex is dealt with as if array of double twice as long. 44*b75c6efcSBarry Smith */ 45*b75c6efcSBarry Smith void SYByteSwapScalar(PetscScalar *buff, int n) 46*b75c6efcSBarry Smith { 47*b75c6efcSBarry Smith int i, j; 48*b75c6efcSBarry Smith double tmp, *buff1 = (double *)buff; 49*b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp; 50*b75c6efcSBarry Smith #if defined(PETSC_USE_COMPLEX) 51*b75c6efcSBarry Smith n *= 2; 52*b75c6efcSBarry Smith #endif 53*b75c6efcSBarry Smith for (j = 0; j < n; j++) { 54*b75c6efcSBarry Smith ptr1 = (char *)(buff1 + j); 55*b75c6efcSBarry Smith for (i = 0; i < (int)sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i]; 56*b75c6efcSBarry Smith buff1[j] = tmp; 57*b75c6efcSBarry Smith } 58*b75c6efcSBarry Smith } 59*b75c6efcSBarry Smith 60*b75c6efcSBarry Smith #define PETSC_MEX_ERROR(a) \ 61*b75c6efcSBarry Smith { \ 62*b75c6efcSBarry Smith fprintf(stdout, "sread: %s \n", a); \ 63*b75c6efcSBarry Smith return PETSC_ERR_SYS; \ 64*b75c6efcSBarry Smith } 65*b75c6efcSBarry Smith 66*b75c6efcSBarry Smith /* 67*b75c6efcSBarry Smith PetscBinaryRead - Reads from a socket, called from MATLAB 68*b75c6efcSBarry Smith 69*b75c6efcSBarry Smith Input Parameters: 70*b75c6efcSBarry Smith . fd - the file 71*b75c6efcSBarry Smith . n - the number of items to read 72*b75c6efcSBarry Smith . type - the type of items to read (PETSC_INT or PETSC_SCALAR) 73*b75c6efcSBarry Smith 74*b75c6efcSBarry Smith Output Parameters: 75*b75c6efcSBarry Smith . p - the buffer 76*b75c6efcSBarry Smith 77*b75c6efcSBarry Smith Notes: 78*b75c6efcSBarry Smith does byte swapping to work on all machines. 79*b75c6efcSBarry Smith */ 80*b75c6efcSBarry Smith PetscErrorCode PetscBinaryRead(int fd, void *p, int n, int *dummy, PetscDataType type) 81*b75c6efcSBarry Smith { 82*b75c6efcSBarry Smith int maxblock, wsize, err; 83*b75c6efcSBarry Smith char *pp = (char *)p; 84*b75c6efcSBarry Smith int ntmp = n; 85*b75c6efcSBarry Smith void *ptmp = p; 86*b75c6efcSBarry Smith 87*b75c6efcSBarry Smith maxblock = 65536; 88*b75c6efcSBarry Smith if (type == PETSC_INT) n *= sizeof(int); 89*b75c6efcSBarry Smith else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); 90*b75c6efcSBarry Smith else if (type == PETSC_SHORT) n *= sizeof(short); 91*b75c6efcSBarry Smith else if (type == PETSC_CHAR) n *= sizeof(char); 92*b75c6efcSBarry Smith else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); 93*b75c6efcSBarry Smith 94*b75c6efcSBarry Smith while (n) { 95*b75c6efcSBarry Smith wsize = (n < maxblock) ? n : maxblock; 96*b75c6efcSBarry Smith err = read(fd, pp, wsize); 97*b75c6efcSBarry Smith #if !defined(PETSC_MISSING_ERRNO_EINTR) 98*b75c6efcSBarry Smith if (err < 0 && errno == EINTR) continue; 99*b75c6efcSBarry Smith #endif 100*b75c6efcSBarry Smith if (!err && wsize > 0) return 1; 101*b75c6efcSBarry Smith if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n"); 102*b75c6efcSBarry Smith n -= err; 103*b75c6efcSBarry Smith pp += err; 104*b75c6efcSBarry Smith } 105*b75c6efcSBarry Smith 106*b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) { 107*b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 108*b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 109*b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 110*b75c6efcSBarry Smith } 111*b75c6efcSBarry Smith return 0; 112*b75c6efcSBarry Smith } 113*b75c6efcSBarry Smith 114*b75c6efcSBarry Smith /* 115*b75c6efcSBarry Smith PetscBinaryWrite - Writes to a socket, called from MATLAB 116*b75c6efcSBarry Smith 117*b75c6efcSBarry Smith Input Parameters: 118*b75c6efcSBarry Smith . fd - the file 119*b75c6efcSBarry Smith . n - the number of items to read 120*b75c6efcSBarry Smith . p - the data 121*b75c6efcSBarry Smith . type - the type of items to read (PETSC_INT or PETSC_SCALAR) 122*b75c6efcSBarry Smith 123*b75c6efcSBarry Smith Notes: 124*b75c6efcSBarry Smith does byte swapping to work on all machines. 125*b75c6efcSBarry Smith */ 126*b75c6efcSBarry Smith PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type) 127*b75c6efcSBarry Smith { 128*b75c6efcSBarry Smith int maxblock, wsize, err = 0, retv = 0; 129*b75c6efcSBarry Smith char *pp = (char *)p; 130*b75c6efcSBarry Smith int ntmp = n; 131*b75c6efcSBarry Smith void *ptmp = (void *)p; 132*b75c6efcSBarry Smith 133*b75c6efcSBarry Smith maxblock = 65536; 134*b75c6efcSBarry Smith if (type == PETSC_INT) n *= sizeof(int); 135*b75c6efcSBarry Smith else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); 136*b75c6efcSBarry Smith else if (type == PETSC_SHORT) n *= sizeof(short); 137*b75c6efcSBarry Smith else if (type == PETSC_CHAR) n *= sizeof(char); 138*b75c6efcSBarry Smith else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); 139*b75c6efcSBarry Smith 140*b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) { 141*b75c6efcSBarry Smith /* make sure data is in correct byte ordering before sending */ 142*b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 143*b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 144*b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 145*b75c6efcSBarry Smith } 146*b75c6efcSBarry Smith 147*b75c6efcSBarry Smith while (n) { 148*b75c6efcSBarry Smith wsize = (n < maxblock) ? n : maxblock; 149*b75c6efcSBarry Smith err = write(fd, pp, wsize); 150*b75c6efcSBarry Smith #if !defined(PETSC_MISSING_ERRNO_EINTR) 151*b75c6efcSBarry Smith if (err < 0 && errno == EINTR) continue; 152*b75c6efcSBarry Smith #endif 153*b75c6efcSBarry Smith if (!err && wsize > 0) { 154*b75c6efcSBarry Smith retv = 1; 155*b75c6efcSBarry Smith break; 156*b75c6efcSBarry Smith }; 157*b75c6efcSBarry Smith if (err < 0) break; 158*b75c6efcSBarry Smith n -= err; 159*b75c6efcSBarry Smith pp += err; 160*b75c6efcSBarry Smith } 161*b75c6efcSBarry Smith 162*b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) { 163*b75c6efcSBarry Smith /* swap the data back if we swapped it before sending it */ 164*b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 165*b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 166*b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 167*b75c6efcSBarry Smith } 168*b75c6efcSBarry Smith 169*b75c6efcSBarry Smith if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n"); 170*b75c6efcSBarry Smith return retv; 171*b75c6efcSBarry Smith } 172