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, 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: static 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: static 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: // PetscClangLinter pragma disable: -fdoc.*
67: /*
68: PetscBinaryRead - Reads from a socket, called from MATLAB
70: Input Parameters:
71: + fd - the file
72: . n - the number of items to read
73: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
75: Output Parameter:
76: . p - the buffer
78: Notes:
79: does byte swapping to work on all machines.
80: */
81: PetscErrorCode PetscBinaryRead(int fd, void *p, int n, int *dummy, PetscDataType type)
82: {
83: int maxblock, wsize, err;
84: char *pp = (char *)p;
85: int ntmp = n;
86: void *ptmp = p;
88: maxblock = 65536;
89: if (type == PETSC_INT) n *= sizeof(int);
90: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
91: else if (type == PETSC_SHORT) n *= sizeof(short);
92: else if (type == PETSC_CHAR) n *= sizeof(char);
93: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
95: while (n) {
96: wsize = (n < maxblock) ? n : maxblock;
97: err = read(fd, pp, wsize);
98: if (err < 0 && errno == EINTR) continue;
99: if (!err && wsize > 0) return 1;
100: if (err < 0) PETSC_MEX_ERROR("Error reading from socket\n");
101: n -= err;
102: pp += err;
103: }
105: if (!PetscBinaryBigEndian()) {
106: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
107: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
108: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
109: }
110: return 0;
111: }
113: /*
114: PetscBinaryWrite - Writes to a socket, called from MATLAB
116: Input Parameters:
117: + fd - the file
118: . n - the number of items to read
119: . p - the data
120: - type - the type of items to read (PETSC_INT or PETSC_SCALAR)
122: Notes:
123: does byte swapping to work on all machines.
124: */
125: PetscErrorCode PetscBinaryWrite(int fd, const void *p, int n, PetscDataType type)
126: {
127: int maxblock, wsize, err = 0, retv = 0;
128: char *pp = (char *)p;
129: int ntmp = n;
130: void *ptmp = (void *)p;
132: maxblock = 65536;
133: if (type == PETSC_INT) n *= sizeof(int);
134: else if (type == PETSC_SCALAR) n *= sizeof(PetscScalar);
135: else if (type == PETSC_SHORT) n *= sizeof(short);
136: else if (type == PETSC_CHAR) n *= sizeof(char);
137: else PETSC_MEX_ERROR("PetscBinaryRead: Unknown type");
139: if (!PetscBinaryBigEndian()) {
140: /* make sure data is in correct byte ordering before sending */
141: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
142: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
143: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
144: }
146: while (n) {
147: wsize = (n < maxblock) ? n : maxblock;
148: err = write(fd, pp, wsize);
149: if (err < 0 && errno == EINTR) continue;
150: if (!err && wsize > 0) {
151: retv = 1;
152: break;
153: };
154: if (err < 0) break;
155: n -= err;
156: pp += err;
157: }
159: if (!PetscBinaryBigEndian()) {
160: /* swap the data back if we swapped it before sending it */
161: if (type == PETSC_INT) SYByteSwapInt((int *)ptmp, ntmp);
162: else if (type == PETSC_SCALAR) SYByteSwapScalar((PetscScalar *)ptmp, ntmp);
163: else if (type == PETSC_SHORT) SYByteSwapShort((short *)ptmp, ntmp);
164: }
166: if (err < 0) PETSC_MEX_ERROR("Error writing to socket\n");
167: return retv;
168: }