Actual source code: bread.c
petsc-3.9.4 2018-09-11
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: does byte swapping to work on all machines.
78: */
79: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
80: {
82: int maxblock,wsize,err;
83: char *pp = (char*)p;
84: #if !defined(PETSC_WORDS_BIGENDIAN)
85: int ntmp = n;
86: void *ptmp = p;
87: #endif
89: maxblock = 65536;
90: if (type == PETSC_INT) n *= sizeof(int);
91: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
92: else if (type == PETSC_SHORT) n *= sizeof(short);
93: else if (type == PETSC_CHAR) n *= sizeof(char);
94: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
97: while (n) {
98: wsize = (n < maxblock) ? n : maxblock;
99: err = read(fd,pp,wsize);
100: #if !defined(PETSC_MISSING_ERRNO_EINTR)
101: if (err < 0 && errno == EINTR) continue;
102: #endif
103: if (!err && wsize > 0) return 1;
104: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
105: n -= err;
106: pp += err;
107: }
109: #if !defined(PETSC_WORDS_BIGENDIAN)
110: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
111: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
112: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
113: #endif
114: return 0;
115: }
117: /*
118: PetscBinaryWrite - Writes to a socket, called from MATLAB
120: Input Parameters:
121: . fd - the file
122: . n - the number of items to read
123: . p - the data
124: . type - the type of items to read (PETSC_INT or PETSC_SCALAR)
127: Notes: does byte swapping to work on all machines.
128: */
129: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscBool dummy)
130: {
132: int maxblock,wsize,err;
133: char *pp = (char*)p;
134: #if !defined(PETSC_WORDS_BIGENDIAN)
135: int ntmp = n;
136: void *ptmp = p;
137: #endif
139: maxblock = 65536;
140: if (type == PETSC_INT) n *= sizeof(int);
141: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
142: else if (type == PETSC_SHORT) n *= sizeof(short);
143: else if (type == PETSC_CHAR) n *= sizeof(char);
144: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
146: #if !defined(PETSC_WORDS_BIGENDIAN)
147: /* make sure data is in correct byte ordering before sending */
148: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
149: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
150: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
151: #endif
153: while (n) {
154: wsize = (n < maxblock) ? n : maxblock;
155: err = write(fd,pp,wsize);
156: #if !defined(PETSC_MISSING_ERRNO_EINTR)
157: if (err < 0 && errno == EINTR) continue;
158: #endif
159: if (!err && wsize > 0) return 1;
160: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
161: n -= err;
162: pp += err;
163: }
164: #if !defined(PETSC_WORDS_BIGENDIAN)
165: /* swap the data back if we swapped it before sending it */
166: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
167: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
168: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
169: #endif
171: return 0;
172: }