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