1 #include <petscsys.h> 2 #include <../src/sys/classes/viewer/impls/socket/socket.h> 3 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 13 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 } 59 60 #define PETSC_MEX_ERROR(a) \ 61 { \ 62 fprintf(stdout, "sread: %s \n", a); \ 63 return PETSC_ERR_SYS; \ 64 } 65 66 // PetscClangLinter pragma disable: -fdoc.* 67 /* 68 PetscBinaryRead - Reads from a socket, called from MATLAB 69 70 Input Parameters: 71 + fd - the file 72 . n - the number of items to read 73 - type - the type of items to read (PETSC_INT or PETSC_SCALAR) 74 75 Output Parameter: 76 . p - the buffer 77 78 Notes: 79 does byte swapping to work on all machines. 80 */ 81 PetscErrorCode PetscBinaryRead(int fd, void *p, int n, int *dummy, PetscDataType type) 82 { 83 int maxblock, wsize, err; 84 char *pp = (char *)p; 85 int ntmp = n; 86 void *ptmp = p; 87 88 maxblock = 65536; 89 if (type == PETSC_INT) n *= sizeof(int); 90 else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); 91 else if (type == PETSC_SHORT) n *= sizeof(short); 92 else if (type == PETSC_CHAR) n *= sizeof(char); 93 else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); 94 95 while (n) { 96 wsize = (n < maxblock) ? n : maxblock; 97 err = read(fd, pp, wsize); 98 #if !defined(PETSC_MISSING_ERRNO_EINTR) 99 if (err < 0 && errno == EINTR) continue; 100 #endif 101 if (!err && wsize > 0) return 1; 102 if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n"); 103 n -= err; 104 pp += err; 105 } 106 107 if (!PetscBinaryBigEndian()) { 108 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 109 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 110 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 111 } 112 return 0; 113 } 114 115 /* 116 PetscBinaryWrite - Writes to a socket, called from MATLAB 117 118 Input Parameters: 119 + fd - the file 120 . n - the number of items to read 121 . p - the data 122 - type - the type of items to read (PETSC_INT or PETSC_SCALAR) 123 124 Notes: 125 does byte swapping to work on all machines. 126 */ 127 PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type) 128 { 129 int maxblock, wsize, err = 0, retv = 0; 130 char *pp = (char *)p; 131 int ntmp = n; 132 void *ptmp = (void *)p; 133 134 maxblock = 65536; 135 if (type == PETSC_INT) n *= sizeof(int); 136 else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); 137 else if (type == PETSC_SHORT) n *= sizeof(short); 138 else if (type == PETSC_CHAR) n *= sizeof(char); 139 else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); 140 141 if (!PetscBinaryBigEndian()) { 142 /* make sure data is in correct byte ordering before sending */ 143 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 144 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 145 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 146 } 147 148 while (n) { 149 wsize = (n < maxblock) ? n : maxblock; 150 err = write(fd, pp, wsize); 151 #if !defined(PETSC_MISSING_ERRNO_EINTR) 152 if (err < 0 && errno == EINTR) continue; 153 #endif 154 if (!err && wsize > 0) { 155 retv = 1; 156 break; 157 }; 158 if (err < 0) break; 159 n -= err; 160 pp += err; 161 } 162 163 if (!PetscBinaryBigEndian()) { 164 /* swap the data back if we swapped it before sending it */ 165 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 166 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 167 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 168 } 169 170 if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n"); 171 return retv; 172 } 173