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