Actual source code: bread.c
2: #include <stdio.h>
3: #include petscsys.h
4: #include ../src/sys/viewer/impls/socket/socket.h
7: /*
8: TAKEN from src/sys/fileio/sysio.c The swap byte routines are
9: included here because the Matlab programs that use this do NOT
10: link to the PETSc libraries.
11: */
12: #include <errno.h>
13: #if defined(PETSC_HAVE_UNISTD_H)
14: #include <unistd.h>
15: #endif
17: #if !defined(PETSC_WORDS_BIGENDIAN)
18: /*
19: SYByteSwapInt - Swap bytes in an integer
20: */
23: void SYByteSwapInt(int *buff,int n)
24: {
25: int i,j,tmp;
26: char *ptr1,*ptr2 = (char*)&tmp;
27: for (j=0; j<n; j++) {
28: ptr1 = (char*)(buff + j);
29: for (i=0; i<sizeof(int); i++) {
30: ptr2[i] = ptr1[sizeof(int)-1-i];
31: }
32: buff[j] = tmp;
33: }
34: }
35: /*
36: SYByteSwapShort - Swap bytes in a short
37: */
40: void SYByteSwapShort(short *buff,int n)
41: {
42: int i,j;
43: short tmp;
44: char *ptr1,*ptr2 = (char*)&tmp;
45: for (j=0; j<n; j++) {
46: ptr1 = (char*)(buff + j);
47: for (i=0; i<sizeof(short); i++) {
48: ptr2[i] = ptr1[sizeof(int)-1-i];
49: }
50: buff[j] = tmp;
51: }
52: }
53: /*
54: SYByteSwapScalar - Swap bytes in a double
55: Complex is dealt with as if array of double twice as long.
56: */
59: void SYByteSwapScalar(PetscScalar *buff,int n)
60: {
61: int i,j;
62: double tmp,*buff1 = (double*)buff;
63: char *ptr1,*ptr2 = (char*)&tmp;
64: #if defined(PETSC_USE_COMPLEX)
65: n *= 2;
66: #endif
67: for (j=0; j<n; j++) {
68: ptr1 = (char*)(buff1 + j);
69: for (i=0; i<sizeof(double); i++) {
70: ptr2[i] = ptr1[sizeof(double)-1-i];
71: }
72: buff1[j] = tmp;
73: }
74: }
75: #endif
77: #define PETSC_MEX_ERROR(a) {fprintf(stdout,"sread: %s \n",a); return PETSC_ERR_SYS;}
81: /*
82: PetscBinaryRead - Reads from a socket, called from Matlab
84: Input Parameters:
85: . fd - the file
86: . n - the number of items to read
87: . type - the type of items to read (PETSC_INT or PETSC_SCALAR)
89: Output Parameters:
90: . p - the buffer
92: Notes: does byte swapping to work on all machines.
93: */
94: PetscErrorCode PetscBinaryRead(int fd,void *p,int n,PetscDataType type)
95: {
97: int maxblock,wsize,err;
98: char *pp = (char*)p;
99: #if !defined(PETSC_WORDS_BIGENDIAN)
100: int ntmp = n;
101: void *ptmp = p;
102: #endif
104: maxblock = 65536;
105: if (type == PETSC_INT) n *= sizeof(int);
106: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
107: else if (type == PETSC_SHORT) n *= sizeof(short);
108: else if (type == PETSC_CHAR) n *= sizeof(char);
109: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
110:
111: while (n) {
112: wsize = (n < maxblock) ? n : maxblock;
113: err = read(fd,pp,wsize);
114: #if !defined(PETSC_MISSING_ERRNO_EINTR)
115: if (err < 0 && errno == EINTR) continue;
116: #endif
117: if (!err && wsize > 0) return 1;
118: if (err < 0) {
119: PETSC_MEX_ERROR("Error reading from socket\n");
120: }
121: n -= err;
122: pp += err;
123: }
124: #if !defined(PETSC_WORDS_BIGENDIAN)
125: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
126: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
127: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
128: #endif
130: return 0;
131: }
135: /*
136: PetscBinaryWrite - Writes to a socket, called from Matlab
138: Input Parameters:
139: . fd - the file
140: . n - the number of items to read
141: . p - the data
142: . type - the type of items to read (PETSC_INT or PETSC_SCALAR)
145: Notes: does byte swapping to work on all machines.
146: */
147: PetscErrorCode PetscBinaryWrite(int fd,void *p,int n,PetscDataType type,PetscTruth dummy)
148: {
150: int maxblock,wsize,err;
151: char *pp = (char*)p;
152: #if !defined(PETSC_WORDS_BIGENDIAN)
153: int ntmp = n;
154: void *ptmp = p;
155: #endif
157: maxblock = 65536;
158: if (type == PETSC_INT) n *= sizeof(int);
159: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
160: else if (type == PETSC_SHORT) n *= sizeof(short);
161: else if (type == PETSC_CHAR) n *= sizeof(char);
162: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
164: #if !defined(PETSC_WORDS_BIGENDIAN)
165: /* make sure data is in correct byte ordering before sending */
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: while (n) {
172: wsize = (n < maxblock) ? n : maxblock;
173: err = write(fd,pp,wsize);
174: #if !defined(PETSC_MISSING_ERRNO_EINTR)
175: if (err < 0 && errno == EINTR) continue;
176: #endif
177: if (!err && wsize > 0) return 1;
178: if (err < 0) {
179: PETSC_MEX_ERROR("Error reading from socket\n");
180: }
181: n -= err;
182: pp += err;
183: }
184: #if !defined(PETSC_WORDS_BIGENDIAN)
185: /* swap the data back if we swapped it before sending it */
186: if (type == PETSC_INT) SYByteSwapInt((int*)ptmp,ntmp);
187: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar*)ptmp,ntmp);
188: else if (type == PETSC_SHORT) SYByteSwapShort((short*)ptmp,ntmp);
189: #endif
191: return 0;
192: }