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