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 static 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 static 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 static 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 (err < 0 && errno == EINTR) continue; 99 if (!err && wsize > 0) return 1; 100 if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n"); 101 n -= err; 102 pp += err; 103 } 104 105 if (!PetscBinaryBigEndian()) { 106 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 107 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 108 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 109 } 110 return 0; 111 } 112 113 /* 114 PetscBinaryWrite - Writes to a socket, called from MATLAB 115 116 Input Parameters: 117 + fd - the file 118 . n - the number of items to read 119 . p - the data 120 - type - the type of items to read (PETSC_INT or PETSC_SCALAR) 121 122 Notes: 123 does byte swapping to work on all machines. 124 */ 125 PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type) 126 { 127 int maxblock, wsize, err = 0, retv = 0; 128 char *pp = (char *)p; 129 int ntmp = n; 130 void *ptmp = (void *)p; 131 132 maxblock = 65536; 133 if (type == PETSC_INT) n *= sizeof(int); 134 else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar); 135 else if (type == PETSC_SHORT) n *= sizeof(short); 136 else if (type == PETSC_CHAR) n *= sizeof(char); 137 else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type"); 138 139 if (!PetscBinaryBigEndian()) { 140 /* make sure data is in correct byte ordering before sending */ 141 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 142 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 143 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 144 } 145 146 while (n) { 147 wsize = (n < maxblock) ? n : maxblock; 148 err = write(fd, pp, wsize); 149 if (err < 0 && errno == EINTR) continue; 150 if (!err && wsize > 0) { 151 retv = 1; 152 break; 153 }; 154 if (err < 0) break; 155 n -= err; 156 pp += err; 157 } 158 159 if (!PetscBinaryBigEndian()) { 160 /* swap the data back if we swapped it before sending it */ 161 if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp); 162 else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp); 163 else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp); 164 } 165 166 if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n"); 167 return retv; 168 } 169