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 */
SYByteSwapInt(int * buff,PetscCount n)17*66218dbdSBarry Smith static void SYByteSwapInt(int *buff, PetscCount n)
18b75c6efcSBarry Smith {
19*66218dbdSBarry Smith int tmp;
20b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp;
21*66218dbdSBarry Smith for (PetscCount j = 0; j < n; j++) {
22b75c6efcSBarry Smith ptr1 = (char *)(buff + j);
23*66218dbdSBarry Smith for (PetscCount i = 0; i < 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 */
SYByteSwapShort(short * buff,PetscCount n)30*66218dbdSBarry Smith static void SYByteSwapShort(short *buff, PetscCount n)
31b75c6efcSBarry Smith {
32b75c6efcSBarry Smith short tmp;
33b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp;
34*66218dbdSBarry Smith for (PetscCount j = 0; j < n; j++) {
35b75c6efcSBarry Smith ptr1 = (char *)(buff + j);
36*66218dbdSBarry Smith for (PetscCount i = 0; i < sizeof(short); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i];
37b75c6efcSBarry Smith buff[j] = tmp;
38b75c6efcSBarry Smith }
39b75c6efcSBarry Smith }
40b75c6efcSBarry Smith /*
41b75c6efcSBarry Smith SYByteSwapScalar - Swap bytes in a double
42b75c6efcSBarry Smith Complex is dealt with as if array of double twice as long.
43b75c6efcSBarry Smith */
SYByteSwapScalar(PetscScalar * buff,PetscCount n)44*66218dbdSBarry Smith static void SYByteSwapScalar(PetscScalar *buff, PetscCount n)
45b75c6efcSBarry Smith {
46b75c6efcSBarry Smith double tmp, *buff1 = (double *)buff;
47b75c6efcSBarry Smith char *ptr1, *ptr2 = (char *)&tmp;
48b75c6efcSBarry Smith #if defined(PETSC_USE_COMPLEX)
49b75c6efcSBarry Smith n *= 2;
50b75c6efcSBarry Smith #endif
51*66218dbdSBarry Smith for (PetscCount j = 0; j < n; j++) {
52b75c6efcSBarry Smith ptr1 = (char *)(buff1 + j);
53*66218dbdSBarry Smith for (PetscCount i = 0; i < sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i];
54b75c6efcSBarry Smith buff1[j] = tmp;
55b75c6efcSBarry Smith }
56b75c6efcSBarry Smith }
57b75c6efcSBarry Smith
58b75c6efcSBarry Smith #define PETSC_MEX_ERROR(a) \
59b75c6efcSBarry Smith { \
60b75c6efcSBarry Smith fprintf(stdout, "sread: %s \n", a); \
61b75c6efcSBarry Smith return PETSC_ERR_SYS; \
62b75c6efcSBarry Smith }
63b75c6efcSBarry Smith
6410450e9eSJacob Faibussowitsch // PetscClangLinter pragma disable: -fdoc.*
65b75c6efcSBarry Smith /*
66b75c6efcSBarry Smith PetscBinaryRead - Reads from a socket, called from MATLAB
67b75c6efcSBarry Smith
68b75c6efcSBarry Smith Input Parameters:
692fe279fdSBarry Smith + fd - the file
70b75c6efcSBarry Smith . n - the number of items to read
712fe279fdSBarry Smith - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
72b75c6efcSBarry Smith
732fe279fdSBarry Smith Output Parameter:
74b75c6efcSBarry Smith . p - the buffer
75b75c6efcSBarry Smith
76b75c6efcSBarry Smith Notes:
77b75c6efcSBarry Smith does byte swapping to work on all machines.
78b75c6efcSBarry Smith */
PetscBinaryRead(int fd,void * p,PetscCount n,PetscInt * dummy,PetscDataType type)79*66218dbdSBarry Smith PetscErrorCode PetscBinaryRead(int fd, void *p, PetscCount n, PetscInt *dummy, PetscDataType type)
80b75c6efcSBarry Smith {
81*66218dbdSBarry Smith int maxblock, err;
82b75c6efcSBarry Smith char *pp = (char *)p;
83*66218dbdSBarry Smith PetscCount ntmp = n, wsize;
84b75c6efcSBarry Smith void *ptmp = p;
85b75c6efcSBarry Smith
86b75c6efcSBarry Smith maxblock = 65536;
87b75c6efcSBarry Smith if (type == PETSC_INT) n *= sizeof(int);
88b75c6efcSBarry Smith else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
89b75c6efcSBarry Smith else if (type == PETSC_SHORT) n *= sizeof(short);
90b75c6efcSBarry Smith else if (type == PETSC_CHAR) n *= sizeof(char);
91b75c6efcSBarry Smith else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
92b75c6efcSBarry Smith
93b75c6efcSBarry Smith while (n) {
94b75c6efcSBarry Smith wsize = (n < maxblock) ? n : maxblock;
95*66218dbdSBarry Smith err = (int)read(fd, pp, (int)wsize);
96b75c6efcSBarry Smith if (err < 0 && errno == EINTR) continue;
97b75c6efcSBarry Smith if (!err && wsize > 0) return 1;
98b75c6efcSBarry Smith if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
99b75c6efcSBarry Smith n -= err;
100b75c6efcSBarry Smith pp += err;
101b75c6efcSBarry Smith }
102b75c6efcSBarry Smith
103b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) {
104b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
105b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
106b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
107b75c6efcSBarry Smith }
108b75c6efcSBarry Smith return 0;
109b75c6efcSBarry Smith }
110b75c6efcSBarry Smith
111b75c6efcSBarry Smith /*
112b75c6efcSBarry Smith PetscBinaryWrite - Writes to a socket, called from MATLAB
113b75c6efcSBarry Smith
114b75c6efcSBarry Smith Input Parameters:
1152fe279fdSBarry Smith + fd - the file
116b75c6efcSBarry Smith . n - the number of items to read
117b75c6efcSBarry Smith . p - the data
1182fe279fdSBarry Smith - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
119b75c6efcSBarry Smith
120b75c6efcSBarry Smith Notes:
121b75c6efcSBarry Smith does byte swapping to work on all machines.
122b75c6efcSBarry Smith */
PetscBinaryWrite(int fd,const void * p,PetscCount n,PetscDataType type)123*66218dbdSBarry Smith PetscErrorCode PetscBinaryWrite(int fd, const void *p, PetscCount n, PetscDataType type)
124b75c6efcSBarry Smith {
125*66218dbdSBarry Smith int maxblock, err = 0, retv = 0;
126b75c6efcSBarry Smith char *pp = (char *)p;
127*66218dbdSBarry Smith PetscCount ntmp = n;
128b75c6efcSBarry Smith void *ptmp = (void *)p;
129*66218dbdSBarry Smith PetscCount wsize;
130b75c6efcSBarry Smith
131b75c6efcSBarry Smith maxblock = 65536;
132b75c6efcSBarry Smith if (type == PETSC_INT) n *= sizeof(int);
133b75c6efcSBarry Smith else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
134b75c6efcSBarry Smith else if (type == PETSC_SHORT) n *= sizeof(short);
135b75c6efcSBarry Smith else if (type == PETSC_CHAR) n *= sizeof(char);
136b75c6efcSBarry Smith else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
137b75c6efcSBarry Smith
138b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) {
139b75c6efcSBarry Smith /* make sure data is in correct byte ordering before sending */
140b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
141b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
142b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
143b75c6efcSBarry Smith }
144b75c6efcSBarry Smith
145b75c6efcSBarry Smith while (n) {
146b75c6efcSBarry Smith wsize = (n < maxblock) ? n : maxblock;
147*66218dbdSBarry Smith err = (int)write(fd, pp, (int)wsize);
148b75c6efcSBarry Smith if (err < 0 && errno == EINTR) continue;
149b75c6efcSBarry Smith if (!err && wsize > 0) {
150b75c6efcSBarry Smith retv = 1;
151b75c6efcSBarry Smith break;
152b75c6efcSBarry Smith };
153b75c6efcSBarry Smith if (err < 0) break;
154b75c6efcSBarry Smith n -= err;
155b75c6efcSBarry Smith pp += err;
156b75c6efcSBarry Smith }
157b75c6efcSBarry Smith
158b75c6efcSBarry Smith if (!PetscBinaryBigEndian()) {
159b75c6efcSBarry Smith /* swap the data back if we swapped it before sending it */
160b75c6efcSBarry Smith if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
161b75c6efcSBarry Smith else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
162b75c6efcSBarry Smith else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
163b75c6efcSBarry Smith }
164b75c6efcSBarry Smith
165b75c6efcSBarry Smith if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
166b75c6efcSBarry Smith return retv;
167b75c6efcSBarry Smith }
168