~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/Buffer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// ---------------------------------------------------------------------------
 
2
// - Buffer.cpp                                                              -
 
3
// - standard object library - character buffer class implementation         -
 
4
// ---------------------------------------------------------------------------
 
5
// - This program is free software;  you can redistribute it  and/or  modify -
 
6
// - it provided that this copyright notice is kept intact.                  -
 
7
// -                                                                         -
 
8
// - This program  is  distributed in  the hope  that it will be useful, but -
 
9
// - without  any  warranty;  without  even   the   implied    warranty   of -
 
10
// - merchantability or fitness for a particular purpose.  In no event shall -
 
11
// - the copyright holder be liable for any  direct, indirect, incidental or -
 
12
// - special damages arising in any way out of the use of this software.     -
 
13
// ---------------------------------------------------------------------------
 
14
// - copyright (c) 1999-2011 amaury darsch                                   -
 
15
// ---------------------------------------------------------------------------
 
16
 
 
17
#include "Byte.hpp"
 
18
#include "Ascii.hpp"
 
19
#include "Vector.hpp"
 
20
#include "Buffer.hpp"
 
21
#include "System.hpp"
 
22
#include "Utility.hpp"
 
23
#include "Unicode.hpp"
 
24
#include "Integer.hpp"
 
25
#include "Boolean.hpp"
 
26
#include "QuarkZone.hpp"
 
27
#include "Exception.hpp"
 
28
#include "ccnv.hpp"
 
