#include #include <../src/sys/classes/viewer/impls/socket/socket.h> /* TAKEN from src/sys/fileio/sysio.c The swap byte routines are included here because the MATLAB programs that use this do NOT link to the PETSc libraries. */ #include #if defined(PETSC_HAVE_UNISTD_H) #include #endif /* SYByteSwapInt - Swap bytes in an integer */ static void SYByteSwapInt(int *buff, int n) { int i, j, tmp; char *ptr1, *ptr2 = (char *)&tmp; for (j = 0; j < n; j++) { ptr1 = (char *)(buff + j); for (i = 0; i < (int)sizeof(int); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i]; buff[j] = tmp; } } /* SYByteSwapShort - Swap bytes in a short */ static void SYByteSwapShort(short *buff, int n) { int i, j; short tmp; char *ptr1, *ptr2 = (char *)&tmp; for (j = 0; j < n; j++) { ptr1 = (char *)(buff + j); for (i = 0; i < (int)sizeof(short); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i]; buff[j] = tmp; } } /* SYByteSwapScalar - Swap bytes in a double Complex is dealt with as if array of double twice as long. */ static void SYByteSwapScalar(PetscScalar *buff, int n) { int i, j; double tmp, *buff1 = (double *)buff; char *ptr1, *ptr2 = (char *)&tmp; #if defined(PETSC_USE_COMPLEX) n *= 2; #endif for (j = 0; j < n; j++) { ptr1 = (char *)(buff1 + j); for (i = 0; i < (int)sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i]; buff1[j] = tmp; } } #define PETSC_MEX_ERROR(a) \ { \ fprintf(stdout, "sread: %s \n", a); \ return PETSC_ERR_SYS; \ } // PetscClangLinter pragma disable: -fdoc.* /* PetscBinaryRead - Reads from a socket, called from MATLAB Input Parameters: + fd - the file . n - the number of items to read - type - the type of items to read (PETSC_INT or PETSC_SCALAR) Output Parameter: . p - the buffer Notes: does byte swapping to work on all machines. */ PetscErrorCode PetscBinaryRead(int fd, void *p, int n, int *dummy, PetscDataType type) { int maxblock, wsize, err; char *pp = (char *)p; int ntmp = n; void *ptmp = p; maxblock = 65536; if (type == PETSC_INT) n *= sizeof(int); else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); else if (type == PETSC_SHORT) n *= sizeof(short); else if (type == PETSC_CHAR) n *= sizeof(char); else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); while (n) { wsize = (n < maxblock) ? n : maxblock; err = read(fd, pp, wsize); if (err < 0 && errno == EINTR) continue; if (!err && wsize > 0) return 1; if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n"); n -= err; pp += err; } if (!PetscBinaryBigEndian()) { if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); } return 0; } /* PetscBinaryWrite - Writes to a socket, called from MATLAB Input Parameters: + fd - the file . n - the number of items to read . p - the data - type - the type of items to read (PETSC_INT or PETSC_SCALAR) Notes: does byte swapping to work on all machines. */ PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type) { int maxblock, wsize, err = 0, retv = 0; char *pp = (char *)p; int ntmp = n; void *ptmp = (void *)p; maxblock = 65536; if (type == PETSC_INT) n *= sizeof(int); else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); else if (type == PETSC_SHORT) n *= sizeof(short); else if (type == PETSC_CHAR) n *= sizeof(char); else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); if (!PetscBinaryBigEndian()) { /* make sure data is in correct byte ordering before sending */ if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); } while (n) { wsize = (n < maxblock) ? n : maxblock; err = write(fd, pp, wsize); if (err < 0 && errno == EINTR) continue; if (!err && wsize > 0) { retv = 1; break; }; if (err < 0) break; n -= err; pp += err; } if (!PetscBinaryBigEndian()) { /* swap the data back if we swapped it before sending it */ if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); } if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n"); return retv; }