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