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