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 PetscDefined(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 (PetscDefined(USE_COMPLEX)) n *= 2;
49: for (PetscCount j = 0; j < n; j++) {
50: ptr1 = (char *)(buff1 + j);
51: for (PetscCount i = 0; i < sizeof(double); i++) ptr2[i] = ptr1[sizeof(double) - 1 - i];
52: buff1[j] = tmp;
53: }
54: }
56: #define PETSC_MEX_ERROR(a) \
57: { \
58: fprintf(stdout, "sread: %s \n", a); \
59: return PETSC_ERR_SYS; \
60: }
62: // PetscClangLinter pragma disable: -fdoc.*
63: /*
64: PetscBinaryRead - Reads from a socket, called from MATLAB
66: Input Parameters:
67: + fd - the file
68: . n - the number of items to read
69: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
71: Output Parameter:
72: . p - the buffer
74: Notes:
75: does byte swapping to work on all machines.
76: */
77: PetscErrorCode PetscBinaryRead(int fd, void *p, PetscCount n, PetscInt *dummy, PetscDataType type)
78: {
79: int maxblock, err;
80: char *pp = (char *)p;
81: PetscCount ntmp = n, wsize;
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 = (int)read(fd, pp, (int)wsize);
94: if (err < 0 && errno == EINTR) continue;
95: if (!err && wsize > 0) return 1;
96: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
97: n -= err;
98: pp += err;
99: }
101: if (!PetscBinaryBigEndian()) {
102: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
103: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
104: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
105: }
106: return 0;
107: }
109: /*
110: PetscBinaryWrite - Writes to a socket, called from MATLAB
112: Input Parameters:
113: + fd - the file
114: . n - the number of items to read
115: . p - the data
116: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
118: Notes:
119: does byte swapping to work on all machines.
120: */
121: PetscErrorCode PetscBinaryWrite(int fd, const void *p, PetscCount n, PetscDataType type)
122: {
123: int maxblock, err = 0, retv = 0;
124: char *pp = (char *)p;
125: PetscCount ntmp = n;
126: void *ptmp = (void *)p;
127: PetscCount wsize;
129: maxblock = 65536;
130: if (type == PETSC_INT) n *= sizeof(int);
131: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
132: else if (type == PETSC_SHORT) n *= sizeof(short);
133: else if (type == PETSC_CHAR) n *= sizeof(char);
134: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
136: if (!PetscBinaryBigEndian()) {
137: /* make sure data is in correct byte ordering before sending */
138: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
139: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
140: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
141: }
143: while (n) {
144: wsize = (n < maxblock) ? n : maxblock;
145: err = (int)write(fd, pp, (int)wsize);
146: if (err < 0 && errno == EINTR) continue;
147: if (!err && wsize > 0) {
148: retv = 1;
149: break;
150: };
151: if (err < 0) break;
152: n -= err;
153: pp += err;
154: }
156: if (!PetscBinaryBigEndian()) {
157: /* swap the data back if we swapped it before sending it */
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: }
163: if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
164: return retv;
165: }