Actual source code: bread.c
petsc-3.10.5 2019-03-28
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: #if !defined(PETSC_WORDS_BIGENDIAN)
17: /*
18: SYByteSwapInt - Swap bytes in an integer
19: */
20: void SYByteSwapInt(int *buff,int n)
21: {
22: int i,j,tmp;
23: char *ptr1,*ptr2 = (char*)&tmp;
24: for (j=0; j<n; j++) {
25: ptr1 = (char*)(buff + j);
26: for (i=0; i<(int)sizeof(int); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
27: buff[j] = tmp;
28: }
29: }
30: /*
31: SYByteSwapShort - Swap bytes in a short
32: */
33: void SYByteSwapShort(short *buff,int n)
34: {
35: int i,j;
36: short tmp;
37: char *ptr1,*ptr2 = (char*)&tmp;
38: for (j=0; j<n; j++) {
39: ptr1 = (char*)(buff + j);
40: for (i=0; i<(int)sizeof(short); i++) ptr2[i] = ptr1[sizeof(int)-1-i];
41: buff[j] = tmp;
42: }
43: }
44: /*
45: SYByteSwapScalar - Swap bytes in a double
46: Complex is dealt with as if array of double twice as long.
47: */
48: void SYByteSwapScalar(PetscScalar *buff,int n)
49: {
50: int i,j;
51: double tmp,*buff1 = (double*)buff;
52: char *ptr1,*ptr2 = (char*)&tmp;
53: #if defined(PETSC_USE_COMPLEX)
54: n *= 2;
55: #endif
56: for (j=0; j<n; j++) {
57: ptr1 = (char*)(buff1 + j);
58: for (i=0; i<(int)sizeof(double); i++) ptr2[i] = ptr1[sizeof(double)-1-i];
59: buff1[j] = tmp;
60: }
61: }
62: #endif
64: #define PETSC_MEX_ERROR(a) {fprintf(stdout,"sread: %s \n",a); return PETSC_ERR_SYS;}
66: /*
67: PetscBinaryRead - Reads from a socket, called from MATLAB
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)
74: Output Parameters:
75: . p - the buffer
77: Notes:
78: does byte swapping to work on all machines.
79: */
80: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
81: {
83: int maxblock,wsize,err;
84: char *pp = (char*)p;
85: #if !defined(PETSC_WORDS_BIGENDIAN)
86: int ntmp = n;
87: void *ptmp = p;
88: #endif
90: maxblock = 65536;
91: if (type == PETSC_INT) n *= sizeof(int);
92: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
93: else if (type == PETSC_SHORT) n *= sizeof(short);
94: else if (type == PETSC_CHAR) n *= sizeof(char);
95: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
98: while (n) {
99: wsize = (n < maxblock) ? n : maxblock;
100: err = read(fd,pp,wsize);
101: #if !defined(PETSC_MISSING_ERRNO_EINTR)
102: if (err < 0 && errno == EINTR) continue;
103: #endif
104: if (!err && wsize > 0) return 1;
105: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
106: n -= err;
107: pp += err;
108: }
110: #if !defined(PETSC_WORDS_BIGENDIAN)
111: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
112: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
113: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
114: #endif
115: return 0;
116: }
118: /*
119: PetscBinaryWrite - Writes to a socket, called from MATLAB
121: Input Parameters:
122: . fd - the file
123: . n - the number of items to read
124: . p - the data
125: . type - the type of items to read (PETSC_INT or PETSC_SCALAR)
128: Notes:
129: does byte swapping to work on all machines.
130: */
131: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscBool dummy)
132: {
134: int maxblock,wsize,err;
135: char *pp = (char*)p;
136: #if !defined(PETSC_WORDS_BIGENDIAN)
137: int ntmp = n;
138: void *ptmp = p;
139: #endif
141: maxblock = 65536;
142: if (type == PETSC_INT) n *= sizeof(int);
143: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
144: else if (type == PETSC_SHORT) n *= sizeof(short);
145: else if (type == PETSC_CHAR) n *= sizeof(char);
146: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
148: #if !defined(PETSC_WORDS_BIGENDIAN)
149: /* make sure data is in correct byte ordering before sending */
150: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
151: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
152: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
153: #endif
155: while (n) {
156: wsize = (n < maxblock) ? n : maxblock;
157: err = write(fd,pp,wsize);
158: #if !defined(PETSC_MISSING_ERRNO_EINTR)
159: if (err < 0 && errno == EINTR) continue;
160: #endif
161: if (!err && wsize > 0) return 1;
162: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
163: n -= err;
164: pp += err;
165: }
166: #if !defined(PETSC_WORDS_BIGENDIAN)
167: /* swap the data back if we swapped it before sending it */
168: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
169: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
170: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
171: #endif
173: return 0;
174: }