Orbiter 2022
Combinatorial Objects
memory.cpp
Go to the documentation of this file.
1// memory.cpp
2//
3// Anton Betten
4// 04.04.2000
5// moved from D2 to ORBI Nov 15, 2007
6
8#include "discreta.h"
9
10using namespace std;
11
12
13
14namespace orbiter {
15namespace layer2_discreta {
16
17#undef MEMORY_COPY_VERBOSE
18#undef DEBUG_MEM
19#undef DEBUG_WRITE_CHAR
20#undef DEBUG_WRITE_int
21
22#define MEM_OVERSIZE 32
23#define MEM_OVERSIZE1 512
24
25/*
26 * int - offset - 3 + 0: alloc_length
27 * - 3 + 1: used_length
28 * - 3 + 2: cur_pointer
29 *
30 * alloc_length: allocated length in chars
31 * used_length: used length in charS
32 * cur_pointer:
33 * 0 <= pointer < used length.
34 */
35
36
37
39{
40 k = MEMORY;
41 self.char_pointer = NULL;
42}
43
45 // copy constructor: this := x
46{
47 // cout << "memory::copy constructor for object: " << const_cast<discreta_base &>(x) << "\n";
48 clearself();
49 const_cast<discreta_base &>(x).copyobject_to(*this);
50}
51
53 // copy assignment
54{
55 // cout << "memory::operator = (copy assignment)" << endl;
56 copyobject(const_cast<discreta_base &>(x));
57 return *this;
58}
59
61{
62 OBJECTSELF s;
63
64 s = self;
65 new(this) memory;
66 self = s;
67 k = MEMORY;
68}
69
71{
72 // cout << "memory::~memory()\n";
74}
75
77{
78
79 char *pc;
80 int *pi;
81
82 if (self.char_pointer == NULL) {
83 // cout << "returning\n";
84 return;
85 }
86 if (s_kind() != MEMORY) {
87 cout << "memory::freeself(): kind != MEM" << endl;
88 exit(1);
89 }
90 // cout << "memory::freeself_memory():"; cout << *this << endl;
91 pc = self.char_pointer;
92 if (pc) {
93 pi = (int *) pc;
94 pi -= 3;
95 delete [] pi;
96 self.char_pointer = NULL;
97 }
98}
99
101{
102 return MEMORY;
103}
104
106{
107 int l;
108
109#ifdef MEMORY_COPY_VERBOSE
110 cout << "in memory::copyobject_to()\n";
111#endif
112 x.freeself();
113 if (x.s_kind() != MEMORY) {
114#ifdef MEMORY_CHANGE_KIND_VERBOSE
115 cout << "warning: memory::copyobject_to x not a memory\n";
116#endif
117 x.c_kind(MEMORY);
118 // x.printobjectkindln();
119 }
120 memory m = x.as_memory();
121
122 l = used_length();
123 m.init(l, self.char_pointer);
124 m.cur_pointer() = cur_pointer();
125}
126
127ostream& memory::print(ostream& ost)
128{
129 if (self.char_pointer == NULL) {
130 ost << "memory not allocated";
131 }
132 cout << "memory, used_length=" << used_length()
133 << ", alloc_length=" << alloc_length()
134 << ", cur_pointer=" << cur_pointer() << endl;
135 return ost;
136}
137
138void memory::init(int length, char *d)
139{
140 int i;
141
142 alloc(length);
143 for (i = 0; i < length; i++) {
144 s_i(i) = d[i];
145 }
146}
147
148void memory::alloc(int length)
149// sets alloc_length to length + MEM_OVERSIZE,
150// sets used_length to length,
151// sets cur_pointer to 0.
152{
153 int size, mem_oversize;
154 int *pi;
155
156#ifdef DEBUG_MEM
157 cout << "memory::alloc()" << endl;
158#endif
159 if (length >= MEM_OVERSIZE) {
160 mem_oversize = MEM_OVERSIZE1;
161 }
162 else {
163 mem_oversize = MEM_OVERSIZE;
164 }
166 size = length + mem_oversize + 3 * sizeof(int);
167#ifdef DEBUG_MEM
168 cout << "memory::alloc() allocating " << size << " chars" << endl;
169#endif
170
171 pi = (int *) new char[size];
172 if (pi == NULL) {
173 cout << "memoy::alloc() out of memory" << endl;
174 exit(1);
175 }
176 self.char_pointer = (char *) (pi + 3);
177#ifdef DEBUG_MEM
178 cout << "memory::alloc() setting alloc_length()" << endl;
179#endif
180 alloc_length() = length + mem_oversize;
181 used_length() = length;
182 cur_pointer() = 0;
183 c_kind(MEMORY);
184#ifdef DEBUG_MEM
185 cout << "memory::alloc() " << used_length() << " chars allocated." << endl;
186#endif
187}
188
189void memory::append(int length, char *d)
190{
191 char *pc;
192 int i, old_length, new_length;
193
194 old_length = used_length();
195 new_length = old_length + length;
196 if (new_length > alloc_length()) {
197 realloc(new_length);
198 }
199 else {
200 used_length() = new_length;
201 }
202 pc = self.char_pointer;
203 for (i = 0; i < length; i++) {
204 pc[old_length + i] = d[i];
205 }
206}
207
208void memory::realloc(int new_length)
209{
210 int old_length;
211 int old_cur_pointer;
212 int i;
213 char *old_pc, *pc;
214 int *old_pi;
215
216 old_pc = self.char_pointer;
217 old_pi = (int *)old_pc - 3;
218 old_length = used_length();
219 old_cur_pointer = cur_pointer();
220 if (new_length < old_length) {
221 cout << "memory::realloc() warning: new_length < old_length" << endl;
222 }
223 self.char_pointer = NULL;
224 alloc(new_length);
225 pc = self.char_pointer;
226 for (i = 0;
227 i < MINIMUM(old_length, new_length);
228 i++) {
229 pc[i] = old_pc[i];
230 }
231 for (i = old_length; i < new_length; i++) {
232 pc[i] = 0;
233 }
234 delete [] old_pi;
235 cur_pointer() = old_cur_pointer;
236#ifdef DEBUG_MEM
237 cout << "memory::realloc() to " << used_length() << " chars" << endl;
238#endif
239}
240
242{
243#ifdef DEBUG_WRITE_CHAR
244 cout << "memory::write_char(), at " << used_length() << ", writing char " << (int) c << endl;
245#endif
246 append(1, &c);
247}
248
249void memory::read_char(char *c)
250{
251 int l1, cur_p, l;
252 char *cp;
253
254 cur_p = cur_pointer();
255 l = used_length();
256 l1 = l - cur_p;
257 if (l1 < 1) {
258 cout << "memory::read_char() error: l1 < 1" << endl;
259 exit(1);
260 }
261 cp = self.char_pointer + cur_p;
262 *c = *cp;
263#ifdef DEBUG_WRITE_CHAR
264 cout << "memory::read_char(), at " << cur_pointer() << ", reading char " << (int) c << endl;
265#endif
266 cur_pointer()++;
267}
268
270{
271 int_4 i1 = (int_4) i;
273
274#ifdef DEBUG_WRITE_int
275 cout << "memory::write_int(), at " << used_length() << ", writing int " << i1 << endl;
276#endif
277 Os.block_swap_chars((char *) &i1, 4, 1);
278 append(4, (char *) &i1);
279}
280
282{
283 int_4 i1;
284 int l1, j, cur_p, l;
285 char *cp, *cp1;
287
288 cur_p = cur_pointer();
289 l = used_length();
290 l1 = l - cur_p;
291 if (l1 < 4) {
292 cout << "memory::read_int() error: l1 < 4" << endl;
293 exit(1);
294 }
295 cp = self.char_pointer + cur_p;
296 cp1 = (char *) &i1;
297 for (j = 0; j < 4; j++) {
298 *cp1 = *cp;
299 cp1++;
300 cp++;
301 }
302 /* i1 = *(int *) (cp + cur_p); */
303 Os.block_swap_chars((char *) &i1, 4, 1);
304#ifdef DEBUG_WRITE_int
305 cout << "memory::read_int(), at " << cur_pointer() << ", reading " << i1 << endl;
306#endif
307 cur_pointer() = cur_p + 4;
308 *i = (int) i1;
309}
310
311#include <cstdio>
312
313void memory::read_file(char *fname, int verbose_level)
314{
315 int f_v = (verbose_level >= 1);
316 FILE *fp;
317 int fsize;
318 char *pc;
320
321 fsize = Fio.file_size(fname);
322 alloc(fsize);
323 pc = self.char_pointer;
324 fp = fopen(fname, "r");
325 if ((int) fread(pc, 1 /* size */, fsize /* nitems */, fp) != fsize) {
326 cout << "memory::read_file() error in fread" << endl;
327 }
328 fclose(fp);
329 used_length() = fsize;
330 cur_pointer() = 0;
331 if (f_v) {
332 cout << "memory::read_file() read file "
333 << fname << " of size " << fsize << endl;
334 }
335}
336
337void memory::write_file(char *fname, int verbose_level)
338{
339 int f_v = (verbose_level >= 1);
340 FILE *fp;
341 int size;
342 char *pc;
344
345 size = used_length();
346 pc = self.char_pointer;
347
348 fp = fopen(fname, "wb");
349
350 fwrite(pc, 1 /* size */, size /* items */, fp);
351
352 fclose(fp);
353 if (Fio.file_size(fname) != size) {
354 cout << "memory::write_file() error: file_size(fname) != size" << endl;
355 exit(1);
356 }
357 if (f_v) {
358 cout << "memory::write_file() wrote file "
359 << fname << " of size " << size << endl;
360 }
361}
362
364{
365 char *pc;
366 int i, l = 0, len;
367
368 pc = self.char_pointer;
369 len = used_length();
370 for (i = 0; i < len; i++)
371 if (pc[i] == c)
372 l++;
373 return l;
374}
375
376static void code(uchar *pc, int l, uchar *pc2, uchar code_char);
377static int decode(uchar *pc2, int l2, uchar *pc, uchar code_char);
378
379static void code(uchar *pc, int l, uchar *pc2, uchar code_char)
380/* Wolfgang Boessenecker 940919 */
381{
382 uchar cc;
383 int pos = 0, pos2 = 0, pos2h = 0, i;
384
385 while (pos < l) {
386 pos2++;
387 cc = 0;
388#if 0
389 if ((posf % 100000) == 0) {
390 cout << posf << endl;
391 }
392#endif
393 for (i = 0; i < 8; i++) {
394 cc <<= 1;
395 if (pos < l) {
396 if (pc[pos] == code_char)
397 cc = cc | 0X1U;
398 else {
399 pc2[pos2] = pc[pos];
400 pos2++;
401 }
402 pos++;
403 }
404 }
405 pc2[pos2h] = cc;
406 pos2h = pos2;
407 }
408}
409
410static int decode(uchar *pc2, int l2, uchar *pc, uchar code_char)
411// returns length of decompressed data
412// pc may be NULL */
413{
414 uchar cc = 0;
415 int pos = 0, pos2 = 0, i = 8;
416
417 while (TRUE) {
418 /* for (; pos2 < l2; ) { */
419 if (pos2 >= l2 && i >= 8)
420 break;
421 if (i == 8) {
422 cc = pc2[pos2];
423 pos2++;
424 i = 0;
425 }
426 if (cc & (uchar) 128U) {
427 if (pc) {
428 pc[pos] = code_char;
429 }
430 pos++;
431 }
432 else {
433 if (pos2 < l2) {
434 if (pc) {
435 pc[pos] = pc2[pos2];
436 }
437 pos2++;
438 pos++;
439 }
440 }
441 cc <<= 1;
442 i++;
443 }
444 return pos;
445}
446
447void memory::compress(int f_v)
448// Wolfgang Boessenecker 9/94
449{
450 memory mem2;
451 char *pc, *pc2;
452 int l, l2, l_c;
453
454 pc = self.char_pointer;
455 l = used_length();
456 if (f_v) {
457 cout << "compressing from " << l << " to ";
458 }
459 l_c = multiplicity_of_character((char) 0);
460 l2 = l - l_c + ((l + 7) >> 3);
461 mem2.alloc(l2); // sets used_length to l2
462 pc2 = mem2.self.char_pointer;
463 code((uchar *) pc, l, (uchar *) pc2, (uchar) 0);
464#if 0
465 if (l3 != l2) {
466 cout << "memory::compress() warning: l2 = " << l2 << " != l3 = " << l3 << endl;
467 }
468#endif
469 swap(mem2);
470 if (f_v) {
471 cout << l2 << " chars." << endl;
472 print(cout);
473 }
474}
475
477{
478 memory mem;
479 char *pc, *pc2;
480 int l, l2;
481
482 pc2 = self.char_pointer;
483 l2 = used_length();
484 if (f_v) {
485 cout << "decompressing from " << l2 << " to ";
486 }
487 l = decode((uchar *) pc2, l2, NULL, (uchar) 0);
488 mem.alloc(l);
489 pc = mem.self.char_pointer;
490 decode((uchar *) pc2, l2, (uchar *) pc, (uchar) 0);
491 swap(mem);
492 if (f_v) {
493 cout << l << " chars." << endl;
494 }
495}
496
498{
499 int l;
500 int size = 0;
501
502 l = used_length();
503 size += 4; /* l */
504 size += l;
505 return size;
506}
507
508void memory::write_mem(memory & M, int debug_depth)
509{
510 int i, l, a;
511
512 l = used_length();
513 M.write_int(l);
514 for (i = 0; i < l; i++) {
515 a = s_i(i);
516 M.write_char((char) a);
517 }
518}
519
520void memory::read_mem(memory & M, int debug_depth)
521{
522 int i, l;
523 char c;
524 char *mem;
525
526 M.read_int(&l);
527 mem = new char[l];
528
529 for (i = 0; i < l; i++) {
530 M.read_char(&c);
531 mem[i] = c;
532 }
533 M.init(l, mem);
534 delete [] mem;
535}
536
537}}
538
539
DISCRETA base class. All DISCRETA classes are derived from this class.
Definition: discreta.h:382
void swap(discreta_base &a)
Definition: base.cpp:179
void copyobject(discreta_base &x)
Definition: base.cpp:194
DISCRETA class to serialize data structures.
Definition: discreta.h:582
void copyobject_to(discreta_base &x)
Definition: memory.cpp:105
int multiplicity_of_character(char c)
Definition: memory.cpp:363
void realloc(int new_length)
Definition: memory.cpp:208
void append(int length, char *d)
Definition: memory.cpp:189
void read_mem(memory &M, int debug_depth)
Definition: memory.cpp:520
void write_mem(memory &M, int debug_depth)
Definition: memory.cpp:508
memory & operator=(const discreta_base &x)
Definition: memory.cpp:52
void read_file(char *fname, int verbose_level)
Definition: memory.cpp:313
std::ostream & print(std::ostream &ost)
Definition: memory.cpp:127
void write_file(char *fname, int verbose_level)
Definition: memory.cpp:337
void init(int length, char *d)
Definition: memory.cpp:138
#define MINIMUM(x, y)
Definition: foundations.h:216
unsigned char uchar
Definition: foundations.h:204
int int_4
Definition: foundations.h:181
#define TRUE
Definition: foundations.h:231
#define MEM_OVERSIZE
Definition: memory.cpp:22
#define MEM_OVERSIZE1
Definition: memory.cpp:23
the orbiter library for the classification of combinatorial objects
DISCRETA internal class.
Definition: discreta.h:353