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