textwolf  0.2
xmltagstack.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Patrick P. Frey
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
10 
11 #ifndef __TEXTWOLF_XML_TAG_STACK_HPP__
12 #define __TEXTWOLF_XML_TAG_STACK_HPP__
13 #include "textwolf/exception.hpp"
14 #include <cstring>
15 #include <cstdlib>
16 
19 namespace textwolf {
20 
23 class TagStack
24  :public throws_exception
25 {
26 public:
29  {
30  if (m_ptr) std::free( m_ptr);
31  }
32 
35  :m_ptr(0),m_pos(0),m_size(InitSize)
36  {
37  if ((m_ptr=(char*)std::malloc( m_size)) == 0) throw std::bad_alloc();
38  }
40  TagStack( const TagStack& o)
41  :m_ptr(0),m_pos(o.m_pos),m_size(o.m_size)
42  {
43  if ((m_ptr=(char*)std::malloc( m_size)) == 0) throw std::bad_alloc();
44  std::memcpy( m_ptr, o.m_ptr, m_pos);
45  }
46 
50  void push( const char* pp, std::size_t nn)
51  {
52  std::size_t align = getAlign( nn);
53  std::size_t ofs = nn + align + sizeof( std::size_t);
54  if (m_pos + ofs > m_size)
55  {
56  while (m_pos + ofs > m_size) m_size *= 2;
57  if (m_pos + ofs > m_size) throw std::bad_alloc();
58  if (nn > ofs) throw exception( InvalidTagOffset);
59  char* xx = (char*)std::realloc( m_ptr, m_size);
60  if (!xx) throw std::bad_alloc();
61  m_ptr = xx;
62  }
63  std::memcpy( m_ptr + m_pos, pp, nn);
64  m_pos += ofs;
65  void* tt = m_ptr + m_pos - sizeof( std::size_t);
66  *(std::size_t*)(tt) = nn;
67  }
68 
73  bool top( const void*& element, std::size_t& elementsize)
74  {
75  std::size_t ofs = topofs(elementsize);
76  if (!ofs) return false;
77  element = m_ptr + m_pos - ofs;
78  return true;
79  }
80 
82  void pop()
83  {
84  std::size_t elementsize=0;
85  std::size_t ofs = topofs(elementsize);
86  if (m_pos < ofs) throw exception( CorruptTagStack);
87  m_pos -= ofs;
88  }
89 
92  bool empty() const
93  {
94  return (m_pos == 0);
95  }
96 
97  void clear()
98  {
99  m_pos = 0;
100  }
101 
102 private:
103  std::size_t topofs( std::size_t& elementsize)
104  {
105  if (m_pos < sizeof( std::size_t)) return 0;
106  void* tt = m_ptr + (m_pos - sizeof( std::size_t));
107  elementsize = *(std::size_t*)(tt);
108  std::size_t align = getAlign( elementsize);
109  std::size_t ofs = elementsize + align + sizeof( std::size_t);
110  if (ofs > m_pos) return 0;
111  return ofs;
112  }
113 private:
114  enum {InitSize=256};
115  char* m_ptr;
116  std::size_t m_pos;
117  std::size_t m_size;
118 
119  static std::size_t getAlign( std::size_t n)
120  {
121  return (sizeof(std::size_t) - (n & (sizeof(std::size_t)-1))) & (sizeof(std::size_t)-1);
122  }
123 };
124 
125 } //namespace
126 #endif
Base class for structures that can throw exceptions for non recoverable errors.
Definition: exception.hpp:20
currupted tag stack. Internal textwolf error
Definition: exception.hpp:41
bool top(const void *&element, std::size_t &elementsize)
Get the topmost tag.
Definition: xmltagstack.hpp:73
stack of tag names
Definition: xmltagstack.hpp:23
textwolf exception class
Definition: exception.hpp:48
void clear()
Definition: xmltagstack.hpp:97
internal error in the tag stack. Internal textwolf error
Definition: exception.hpp:40
bool empty() const
Find out if the stack is empty.
Definition: xmltagstack.hpp:92
~TagStack()
Destructor.
Definition: xmltagstack.hpp:28
TagStack(const TagStack &o)
Copy constructor.
Definition: xmltagstack.hpp:40
TagStack()
Default constructor.
Definition: xmltagstack.hpp:34
void pop()
Pop (remove) the topmost tag.
Definition: xmltagstack.hpp:82
Definition of exceptions with containing error codes thrown by textwolf.
void push(const char *pp, std::size_t nn)
Push a tag on top.
Definition: xmltagstack.hpp:50