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) \
61: { \
62: fprintf(stdout, "sread: %s \n", a); \
63: return PETSC_ERR_SYS; \
64: }
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 Parameter:
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, int *dummy, PetscDataType type)
81: {
82: int maxblock, wsize, err;
83: char *pp = (char *)p;
84: int ntmp = n;
85: void *ptmp = p;
87: maxblock = 65536;
88: if (type == PETSC_INT) n *= sizeof(int);
89: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
90: else if (type == PETSC_SHORT) n *= sizeof(short);
91: else if (type == PETSC_CHAR) n *= sizeof(char);
92: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
94: while (n) {
95: wsize = (n < maxblock) ? n : maxblock;
96: err = read(fd, pp, wsize);
97: #if !defined(PETSC_MISSING_ERRNO_EINTR)
98: if (err < 0 && errno == EINTR) continue;
99: #endif
100: if (!err && wsize > 0) return 1;
101: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
102: n -= err;
103: pp += err;
104: }
106: if (!PetscBinaryBigEndian()) {
107: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
108: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
109: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
110: }
111: return 0;
112: }
114: /*
115: PetscBinaryWrite - Writes to a socket, called from MATLAB
117: Input Parameters:
118: + fd - the file
119: . n - the number of items to read
120: . p - the data
121: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
123: Notes:
124: does byte swapping to work on all machines.
125: */
126: PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type)
127: {
128: int maxblock, wsize, err = 0, retv = 0;
129: char *pp = (char *)p;
130: int ntmp = n;
131: void *ptmp = (void *)p;
133: maxblock = 65536;
134: if (type == PETSC_INT) n *= sizeof(int);
135: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
136: else if (type == PETSC_SHORT) n *= sizeof(short);
137: else if (type == PETSC_CHAR) n *= sizeof(char);
138: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
140: if (!PetscBinaryBigEndian()) {
141: /* make sure data is in correct byte ordering before sending */
142: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
143: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
144: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
145: }
147: while (n) {
148: wsize = (n < maxblock) ? n : maxblock;
149: err = write(fd, pp, wsize);
150: #if !defined(PETSC_MISSING_ERRNO_EINTR)
151: if (err < 0 && errno == EINTR) continue;
152: #endif
153: if (!err && wsize > 0) {
154: retv = 1;
155: break;
156: };
157: if (err < 0) break;
158: n -= err;
159: pp += err;
160: }
162: if (!PetscBinaryBigEndian()) {
163: /* swap the data back if we swapped it before sending it */
164: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
165: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
166: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
167: }
169: if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
170: return retv;
171: }