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