xref: /petsc/src/sys/classes/viewer/impls/socket/mex-scripts/bread.c (revision fbf9dbe564678ed6eff1806adbc4c4f01b9743f4)
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