29
 
 
30
namespace afnix {
 
31
 
 
32
  // -------------------------------------------------------------------------
 
33
  // - public section                                                        -
 
34
  // -------------------------------------------------------------------------
 
35
 
 
36
  // generate a random buffer
 
37
 
 
38
  Buffer Buffer::random (const long size) {
 
39
    // check for valid size
 
40
    if (size < 0) {
 
41
      throw Exception ("size-error", "invalid random number size");
 
42
    }
 
43
    // create a buffer by size
 
44
    Buffer result (size);
 
45
    // fill it with random bytes
 
46
    for (long i = 0; i < size; i++) {
 
47
      result.add ((char) Utility::byternd ());
 
48
    }
 
49
    // here it is
 
50
    return result;
 
51
  }
 
52
  
 
53
  // -------------------------------------------------------------------------
 
54
  // - class section                                                         -
 
55
  // -------------------------------------------------------------------------
 
56
 
 
57
  // create a new buffer class with a default size of 1024 characters
 
58
 
 
59
  Buffer::Buffer (void) {
 
60
    d_size = System::blocksz ();
 
61
    p_data = new char [d_size];
 
62
    d_blen = 0;
 
63
    d_rflg = true;
 
64
    d_emod = Encoding::BYTE;
 
65
  }
 
66
 
 
67
  // create a new buffer with a predefined size
 
68
 
 
69
  Buffer::Buffer (const long size) {
 
70
    d_size = (size <= 0) ? System::blocksz () : size;
 
71
    p_data = new char[d_size];
 
72
    d_blen = 0;
 
73
    d_rflg = true;
 
74
    d_emod = Encoding::BYTE;
 
75
  }
 
76
 
 
77
  // create a new buffer by mode
 
78
 
 
79
  Buffer::Buffer (const Encoding::t_emod emod) {
 
80
    d_size = System::blocksz ();
 
81
    p_data = new char[d_size];
 
82
    d_blen = 0;
 
83
    d_rflg = true;
 
84
    d_emod = emod;
 
85
  }
 
86
 
 
87
  // create a new buffer by size with a mode
 
88
 
 
89
  Buffer::Buffer (const long size, const Encoding::t_emod emod) {
 
90
    d_size = (size <= 0) ? System::blocksz () : size;
 
91
    p_data = new char[d_size];
 
92
    d_blen = 0;
 
93
    d_rflg = true;
 
94
    d_emod = emod;
 
95
  }
 
96
 
 
97
  // create a new buffer and initialize it with a c string
 
98
 
 
99
  Buffer::Buffer (const char* value) {
 
100
    d_size = System::blocksz ();
 
101
    p_data = new char[d_size];
 
102
    d_blen = 0;
 
103
    d_rflg = true;
 
104
    d_emod = Encoding::UTF8;
 
105
    add (value, Ascii::strlen (value));
 
106
  }
 
107
 
 
108
  // create a new buffer and initialize it with a string
 
109
 
 
110
  Buffer::Buffer (const String& value) {
 
111
    d_size = System::blocksz ();
 
112
    p_data = new char[d_size];
 
113
    d_blen = 0;
 
114
    d_rflg = true;
 
115
    d_emod = Encoding::UTF8;
 
116
    add (value);
 
117
  }
 
118
 
 
119
  // copy construct a buffer
 
120
 
 
121
  Buffer::Buffer (const Buffer& that) {
 
122
    that.rdlock ();
 
123
    try {
 
124
      d_size = that.d_size;
 
125
      d_blen = 0;
 
126
      d_rflg = that.d_rflg;
 
127
      d_emod = that.d_emod;
 
128
      p_data = new char[d_size];
 
129
      add (that.p_data, that.d_blen);
 
130
      that.unlock ();
 
131
    } catch (...) {
 
132
      that.unlock ();
 
133
      throw;
 
134
    }
 
135
  }
 
136
 
 
137
  // destroy this buffer
 
138
  
 
139
  Buffer::~Buffer (void) {
 
140
    delete [] p_data;
 
141
  }
 
142
  
 
143
  // return the class name
 
144
 
 
145
  String Buffer::repr (void) const {
 
146
    return "Buffer";
 
147
  }
 
148
 
 
149
  // assign a buffer to this one
 
150
 
 
151
  Buffer& Buffer::operator = (const Buffer& that) {
 
152
    if (this == &that) return *this;
 
153
    wrlock ();
 
154
    that.rdlock ();
 
155
    try {
 
156
      // clean the old data
 
157
      delete [] p_data;
 
158
      p_data = nilp;
 
159
      d_blen = 0;
 
160
      // add the new data
 
161
      d_size = that.d_size;
 
162
      d_rflg = that.d_rflg;
 
163
      d_emod = that.d_emod;
 
164
      p_data = new char[d_size];
 
165
      add (that.p_data, that.d_blen);
 
166
      unlock ();
 
167
      that.unlock ();
 
168
      return *this;
 
169
    } catch (...) {
 
170
      unlock ();
 
171
      that.unlock ();
 
172
      throw;
 
173
    }
 
174
  }
 
175
 
 
176
  // return a clone of this object
 
177
 
 
178
  Object* Buffer::clone (void) const {
 
179
    return new Buffer (*this);
 
180
  }
 
181
 
 
182
  // reset this buffer but do not change the size
 
183
  
 
184
  void Buffer::reset (void) {
 
185
    wrlock ();
 
186
    try {
 
187
      d_blen = 0;
 
188
      unlock ();
 
189
    } catch (...) {
 
190
      unlock ();
 
191
      throw;
 
192
    }
 
193
  }
 
194
 
 
195
  // return the size of this buffer
 
196
  
 
197
  long Buffer::getsize (void) const {
 
198
    rdlock ();
 
199
    try {
 
200
      long result = d_size;
 
201
      unlock ();
 
202
      return result;
 
203
    } catch (...) {
 
204
      unlock ();
 
205
      throw;
 
206
    }
 
207
  }
 
208
 
 
209
  // return the length of this buffer
 
210
  
 
211
  long Buffer::length (void) const {
 
212
    rdlock ();
 
213
    try {
 
214
      long result = d_blen;
 
215
      unlock ();
 
216
      return result;
 
217
    } catch (...) {
 
218
      unlock ();
 
219
      throw;
 
220
    }
 
221
  }
 
222
 
 
223
  // set the buffer encoding mode
 
224
 
 
225
  void Buffer::setemod (const Encoding::t_emod emod) {
 
226
    wrlock ();
 
227
    try {
 
228
      d_emod = emod;
 
229
      unlock ();
 
230
    } catch (...) {
 
231
      unlock ();
 
232
      throw;
 
233
    }
 
234
  }
 
235
 
 
236
  // get the buffer encoding
 
237
 
 
238
  Encoding::t_emod Buffer::getemod (void) const {
 
239
    rdlock ();
 
240
    try {
 
241
      Encoding::t_emod result = d_emod;
 
242
      unlock ();
 
243
      return result;
 
244
    } catch (...) {
 
245
      unlock ();
 
246
      throw;
 
247
    }
 
248
  }
 
249
 
 
250
  // set the resize flag
 
251
 
 
252
  void Buffer::setrflg (const bool rflg) {
 
253
    wrlock ();
 
254
    try {
 
255
      d_rflg = rflg;
 
256
      unlock ();
 
257
    } catch (...) {
 
258
      unlock ();
 
259
      throw;
 
260
    }
 
261
  }
 
262
 
 
263
  // return the resize flag
 
264
 
 
265
  bool Buffer::getrflg (void) const {
 
266
    rdlock ();
 
267
    try {
 
268
      bool result = d_rflg;
 
269
      unlock ();
 
270
      return result;
 
271
    } catch (...) {
 
272
      unlock ();
 
273
      throw;
 
274
    }
 
275
  }
 
276
 
 
277
  // return true if the buffer is empty
 
278
 
 
279
  bool Buffer::empty (void) const {
 
280
    rdlock ();
 
281
    try {
 
282
      bool result = (d_blen == 0);
 
283
      unlock ();
 
284
      return result;
 
285
    } catch (...) {
 
286
      unlock ();
 
287
      throw;
 
288
    }
 
289
  }
 
290
 
 
291
  // return true if the buffer is full
 
292
 
 
293
  bool Buffer::full (void) const {
 
294
    rdlock ();
 
295
    try {
 
296
      bool result = d_rflg ? false : (d_blen >= d_size);
 
297
      unlock ();
 
298
      return result;
 
299
    } catch (...) {
 
300
      unlock ();
 
301
      throw;
 
302
    }
 
303
  }
 
304
 
 
305
  // add a character in this buffer
 
306
  
 
307
  long Buffer::add (const char value) {
 
308
    wrlock ();
 
309
    try {
 
310
      // first check if we are at the buffer end
 
311
      if (d_blen >= d_size) {
 
312
        if (d_rflg == true) {
 
313
          long size = d_size * 2;
 
314
          char* buf = new char[size];
 
315
          for (long i = 0; i < d_blen; i++) buf[i] = p_data[i];
 
316
          delete [] p_data;
 
317
          d_size   = size;
 
318
          p_data = buf;
 
319
        } else {
 
320
          unlock ();
 
321
          return 0;
 
322
        }
 
323
      }
 
324
      p_data[d_blen++] = value;
 
325
      unlock ();
 
326
      return 1;
 
327
    } catch (...) {
 
328
      unlock ();
 
329
      throw;
 
330
    }
 
331
  }
 
332
 
 
333
  // add a unicode character in the buffer
 
334
 
 
335
  long Buffer::add (const t_quad value) {
 
336
    wrlock ();
 
337
    char* cbuf = nilp;
 
338
    try {
 
339
      // get the character encoding
 
340
      cbuf = Unicode::encode (d_emod, value);
 
341
      long  size = Ascii::strlen (cbuf);
 
342
      // add the coding in the buffer
 
343
      long result = add (cbuf, size);
 
344
      // clean and unlock
 
345
      delete [] cbuf;
 
346
      unlock ();
 
347
      return result;
 
348
    } catch (...) {
 
349
      delete [] cbuf;
 
350
      unlock ();
 
351
      throw;
 
352
    }
 
353
  }
 
354
 
 
355
  // add a c-string in this buffer
 
356
 
 
357
  long Buffer::add (const char* s) {
 
358
    wrlock ();
 
359
    try {
 
360
      long size = Ascii::strlen (s);
 
361
      long result = add (s, size);
 
362
      unlock ();
 
363
      return result;
 
364
    } catch (...) {
 
365
      unlock ();
 
366
      throw;
 
367
    }
 
368
  }
 
369
 
 
370
  // add a character buffer in this buffer
 
371
  
 
372
  long Buffer::add (const char* cbuf, const long size) {
 
373
    if ((cbuf == nilp) || (size == 0)) return 0;
 
374
    wrlock ();
 
375
    try {
 
376
      long result = 0;
 
377
      for (long i = 0; i < size; i++) {
 
378
        result += add (cbuf[i]);
 
379
        if (full () == true) break;
 
380
      }
 
381
      unlock ();
 
382
      return result;
 
383
    } catch (...) {
 
384
      unlock ();
 
385
      throw;
 
386
    }
 
387
  }
 
388
 
 
389
  // add a string in this buffer
 
390
  
 
391
  long Buffer::add (const String& s) {
 
392
    wrlock ();
 
393
    char* cbuf = nilp;
 
394
    try {
 
395
      // encode the string
 
396
      cbuf = Unicode::encode (d_emod, s);
 
397
      long  size = Ascii::strlen (cbuf);
 
398
      // add the buffer
 
399
      long result = add (cbuf, size);
 
400
      // clean and unlock
 
401
      delete [] cbuf;
 
402
      unlock ();
 
403
      return result;
 
404
    } catch (...) {
 
405
      delete [] cbuf;
 
406
      unlock ();
 
407
      throw;
 
408
    }
 
409
  }
 
410
 
 
411
  // add a buffer object to this buffer
 
412
 
 
413
  long Buffer::add (const Buffer& buffer) {
 
414
    // do not add yourself
 
415
    if (this == &buffer) return 0;
 
416
    // lock and add
 
417
    wrlock ();
 
418
    buffer.rdlock ();
 
419
    try {
 
420
      long result = add (buffer.p_data, buffer.d_blen);
 
421
      buffer.unlock ();
 
422
      unlock ();
 
423
      return result;
 
424
    } catch (...) {
 
425
      buffer.unlock ();
 
426
      unlock ();
 
427
      throw;
 
428
    }
 
429
  }
 
430
  
 
431
  // read a character in this buffer
 
432
  
 
433
  char Buffer::read (void) {
 
434
    wrlock ();
 
435
    try {
 
436
      // check for no character
 
437
      if (d_blen == 0) {
 
438
        unlock ();
 
439
        return nilc;
 
440
      }
 
441
      // get value and shift
 
442
      char value = p_data[0];
 
443
      for (long i = 0; i < d_blen-1; i++) p_data[i] = p_data[i+1];
 
444
      d_blen--;
 
445
      unlock ();
 
446
      return value;
 
447
    } catch (...) {
 
448
      unlock ();
 
449
      throw;
 
450
    }
 
451
  }
 
452
 
 
453
  // get the next character but do not remove it
 
454
 
 
455
  char Buffer::get (void) const {
 
456
    rdlock ();
 
457
    try {
 
458
      char result = (d_blen == 0) ? nilc : p_data[0];
 
459
      unlock ();
 
460
      return result;
 
461
    } catch (...) {
 
462
      unlock ();
 
463
      throw;
 
464
    }
 
465
  }
 
466
 
 
467
  // get a character by index
 
468
 
 
469
  char Buffer::get (const long index) const {
 
470
    rdlock ();
 
471
    try {
 
472
      if ((index < 0) || (index >= d_blen)) {
 
473
        throw Exception ("range-error", "out-of-bound buffer index");
 
474
      }
 
475
      char result = p_data[index];
 
476
      unlock ();
 
477
      return result;
 
478
    } catch (...) {
 
479
      unlock ();
 
480
      throw;
 
481
    }
 
482
  }
 
483
 
 
484
  // shift the buffer by a certain amount
 
485
 
 
486
  void Buffer::shl (const long asl) {
 
487
    wrlock ();
 
488
    try {
 
489
      // check for amount
 
490
      if (asl < d_blen) {
 
491
        // shift the old buffer
 
492
        long  blen = d_blen - asl;
 
493
        long  size = d_rflg ? d_size : blen;
 
494
        char* data = new char[size];
 
495
        for (long i = asl; i < d_blen; i++) data[i-asl] = p_data[i];
 
496
        // adjust indexes
 
497
        delete [] p_data;
 
498
        d_size = size;
 
499
        d_blen = blen;
 
500
        p_data = data;
 
501
      } else {
 
502
        d_blen = 0;
 
503
      }
 
504
      unlock ();
 
505
    } catch (...) {
 
506
      unlock ();
 
507
      throw;
 
508
    }
 
509
  }
 
510
 
 
511
  // read a line from this buffer
 
512
 
 
513
  String Buffer::readln (void) {
 
514
    wrlock ();
 
515
    try {
 
516
      // create a buffer to accumulate characters
 
517
      Buffer buf = d_emod;
 
518
      bool   flg = false;
 
519
      // read the character in the buffer
 
520
      while (empty () == false) {
 
521
        char c = read ();
 
522
        if (c == crlc) {
 
523
          flg = true;
 
524
          continue;
 
525
        }
 
526
        if (c == eolc) break;
 
527
        if (flg == true) {
 
528
          buf.add (crlc);
 
529
          flg = false;
 
530
        }
 
531
        buf.add (c);
 
532
      }
 
533
      unlock ();
 
534
      return buf.tostring ();
 
535
    } catch (...) {
 
536
      unlock ();
 
537
      throw;
 
538
    }
 
539
  }
 
540
  
 
541
  // pushback a character in this buffer
 
542
  
 
543
  long Buffer::pushback (const char value) {
 
544
    wrlock ();
 
545
    try {
 
546
      // check if we are full
 
547
      if (d_blen >= d_size) {
 
548
        if (d_rflg == true) {
 
549
          long size = d_size * 2;
 
550
          char* buf = new char[size];
 
551
          for (long i = 0; i < d_blen; i++) buf[i] = p_data[i];
 
552
          d_size = size;
 
553
          delete [] p_data;
 
554
          p_data = buf;
 
555
        } else {
 
556
          unlock ();
 
557
          return 0;
 
558
        }
 
559
      }
 
560
      // shift the buffer by one
 
561
      for (long i = d_blen; i > 0; i--) p_data[i] = p_data[i-1];
 
562
      p_data[0] = value;
 
563
      d_blen++;
 
564
      unlock ();
 
565
      return 1;
 
566
    } catch (...) {
 
567
      unlock ();
 
568
      throw;
 
569
    }
 
570
  }
 
571
 
 
572
  // pushback a unicode character in the buffer
 
573
 
 
574
  long Buffer::pushback (const t_quad value) {
 
575
    wrlock ();
 
576
    char* cbuf = nilp;
 
577
    try {
 
578
      // get the character encoding
 
579
      cbuf = Unicode::encode (d_emod, value);
 
580
      long size = Ascii::strlen (cbuf);
 
581
      // pushback the coding in the buffer
 
582
      pushback (cbuf, size);
 
583
      // clean and unlock
 
584
      delete [] cbuf;
 
585
      unlock ();
 
586
      return size;
 
587
    } catch (...) {
 
588
      delete [] cbuf;
 
589
      unlock ();
 
590
      throw;
 
591
    }
 
592
  }
 
593
 
 
594
  // pushback a character string to this buffer
 
595
 
 
596
  long Buffer::pushback (const char* s) {
 
597
    wrlock ();
 
598
    try {
 
599
      long   size = Ascii::strlen (s);
 
600
      long result = pushback (s, size);
 
601
      unlock ();
 
602
      return result;
 
603
    } catch (...) {
 
604
      unlock ();
 
605
      throw;
 
606
    }
 
607
  }
 
608
 
 
609
  // pushback a buffer in this buffer
 
610
  
 
611
  long Buffer::pushback (const char* s, const long size) {
 
612
    if ((s == nilp) || (size == 0)) return 0;
 
613
    wrlock ();
 
614
    try {
 
615
      long    len = size - 1;
 
616
      long result = 0;
 
617
      for (long i = len; i >= 0; i--) {
 
618
        result += pushback (s[i]);
 
619
        if (full () == true) break;
 
620
      }
 
621
      unlock ();
 
622
      return result;
 
623
    } catch (...) {
 
624
      unlock ();
 
625
      throw;
 
626
    }
 
627
  }
 
628
  
 
629
  // pushback a string in this buffer
 
630
  
 
631
  long Buffer::pushback (const String& value) {
 
632
    wrlock ();
 
633
    char* cbuf = nilp;
 
634
    try {
 
635
      // encode the string
 
636
      cbuf = Unicode::encode (d_emod, value);
 
637
      long  size = Ascii::strlen (cbuf);
 
638
      // pushback the string
 
639
      long result = pushback (cbuf, size);
 
640
      // clean and unlock
 
641
      delete [] cbuf;
 
642
      unlock ();
 
643
      return result;
 
644
    } catch (...) {
 
645
      delete [] cbuf;
 
646
      unlock ();
 
647
      throw;
 
648
    }
 
649
  }
 
650
 
 
651
  // pushback a buffer in this buffer
 
652
  
 
653
  long Buffer::pushback (const Buffer& buffer) {
 
654
    // do not pushback yourself
 
655
    if (this == &buffer) return 0;
 
656
    // lock and push
 
657
    wrlock ();
 
658
    buffer.rdlock ();
 
659
    try {
 
660
      long result = pushback (buffer.p_data, buffer.d_blen);
 
661
      buffer.unlock ();
 
662
      unlock ();
 
663
      return result;
 
664
    } catch (...) {
 
665
      buffer.unlock ();
 
666
      unlock ();
 
667
      throw;
 
668
    }
 
669
  }
 
670
 
 
671
  // return the corresponding string accumulated in this buffer
 
672
  
 
673
  String Buffer::tostring (void) const {
 
674
    rdlock ();
 
675
    try {
 
676
      // decode the buffer
 
677
      t_quad* sbuf = Unicode::decode (d_emod, p_data, d_blen);
 
678
      // map the result string
 
679
      String result = sbuf;
 
680
      // clean and return
 
681
      delete [] sbuf;
 
682
      unlock ();
 
683
      return result;
 
684
    } catch (...) {
 
685
      unlock ();
 
686
      throw;
 
687
    }
 
688
  }
 
689
 
 
690
  // format the buffer content as an octet string
 
691
 
 
692
  String Buffer::format (void) const {
 
693
    rdlock ();
 
694
    try {
 
695
      // format the string
 
696
      String result = Ascii::btos ((const t_byte*) p_data, d_blen);
 
697
      unlock ();
 
698
      return result;
 
699
    } catch (...) {
 
700
      unlock ();
 
701
      throw;
 
702
    } 
 
703
  }
 
704
 
 
705
  // map this buffer to an anonymous data structure
 
706
 
 
707
  long Buffer::tomap (void* data, const long size) const {
 
708
    rdlock ();
 
709
    try {
 
710
      // check for a null content
 
711
      if (d_blen == 0) {
 
712
        unlock ();
 
713
        return 0;
 
714
      }
 
715
      // process normal size
 
716
      long result = (size < d_blen) ? size : d_blen;
 
717
      char* ptr   = reinterpret_cast <char*> (data);
 
718
      // copy the buffer content
 
719
      for (long i = 0; i < result; i++) ptr[i] = p_data[i];
 
720
      // unlock and return
 
721
      unlock ();
 
722
      return result;
 
723
    } catch (...) {
 
724
      unlock ();
 
725
      throw;
 
726
    }
 
727
  }
 
728
 
 
729
  // add a word in natural format to this buffer
 
730
 
 
731
  void Buffer::addnw (const t_word wval) {
 
732
    wrlock ();
 
733
    try {
 
734
      add ((char) ((wval >> 8) & 0x00FFU));
 
735
      add ((char) (wval & 0x00FFU));
 
736
      unlock ();
 
737
    } catch (...) {
 
738
      unlock ();
 
739
      throw;
 
740
    }
 
741
  }
 
742
 
 
743
  // add a quad in natural format to this buffer
 
744
 
 
745
  void Buffer::addnq (const t_quad qval) {
 
746
    wrlock ();
 
747
    try {
 
748
      add ((char) ((qval >> 24) & 0x000000FFU));
 
749
      add ((char) ((qval >> 16) & 0x000000FFU));
 
750
      add ((char) ((qval >> 8)  & 0x000000FFU));
 
751
      add ((char) (qval & 0x000000FFU));
 
752
      unlock ();
 
753
    } catch (...) {
 
754
      unlock ();
 
755
      throw;
 
756
    }
 
757
  }
 
758
 
 
759
  // add an octa in natural format to this buffer
 
760
 
 
761
  void Buffer::addno (const t_octa oval) {
 
762
    wrlock ();
 
763
    try {
 
764
      add ((char) ((oval >> 56) & 0x00000000000000FFU));
 
765
      add ((char) ((oval >> 48) & 0x00000000000000FFU));
 
766
      add ((char) ((oval >> 40) & 0x00000000000000FFU));
 
767
      add ((char) ((oval >> 32) & 0x00000000000000FFU));
 
768
      add ((char) ((oval >> 24) & 0x00000000000000FFU));
 
769
      add ((char) ((oval >> 16) & 0x00000000000000FFU));
 
770
      add ((char) ((oval >> 8)  & 0x00000000000000FFU));
 
771
      add ((char) (oval & 0x00000000000000FFU));
 
772
      unlock ();
 
773
    } catch (...) {
 
774
      unlock ();
 
775
      throw;
 
776
    }
 
777
  }
 
778
 
 
779
  // get a word in natural format from this buffer
 
780
 
 
781
  t_word Buffer::getnw (void) {
 
782
    wrlock ();
 
783
    try {
 
784
      // check valid buffer size
 
785
      if (d_blen < 2) {
 
786
        throw Exception ("buffer-error", "small buffer size with getnw");
 
787
      }
 
788
      // prepare result
 
789
      t_word result = 0x0000U;
 
790
      // read and shift
 
791
      result |= (t_byte) read ();
 
792
      result <<= 8;
 
793
      result |= (t_byte) read ();
 
794
      // unlock and return
 
795
      unlock ();
 
796
      return result;
 
797
    } catch (...) {
 
798
      unlock ();
 
799
      throw;
 
800
    }
 
801
  }
 
802
 
 
803
  // get a quad in natural format from this buffer
 
804
 
 
805
  t_quad Buffer::getnq (void) {
 
806
    wrlock ();
 
807
    try {
 
808
      // check valid buffer size
 
809
      if (d_blen < 4) {
 
810
        throw Exception ("buffer-error", "small buffer size with getnq");
 
811
      }
 
812
      // prepare result
 
813
      t_quad result = nilq;
 
814
      // read and shift
 
815
      result |= (t_byte) read ();
 
816
      result <<= 8;
 
817
      result |= (t_byte) read ();
 
818
      result <<= 8;
 
819
      result |= (t_byte) read ();
 
820
      result <<= 8;
 
821
      result |= (t_byte) read ();
 
822
      // unlock and return
 
823
      unlock ();
 
824
      return result;
 
825
    } catch (...) {
 
826
      unlock ();
 
827
      throw;
 
828
    }
 
829
  }
 
830
 
 
831
  // get an octa in natural format from this buffer
 
832
 
 
833
  t_octa Buffer::getno (void) {
 
834
    wrlock ();
 
835
    try {
 
836
      // check valid buffer size
 
837
      if (d_blen < 8) {
 
838
        throw Exception ("buffer-error", "small buffer size with getno");
 
839
      }
 
840
      // prepare result
 
841
      t_octa result = 0ULL;
 
842
      // read and shift
 
843
      result |= (t_byte) read ();
 
844
      result <<= 8;
 
845
      result |= (t_byte) read ();
 
846
      result <<= 8;
 
847
      result |= (t_byte) read ();
 
848
      result <<= 8;
 
849
      result |= (t_byte) read ();
 
850
      result <<= 8;
 
851
      result |= (t_byte) read ();
 
852
      result <<= 8;
 
853
      result |= (t_byte) read ();
 
854
      result <<= 8;
 
855
      result |= (t_byte) read ();
 
856
      result <<= 8;
 
857
      result |= (t_byte) read ();
 
858
      // unlock and return
 
859
      unlock ();
 
860
      return result;
 
861
    } catch (...) {
 
862
      unlock ();
 
863
      throw;
 
864
    }
 
865
  }
 
866
 
 
867
  // get a word in host format from this buffer
 
868
 
 
869
  t_word Buffer::gethw (void) {
 
870
    wrlock ();
 
871
    try {
 
872
      // check valid buffer size
 
873
      if (d_blen < 2) {
 
874
        throw Exception ("buffer-error", "small buffer size with gethw");
 
875
      }
 
876
      // extract the character buffer
 
877
      t_byte buf[2];
 
878
      for (long i = 0; i < 2; i++) buf[i] = read ();
 
879
      // convert it in host format
 
880
      t_word result = c_wntoh (buf);
 
881
      unlock ();
 
882
      return result;
 
883
    } catch (...) {
 
884
      unlock ();
 
885
      throw;
 
886
    }
 
887
  }
 
888
 
 
889
  // get a quad in host format from this buffer
 
890
 
 
891
  t_quad Buffer::gethq (void) {
 
892
    wrlock ();
 
893
    try {
 
894
      // check valid buffer size
 
895
      if (d_blen < 4) {
 
896
        throw Exception ("buffer-error", "small buffer size with gethq");
 
897
      }
 
898
      // extract the character buffer
 
899
      t_byte buf[4];
 
900
      for (long i = 0; i < 4; i++) buf[i] = read ();
 
901
      // convert it in host format
 
902
      t_quad result = c_qntoh (buf);
 
903
      unlock ();
 
904
      return result;
 
905
    } catch (...) {
 
906
      unlock ();
 
907
      throw;
 
908
    }
 
909
  }
 
910
 
 
911
  // get an octa in host format from this buffer
 
912
 
 
913
  t_octa Buffer::getho (void) {
 
914
    wrlock ();
 
915
    try {
 
916
      // check valid buffer size
 
917
      if (d_blen < 8) {
 
918
        throw Exception ("buffer-error", "small buffer size with getho");
 
919
      }
 
920
      // extract the character buffer
 
921
      t_byte buf[8];
 
922
      for (long i = 0; i < 8; i++) buf[i] = read ();
 
923
      // convert it in host format
 
924
      t_octa result = c_ontoh (buf);
 
925
      unlock ();
 
926
      return result;
 
927
    } catch (...) {
 
928
      unlock ();
 
929
      throw;
 
930
    }
 
931
  }
 
932
  
 
933
  // -------------------------------------------------------------------------
 
934
  // - object section                                                        -
 
935
  // -------------------------------------------------------------------------
 
936
 
 
937
  // the quark zone
 
938
  static const long QUARK_ZONE_LENGTH = 17;
 
939
  static QuarkZone  zone (QUARK_ZONE_LENGTH);
 
940
  
 
941
  // the object supported quarks
 
942
  static const long QUARK_ADD      = zone.intern ("add");
 
943
  static const long QUARK_GET      = zone.intern ("get");
 
944
  static const long QUARK_SHL      = zone.intern ("shl");
 
945
  static const long QUARK_READ     = zone.intern ("read");
 
946
  static const long QUARK_RESET    = zone.intern ("reset");
 
947
  static const long QUARK_LENGTH   = zone.intern ("length");
 
948
  static const long QUARK_ISFULL   = zone.intern ("full-p");
 
949
  static const long QUARK_EMPTYP   = zone.intern ("empty-p");
 
950
  static const long QUARK_FORMAT   = zone.intern ("format");
 
951
  static const long QUARK_GETSIZE  = zone.intern ("get-size");
 
952
  static const long QUARK_GETHW    = zone.intern ("get-host-word");
 
953
  static const long QUARK_GETHQ    = zone.intern ("get-host-quad");
 
954
  static const long QUARK_GETHO    = zone.intern ("get-host-octa");
 
955
  static const long QUARK_SETRFLG  = zone.intern ("set-resize");
 
956
  static const long QUARK_TOSTRING = zone.intern ("to-string");
 
957
  static const long QUARK_PUSHBACK = zone.intern ("pushback");
 
958
  static const long QUARK_ISRESIZE = zone.intern ("resize-p");
 
959
 
 
960
  // create a new object in a generic way
 
961
 
 
962
  Object* Buffer::mknew (Vector* argv) {
 
963
    long argc = (argv == nilp) ? 0 : argv->length ();
 
964
    // create an empty buffer with 0 arguments
 
965
    Buffer* result = new Buffer;
 
966
    // loop with literal objects
 
967
    for (long i = 0; i < argc; i++) {
 
968
      Object* obj = argv->get (i);
 
969
      // check for a literal
 
970
      Literal* lobj = dynamic_cast <Literal*> (obj);
 
971
      if (lobj != nilp) {
 
972
        result->add (lobj->tostring ());
 
973
        continue;
 
974
      }
 
975
      // check for a vector
 
976
      Vector* vobj = dynamic_cast <Vector*> (obj);
 
977
      if (vobj != nilp) {
 
978
        long vlen = vobj->length ();
 
979
        for (long j = 0; j < vlen; j++) {
 
980
          result->add ((char) vobj->getbyte (j));
 
981
        }
 
982
        continue;
 
983
      }
 
984
      throw Exception ("type-error", "invalid object with buffer",
 
985
                       Object::repr (obj));
 
986
    }
 
987
    return result;
 
988
  }
 
989
 
 
990
  // return true if the given quark is defined
 
991
 
 
992
  bool Buffer::isquark (const long quark, const bool hflg) const {
 
993
    rdlock ();
 
994
    if (zone.exists (quark) == true) {
 
995
      unlock ();
 
996
      return true;
 
997
    }      
 
998
    bool result = hflg ? Object::isquark (quark, hflg) : false;
 
999
    unlock ();
 
1000
    return result;
 
1001
  }
 
1002
 
 
1003
  // apply this object with a set of arguments and a quark
 
1004
 
 
1005
  Object* Buffer::apply (Runnable* robj, Nameset* nset, const long quark,
 
1006
                         Vector* argv) {
 
1007
    // get the number of arguments
 
1008
    long argc = (argv == nilp) ? 0 : argv->length ();
 
1009
 
 
1010
    // dispatch 0 argument
 
1011
    if (argc == 0) {
 
1012
      if (quark == QUARK_GET)      return new Byte    (get      ());
 
1013
      if (quark == QUARK_READ)     return new Byte    (read     ());
 
1014
      if (quark == QUARK_GETHW)    return new Integer (gethw    ());
 
1015
      if (quark == QUARK_GETHQ)    return new Integer (gethq    ());
 
1016
      if (quark == QUARK_GETHO)    return new Integer (getho    ());
 
1017
      if (quark == QUARK_LENGTH)   return new Integer (length   ());
 
1018
      if (quark == QUARK_ISFULL)   return new Boolean (full     ());
 
1019
      if (quark == QUARK_EMPTYP)   return new Boolean (empty    ());
 
1020
      if (quark == QUARK_FORMAT)   return new String  (format   ());
 
1021
      if (quark == QUARK_GETSIZE)  return new Integer (getsize  ());
 
1022
      if (quark == QUARK_TOSTRING) return new String  (tostring ());
 
1023
      if (quark == QUARK_ISRESIZE) return new Boolean (getrflg  ());
 
1024
      if (quark == QUARK_RESET) {
 
1025
        reset ();
 
1026
        return nilp;
 
1027
      }
 
1028
    }
 
1029
 
 
1030
    // dispatch 1 argument
 
1031
    if (argc == 1) {
 
1032
      if (quark == QUARK_GET) {
 
1033
        long index = argv->getlong (0);
 
1034
        return new Byte (get (index));
 
1035
      }
 
1036
      if (quark == QUARK_SETRFLG) {
 
1037
        bool rflg = argv->getbool (0);
 
1038
        setrflg (rflg);
 
1039
        return nilp;
 
1040
      }
 
1041
      if (quark == QUARK_ADD) {
 
1042
        Object* obj = argv->get (0);
 
1043
        // check for a byte
 
1044
        Byte* bobj = dynamic_cast<Byte*> (obj);
 
1045
        if (bobj != nilp) {
 
1046
          long result = add ((char) bobj->tobyte ());
 
1047
          return new Integer (result);
 
1048
        }
 
1049
        // check for a literal
 
1050
        Literal* lobj = dynamic_cast<Literal*> (obj);
 
1051
        if (lobj != nilp) {
 
1052
          long result = add (lobj->tostring ());
 
1053
          return new Integer (result);
 
1054
        }
 
1055
        // check for a buffer
 
1056
        Buffer* uobj = dynamic_cast<Buffer*> (obj);
 
1057
        if (uobj != nilp) {
 
1058
          long result = add (*uobj);
 
1059
          return new Integer (result);
 
1060
        }
 
1061
        throw Exception ("type-error", "invalid object to add in buffer");
 
1062
      }
 
1063
      if (quark == QUARK_PUSHBACK) {
 
1064
        Object* obj = argv->get (0);
 
1065
        // check for a byte
 
1066
        Byte* bobj = dynamic_cast<Byte*> (obj);
 
1067
        if (bobj != nilp) {
 
1068
          long result = pushback ((char) bobj->tobyte ());
 
1069
          return new Integer (result);
 
1070
        }
 
1071
        // check for a literal
 
1072
        Literal* lobj = dynamic_cast<Literal*> (obj);
 
1073
        if (lobj != nilp) {
 
1074
          long result = pushback (lobj->tostring ());
 
1075
          return new Integer (result);
 
1076
        }
 
1077
        // check for a buffer
 
1078
        Buffer* uobj = dynamic_cast<Buffer*> (obj);
 
1079
        if (uobj != nilp) {
 
1080
          long result = pushback (*uobj);
 
1081
          return new Integer (result);
 
1082
        }
 
1083
        throw Exception ("type-error", "invalid object to pushback in buffer");
 
1084
      }
 
1085
      if (quark == QUARK_SHL) {
 
1086
        long asl = argv->getlong (0);
 
1087
        shl (asl);
 
1088
        return nilp;
 
1089
      }
 
1090
    }
 
1091
    // call the object method
 
1092
    return Object::apply (robj, nset, quark, argv);
 
1093
  }
 
1094
}