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