Orbiter 2022
Combinatorial Objects
memory_object.cpp
Go to the documentation of this file.
1// memory_object.cpp
2//
3// Anton Betten
4// October 6, 2013
5//
6//
7// originally started April 4, 2000
8// moved from D2 to ORBI Nov 15, 2007
9
10#include "foundations.h"
11
12using namespace std;
13
14
15namespace orbiter {
16namespace layer1_foundations {
17namespace orbiter_kernel_system {
18
19
20
21//
22//
23// alloc_length: allocated length in chars
24// used_length: used length in charS
25// cur_pointer:
26// 0 <= pointer < used length.
27//
28
29
30
32{
33 data = NULL;
34 alloc_length = 0;
35 used_length = 0;
36 cur_pointer = 0;
37}
38
40{
41 freeself();
42}
43
45{
46 data = NULL;
47}
48
50{
51 if (data) {
53 }
54 null();
55}
56
57void memory_object::init(long int length,
58 char *initial_data, int verbose_level)
59{
60 int f_v = (verbose_level >= 1);
61 int i;
62
63 if (f_v) {
64 cout << "memory_object::init" << endl;
65 }
66 alloc(length, verbose_level - 1);
67 for (i = 0; i < length; i++) {
68 data[i] = initial_data[i];
69 }
70 used_length = length;
71 cur_pointer = 0;
72 if (f_v) {
73 cout << "memory_object::init done" << endl;
74 }
75}
76
77void memory_object::alloc(long int length, int verbose_level)
78// sets alloc_length to length
79{
80 int f_v = (verbose_level >= 1);
81
82 if (f_v) {
83 cout << "memory_object::alloc "
84 "length=" << length << endl;
85 }
86 //freeself();
87
88 data = NEW_char(length);
89 if (data == NULL) {
90 cout << "memory_object::alloc "
91 "out of memory" << endl;
92 exit(1);
93 }
94 alloc_length = length;
95 //used_length = length;
96 //cur_pointer = 0;
97
98 if (f_v) {
99 cout << "memory_object::alloc done" << endl;
100 }
101}
102
103void memory_object::append(long int length,
104 char *d, int verbose_level)
105{
106 int f_v = (verbose_level >= 1);
107 long int i, old_length, new_length, new_alloc_length;
108
109 if (f_v) {
110 cout << "memory_object::append" << endl;
111 cout << "used_length=" << endl;
112 cout << "alloc_length=" << alloc_length << endl;
113 }
114 old_length = used_length;
115 new_length = old_length + length;
116 if (new_length > alloc_length) {
117 if (f_v) {
118 cout << "memory_object::append before realloc" << endl;
119 }
120 new_alloc_length = MAXIMUM(new_length, 2 * alloc_length);
121 realloc(new_alloc_length, verbose_level);
122 if (f_v) {
123 cout << "memory_object::append after realloc" << endl;
124 }
125 }
126 for (i = 0; i < length; i++) {
127 data[old_length + i] = d[i];
128 }
129 used_length = old_length + length;
130 if (f_v) {
131 cout << "memory_object::append done" << endl;
132 }
133}
134
135void memory_object::realloc(long int &new_length, int verbose_level)
136{
137 int f_v = (verbose_level >= 1);
138 long int old_length;
139 long int old_cur_pointer;
140 long int i;
141 char *old_data;
142
143 if (f_v) {
144 cout << "memory_object::realloc "
145 "old_length=" << used_length <<
146 " new_length=" << new_length << endl;
147 }
148 old_data = data;
149 old_length = used_length;
150 old_cur_pointer = cur_pointer;
151 if (new_length < old_length) {
152 cout << "memory_object::realloc error: "
153 "new_length < old_length" << endl;
154 exit(1);
155 }
156 if (new_length < 2 * old_length) {
157 new_length = 2 * old_length;
158 // this is so that we don't get bogged down
159 // in many small increments
160 // which lead to slow performance because
161 // we need to copy the data over each time we reallocate
162 }
163 if (f_v) {
164 cout << "memory_object::realloc "
165 "old_length=" << used_length <<
166 " adjusted new_length=" << new_length << endl;
167 }
168 data = NULL;
169 alloc(new_length, verbose_level - 1);
170 for (i = 0;
171 i < MINIMUM(old_length, new_length);
172 i++) {
173 data[i] = old_data[i];
174 }
175 for (i = old_length; i < new_length; i++) {
176 data[i] = 0;
177 }
178 FREE_char(old_data);
179 cur_pointer = old_cur_pointer;
180
181
182 if (f_v) {
183 cout << "memory_object::realloc done "
184 " used_length=" << used_length << endl;
185 }
186 if (f_v) {
187 cout << "memory_object::realloc done" << endl;
188 }
189}
190
192{
193 append(1, &c, 0);
194}
195
197{
198 long int l1, cur_p, l;
199 char *cp;
200
201 cur_p = cur_pointer;
202 l = used_length;
203 l1 = l - cur_p;
204 if (l1 < 0) {
205 cout << "memory_object::read_char "
206 "error: l1 < 0" << endl;
207 cout << "cur_pointer=" << cur_pointer << endl;
208 cout << "used_length=" << used_length << endl;
209 cout << "l1=" << l1 << endl;
210 exit(1);
211 }
212 cp = data + cur_p;
213 *c = *cp;
214 cur_pointer++;
215}
216
218{
219 int l, i;
220
221 l = strlen(p);
222 for (i = 0; i < l; i++) {
223 write_char(p[i]);
224 }
225 write_char(0);
226}
227
229{
230 char *q;
231 char c;
232 long int alloc_length;
233 long int used_length;
234 int i;
235
236 alloc_length = 1024;
237 used_length = 0;
239
240 while (TRUE) {
241 read_char(&c);
242 if (used_length == alloc_length) {
243 long int new_alloc_length = 2 * alloc_length;
244 char *q1;
245
246 q1 = NEW_char(new_alloc_length);
247 for (i = 0; i < used_length; i++) {
248 q1[i] = q[i];
249 }
250 FREE_char(q);
251 q = q1;
252 alloc_length = new_alloc_length;
253 }
254 q[used_length++] = c;
255 if (c == 0) {
256 break;
257 }
258 }
259 // now used_length = strlen(q) + 1
260
261 // copy the result over. This gets rid of the overhead:
263 strcpy(p, q);
264
265 FREE_char(q);
266}
267
269{
270 append(sizeof(double), (char *) &f, 0);
271}
272
274{
275 double f1;
276 long int l1, j, cur_p, l;
277 char *cp, *cp1;
278
279 cur_p = cur_pointer;
280 l = used_length;
281 l1 = l - cur_p;
282 if (l1 < (int)sizeof(double)) {
283 cout << "memory_object::read_int "
284 "error: l1 < sizeof(double)" << endl;
285 exit(1);
286 }
287 cp = data + cur_p;
288 cp1 = (char *) &f1;
289 for (j = 0; j < (int)sizeof(double); j++) {
290 *cp1 = *cp;
291 cp1++;
292 cp++;
293 }
294 cur_pointer += sizeof(double);
295 *f = f1;
296}
297
299{
300 //block_swap_chars((char *) &i, 8, 1);
301 append(sizeof(long int), (char *) &i, 0);
302}
303
305{
306 long int i1;
307 long int l1, j, cur_p, l;
308 char *cp, *cp1;
309
310 cur_p = cur_pointer;
311 l = used_length;
312 l1 = l - cur_p;
313 if (l1 < sizeof(long int)) {
314 cout << "memory_object::read_int "
315 "error: l1 < sizeof(long int)" << endl;
316 exit(1);
317 }
318 cp = data + cur_p;
319 cp1 = (char *) &i1;
320 for (j = 0; j < sizeof(long int); j++) {
321 *cp1 = *cp;
322 cp1++;
323 cp++;
324 }
325 //block_swap_chars((char *) &i1, 8, 1);
326 cur_pointer += sizeof(long int);
327 *i = i1;
328}
329
331{
332 os_interface Os;
333 int_4 i1 = (int_4) i;
334
335 Os.block_swap_chars((char *) &i1, sizeof(int), 1);
336 append(sizeof(int), (char *) &i1, 0);
337}
338
340{
341 int f_v = FALSE;
342 int_4 i1;
343 long int l1, j, cur_p, l;
344 char *cp, *cp1;
345 os_interface Os;
346
347 if (f_v) {
348 cout << "memory_object::read_int" << endl;
349 }
350 cur_p = cur_pointer;
351 l = used_length;
352 l1 = l - cur_p;
353 if (l1 < sizeof(int)) {
354 cout << "memory_object::read_int "
355 "error: l1 < sizeof(int)" << endl;
356 exit(1);
357 }
358 cp = data + cur_p;
359 cp1 = (char *) &i1;
360 for (j = 0; j < sizeof(int); j++) {
361 *cp1 = *cp;
362 cp1++;
363 cp++;
364 }
365 if (f_v) {
366 cout << "memory_object::read_int before swap: i1 = " << i1 << endl;
367 }
368 Os.block_swap_chars((char *) &i1, sizeof(int), 1);
369 if (f_v) {
370 cout << "memory_object::read_int after swap: i1 = " << i1 << endl;
371 }
372 cur_pointer += sizeof(int);
373 if (f_v) {
374 cout << "memory_object::read_int "
375 "done read " << i1 << endl;
376 }
377 *i = (int) i1;
378}
379
380#include <cstdio>
381
382void memory_object::read_file(const char *fname, int verbose_level)
383{
384 int f_v = (verbose_level >= 1);
385 long int fsize;
386 file_io Fio;
387
388 if (f_v) {
389 cout << "memory_object::read_file" << endl;
390 }
391 fsize = Fio.file_size(fname);
392 alloc(fsize, 0);
393
394#if 0
395 FILE *fp;
396 fp = fopen(fname, "r");
397 if ((int) fread(data,
398 1 /* size */, fsize /* nitems */, fp) != fsize) {
399 cout << "memory_object::read_file "
400 "error in fread" << endl;
401 }
402 fclose(fp);
403#else
404 {
405 ifstream fp(fname, ios::binary);
406 fp.read(data, fsize);
407 }
408#endif
409 used_length = fsize;
410 cur_pointer = 0;
411 if (f_v) {
412 cout << "memory_object::read_file read file "
413 << fname << " of size " << fsize << endl;
414 }
415}
416
417void memory_object::write_file(const char *fname, int verbose_level)
418{
419 int f_v = (verbose_level >= 1);
420 file_io Fio;
421
422 if (f_v) {
423 cout << "memory_object::write_file" << endl;
424 }
425
426#if 0
427 long int size;
428 size = used_length;
429 FILE *fp;
430 fp = fopen(fname, "wb");
431
432 fwrite(data, 1 /* size */, size /* items */, fp);
433
434 fclose(fp);
435#else
436 {
437 ofstream fp(fname, ios::binary);
438 fp.write(data, used_length);
439 }
440#endif
441 if (Fio.file_size(fname) != used_length) {
442 cout << "memory_object::write_file error "
443 "file_size(fname) != used_length" << endl;
444 exit(1);
445 }
446 if (f_v) {
447 cout << "memory_object::write_file written file "
448 << fname << " of size " << used_length << endl;
449 }
450}
451
453{
454 int i, l;
455
456 l = 0;
457 for (i = 0; i < used_length; i++) {
458 if (data[i] == c) {
459 l++;
460 }
461 }
462 return l;
463}
464
465#if 0
466static void code(uchar *pc, int l, uchar *pc2, uchar code_char);
467static int decode(uchar *pc2, int l2, uchar *pc, uchar code_char);
468
469static void code(uchar *pc, int l, uchar *pc2, uchar code_char)
470/* Wolfgang Boessenecker 940919 */
471{
472 uchar cc;
473 int pos = 0, pos2 = 0, pos2h = 0, i;
474
475 while (pos < l) {
476 pos2++;
477 cc = 0;
478#if 0
479 if ((posf % 100000) == 0) {
480 cout << posf << endl;
481 }
482#endif
483 for (i = 0; i < 8; i++) {
484 cc <<= 1;
485 if (pos < l) {
486 if (pc[pos] == code_char)
487 cc = cc | 0X1U;
488 else {
489 pc2[pos2] = pc[pos];
490 pos2++;
491 }
492 pos++;
493 }
494 }
495 pc2[pos2h] = cc;
496 pos2h = pos2;
497 }
498}
499
500static int decode(uchar *pc2, int l2, uchar *pc, uchar code_char)
501// returns the length of the data after decompression
502// pc may be NULL
503{
504 uchar cc = 0;
505 int pos = 0, pos2 = 0, i = 8;
506
507 while (TRUE) {
508 /* for (; pos2 < l2; ) { */
509 if (pos2 >= l2 && i >= 8)
510 break;
511 if (i == 8) {
512 cc = pc2[pos2];
513 pos2++;
514 i = 0;
515 }
516 if (cc & (uchar) 128U) {
517 if (pc) {
518 pc[pos] = code_char;
519 }
520 pos++;
521 }
522 else {
523 if (pos2 < l2) {
524 if (pc) {
525 pc[pos] = pc2[pos2];
526 }
527 pos2++;
528 pos++;
529 }
530 }
531 cc <<= 1;
532 i++;
533 }
534 return pos;
535}
536
537void memory_object::compress(int verbose_level)
538// Wolfgang Boessenecker 9/94
539{
540 int f_v = (verbose_level >= 1);
541 memory_object mem2;
542 int l, l2, l_c;
543
544 l = used_length;
545 if (f_v) {
546 cout << "memory_object::compress compressing " << l << " chars";
547 }
548 l_c = multiplicity_of_character((char) 0);
549 l2 = l - l_c + ((l + 7) >> 3);
550 mem2.alloc(l2, 0); // sets used_length to l2
551 code((uchar *) char_pointer, l, (uchar *) mem2.char_pointer, (uchar) 0);
552#if 0
553 if (l3 != l2) {
554 cout << "memory_object::compress "
555 "warning: l2 = " << l2 << " != l3 = " << l3 << endl;
556 }
557#endif
558 freeself();
559 char_pointer = mem2.char_pointer;
560 cur_pointer = 0;
561 used_length = mem2.used_length;
562 alloc_length = mem2.alloc_length;
563 mem2.null();
564 if (f_v) {
565 cout << "memory_object::compress "
566 "compressed from " << l << " to " << l2 << " chars." << endl;
567 }
568}
569
570void memory_object::decompress(int verbose_level)
571{
572 int f_v = (verbose_level >= 1);
573 memory_object mem2;
574 int l, l2;
575
576 l2 = used_length;
577 if (f_v) {
578 cout << "memory_object::decompress "
579 "decompressing from " << l2 << " chars";
580 }
581 l = decode((uchar *) char_pointer, l2, NULL, (uchar) 0);
582 mem2.alloc(l, 0);
583 decode((uchar *) char_pointer, l2, (uchar *) mem2.char_pointer, (uchar) 0);
584 freeself();
585 char_pointer = mem2.char_pointer;
586 cur_pointer = 0;
587 used_length = mem2.used_length;
588 alloc_length = mem2.alloc_length;
589 mem2.null();
590
591 if (f_v) {
592 cout << "memory_object::decompress "
593 "decompressing from " << l2 << " to ";
594 cout << l << " chars." << endl;
595 }
596}
597#endif
598
599
600}}}
601
602
void init(long int length, char *initial_data, int verbose_level)
void append(long int length, char *d, int verbose_level)
void realloc(long int &new_length, int verbose_level)
#define MINIMUM(x, y)
Definition: foundations.h:216
unsigned char uchar
Definition: foundations.h:204
#define NEW_char(n)
Definition: foundations.h:632
int int_4
Definition: foundations.h:181
#define TRUE
Definition: foundations.h:231
#define FALSE
Definition: foundations.h:234
#define FREE_char(p)
Definition: foundations.h:646
#define MAXIMUM(x, y)
Definition: foundations.h:217
the orbiter library for the classification of combinatorial objects