summaryrefslogtreecommitdiffstats
path: root/src/translators/pilotdb/libpalm/Block.h
blob: 33f507cd8c536e192b04fc54a5ceb32a29fa31b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/*
 * palm-db-tools: Encapsulate "blocks" of data.
 * Copyright (C) 2000 by Tom Dyas (tdyas@users.sourceforge.net)
 *
 * The PalmLib::Block class represents a generic block of data. It is
 * used to make passing pi_char_t buffers around very easy. The Record
 * and Resource classes both inherit from this class. A STL interface
 * is also attempted though it is probably not complete.
 */

#ifndef __PALMLIB_BLOCK_H__
#define __PALMLIB_BLOCK_H__

#include <cstddef>
#include <algorithm>
#include <iterator>

#include "palmtypes.h"

namespace PalmLib {

    class Block {
    public:
      // STL: container type definitions
     typedef PalmLib::pi_char_t value_type;
     typedef value_type* pointer;
     typedef const value_type* const_pointer;
     typedef value_type* iterator;
     typedef const value_type* const_iterator;
     typedef value_type& reference;
     typedef const value_type& const_reference;
     typedef size_t size_type;
     typedef ptrdiff_t difference_type;

     // STL: reverisible container type definitions
#ifdef __GNUG__
     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
     typedef std::reverse_iterator<iterator> reverse_iterator;
#endif

  /**
   * Default constructor.
   */
  Block() : m_data(0), m_size(0) { }

  /**
   * Constructor which fills the block from buffer "raw" with
   * length "len".
   */
  Block(const_pointer raw, const size_type len) : m_data(0), m_size(0) {
      assign(raw, len);
  }

  /**
   * Constructor which takes a size and allocates a zero'ed out
   * buffer of that size. (STL: Sequence: default fill
   * constructor)
   */
  Block(const size_type size, const value_type value = 0)
      : m_data(0), m_size(0) {
      assign(size, value);
  }

  /**
   * Constructor which takes two iterators and builds the block
   * from the region between the iterators. (STL: Sequence:
   * range constructor)
   */
  Block(const_iterator a, const_iterator b) : m_data(0), m_size(0) {
      assign(a, b - a);
  }

  /**
   * Copy constructor. Just copies the data from the other block
   * into this block.
   */
  Block(const Block& rhs) : m_data(0), m_size(0) {
      assign(rhs.data(), rhs.size());
  }

  /**
   * Destructor. Just frees the buffer if it exists.
   */
  virtual ~Block() { clear(); }

  /**
   * Assignment operator.
   *
   * @param rhs The block whose contents should be copied.
   */
  Block& operator = (const Block& rhs) {
      assign(rhs.data(), rhs.size());
      return *this;
  }

  // STL: Container
  iterator begin() { return m_data; }
  const_iterator begin() const { return m_data; }
  iterator end() { return (m_data != 0) ? (m_data + m_size) : (0); }
  const_iterator end() const
      { return (m_data != 0) ? (m_data + m_size) : (0); }
  size_type size() const { return m_size; }
  size_type max_size() const {
      return size_type(-1) / sizeof(value_type);
  }
  bool empty() const { return m_size == 0; }

  // STL: Reversible Container
#ifdef __GNUG__
  reverse_iterator rbegin() { return reverse_iterator(end()); }
  const_reverse_iterator rbegin() const {
      return const_reverse_iterator(end());
  }
  reverse_iterator rend() { return reverse_iterator(begin()); }
  const_reverse_iterator rend() const {
      return const_reverse_iterator(begin());
  }
#endif

  // STL: Random Access Container
  reference operator [] (size_type index) { return m_data[index]; }
  const_reference operator [] (size_type index) const
      { return m_data[index]; }

  // STL: Sequence (not complete)
  void clear() {
      if (m_data) {
    delete [] m_data;
    m_data = 0;
    m_size = 0;
      }
  }
  void resize(size_type n);
  reference front() { return m_data[0]; }
  const_reference front() const { return m_data[0]; }

  // STL: (present in vector but not part of a interface spec)
  size_type capacity() const { return m_size; }
  void reserve(size_type size);

  /**
   * Return a pointer to the data area. If there are no
   * contents, then the return value will be NULL. This is not
   * an STL method but goes with this class as a singular data
   * block and not a container (even though it is).
   */
  iterator data() { return m_data; }
  const_iterator data() const { return m_data; }

  /**
   * Replace the existing contents of the Block with the buffer
   * that starts at raw of size len.
   *
   * @param raw Pointer to the new contents.
   * @param len Size of the new contents.
   */
  void assign(const_pointer data, const size_type size);

  /**
   * Replace the existing contents of the Block with a buffer
   * consisting of size elements equal to fill.
   *
   * @param size The size of the new contents.
   * @param value Value to fill the contents with.
   */
     void assign(const size_type size, const value_type value = 0);

     // compatiblity functions (remove before final 0.3.0 release)
     const_pointer raw_data() const { return data(); }
     pointer raw_data() { return data(); }
     size_type raw_size() const { return size(); }
     void set_raw(const_pointer raw, const size_type len)
         { assign(raw, len); }

    private:
     pointer m_data;
     size_type m_size;
    };

}

bool operator == (const PalmLib::Block& lhs, const PalmLib::Block& rhs);

inline bool operator != (const PalmLib::Block& lhs, const PalmLib::Block& rhs)
{ return ! (lhs == rhs); }

#endif