Fix bug in PL2+ implementation
[xapian.git] / xapian-applications / omega / worker_comms.cc
blob6e3308090d6e3c59926fc3e2e3fde8cee4bb11f6
1 /** @file
2 * @brief Communication with worker processes
3 */
4 /* Copyright (C) 2011,2022,2023 Olly Betts
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
19 * USA
22 #include <config.h>
24 #include "worker_comms.h"
26 using namespace std;
28 const int buffer_size = 4096;
30 bool
31 read_string(FILE* f, string& s)
33 // Extracting the length of the string
34 int ch = getc(f);
35 if (ch < 0) return false;
36 size_t len = ch;
37 if (len >= 253) {
38 unsigned i = len - 251;
39 len = 0;
40 for ( ; i; --i) {
41 ch = getc(f);
42 if (ch < 0) return false;
43 len = (len << 8) | ch;
47 s.resize(0);
48 s.reserve(len);
50 // Reading the string
51 char buf[buffer_size];
53 while (len) {
54 size_t n = fread(buf, 1, min(sizeof(buf), len), f);
55 if (n == 0) {
56 // Error or EOF!
57 return false;
59 s.append(buf, size_t(n));
60 len -= n;
63 return true;
66 bool
67 write_string(FILE* f, const char* p, size_t len)
69 if (len < 253) {
70 putc(static_cast<unsigned char>(len), f);
71 } else if (len < 0x10000) {
72 putc(253, f);
73 putc(static_cast<unsigned char>(len >> 8), f);
74 putc(static_cast<unsigned char>(len), f);
75 } else if (len < 0x1000000) {
76 putc(254, f);
77 putc(static_cast<unsigned char>(len >> 16), f);
78 putc(static_cast<unsigned char>(len >> 8), f);
79 putc(static_cast<unsigned char>(len), f);
80 } else {
81 putc(255, f);
82 putc(static_cast<unsigned char>(len >> 24), f);
83 putc(static_cast<unsigned char>(len >> 16), f);
84 putc(static_cast<unsigned char>(len >> 8), f);
85 putc(static_cast<unsigned char>(len), f);
88 while (len) {
89 size_t n = fwrite(p, 1, len, f);
90 if (n == 0) {
91 // EOF.
92 return false;
94 p += n;
95 len -= n;
98 return true;
101 bool
102 read_unsigned(FILE* f, unsigned& v)
104 unsigned char data[(sizeof(v) * 8 + 6) / 7];
105 unsigned char* p = data;
106 int ch;
107 do {
108 ch = getc(f);
109 if (p - data == sizeof(data) || ch < 0) return false;
110 *p++ = ch & 0x7f;
111 } while (ch & 0x80);
112 v = 0;
113 do {
114 --p;
115 v = (v << 7) | *p;
116 } while (p > data);
117 return true;
120 bool
121 read_unsigned(FILE* f, unsigned long& v)
123 unsigned char data[(sizeof(v) * 8 + 6) / 7];
124 unsigned char* p = data;
125 int ch;
126 do {
127 ch = getc(f);
128 if (p - data == sizeof(data) || ch < 0) return false;
129 *p++ = ch & 0x7f;
130 } while (ch & 0x80);
131 v = 0;
132 do {
133 --p;
134 v = (v << 7) | *p;
135 } while (p > data);
136 return true;
139 bool
140 write_unsigned(FILE* f, unsigned long v)
142 while (v >= 0x80) {
143 if (putc(v | 0x80, f) < 0) return false;
144 v >>= 7;
146 return !(putc(v, f) < 0);
149 bool
150 write_unsigned(FILE* f, unsigned v)
152 while (v >= 0x80) {
153 if (putc(v | 0x80, f) < 0) return false;
154 v >>= 7;
156 return !(putc(v, f) < 0);