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: static void SYByteSwapInt(int *buff, PetscCount n)
18: {
19: int tmp;
20: char *ptr1, *ptr2 = (char *)&tmp;
21: for (PetscCount j = 0; j < n; j++) {
22: ptr1 = (char *)(buff + j);
23: for (PetscCount i = 0; i < 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: static void SYByteSwapShort(short *buff, PetscCount n)
31: {
32: short tmp;
33: char *ptr1, *ptr2 = (char *)&tmp;
34: for (PetscCount j = 0; j < n; j++) {
35: ptr1 = (char *)(buff + j);
36: for (PetscCount i = 0; i < sizeof(short); i++) ptr2[i] = ptr1[sizeof(int) - 1 - i];
37: buff[j] = tmp;
38: }
39: }
40: /*
41: SYByteSwapScalar - Swap bytes in a double
42: Complex is dealt with as if array of double twice as long.
43: */
44: static void SYByteSwapScalar(PetscScalar *buff, PetscCount n)
45: {
46: double tmp, *buff1 = (double *)buff;
47: char *ptr1, *ptr2 = (char *)&tmp;
48: #if defined(PETSC_USE_COMPLEX)
49: n *= 2;
50: #endif
51: for (PetscCount j = 0; j < n; j++) {
52: ptr1 = (char *)(buff1 + j);
53: for (PetscCount i = 0; i < sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i];
54: buff1[j] = tmp;
55: }
56: }
58: #define PETSC_MEX_ERROR(a) \
59: { \
60: fprintf(stdout, "sread: %s \n", a); \
61: return PETSC_ERR_SYS; \
62: }
64: // PetscClangLinter pragma disable: -fdoc.*
65: /*
66: PetscBinaryRead - Reads from a socket, called from MATLAB
68: Input Parameters:
69: + fd - the file
70: . n - the number of items to read
71: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
73: Output Parameter:
74: . p - the buffer
76: Notes:
77: does byte swapping to work on all machines.
78: */
79: PetscErrorCode PetscBinaryRead(int fd, void *p, PetscCount n, PetscInt *dummy, PetscDataType type)
80: {
81: int maxblock, err;
82: char *pp = (char *)p;
83: PetscCount ntmp = n, wsize;
84: void *ptmp = p;
86: maxblock = 65536;
87: if (type == PETSC_INT) n *= sizeof(int);
88: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
89: else if (type == PETSC_SHORT) n *= sizeof(short);
90: else if (type == PETSC_CHAR) n *= sizeof(char);
91: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
93: while (n) {
94: wsize = (n < maxblock) ? n : maxblock;
95: err = (int)read(fd, pp, (int)wsize);
96: if (err < 0 && errno == EINTR) continue;
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, PetscCount n, PetscDataType type)
124: {
125: int maxblock, err = 0, retv = 0;
126: char *pp = (char *)p;
127: PetscCount ntmp = n;
128: void *ptmp = (void *)p;
129: PetscCount wsize;
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 = (int)write(fd, pp, (int)wsize);
148: if (err < 0 && errno == EINTR) continue;
149: if (!err && wsize > 0) {
150: retv = 1;
151: break;
152: };
153: if (err < 0) break;
154: n -= err;
155: pp += err;
156: }
158: if (!PetscBinaryBigEndian()) {
159: /* swap the data back if we swapped it before sending it */
160: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
161: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
162: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
163: }
165: if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
166: return retv;
167: }