Otclient  14/8/2020
binarytree.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2020 OTClient <https://github.com/edubart/otclient>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 #include "binarytree.h"
24 #include "filestream.h"
25 
27  m_fin(fin), m_pos(0xFFFFFFFF)
28 {
29  m_startPos = fin->tell();
30 }
31 
33 {
34 }
35 
36 void BinaryTree::skipNodes()
37 {
38  while(true) {
39  uint8 byte = m_fin->getU8();
40  switch(byte) {
41  case BINARYTREE_NODE_START: {
42  skipNodes();
43  break;
44  }
46  return;
48  m_fin->getU8();
49  break;
50  default:
51  break;
52  }
53  }
54 }
55 
56 void BinaryTree::unserialize()
57 {
58  if(m_pos != 0xFFFFFFFF)
59  return;
60  m_pos = 0;
61 
62  m_fin->seek(m_startPos);
63  while(true) {
64  uint8 byte = m_fin->getU8();
65  switch(byte) {
66  case BINARYTREE_NODE_START: {
67  skipNodes();
68  break;
69  }
71  return;
73  m_buffer.add(m_fin->getU8());
74  break;
75  default:
76  m_buffer.add(byte);
77  break;
78  }
79  }
80 }
81 
83 {
84  BinaryTreeVec children;
85  m_fin->seek(m_startPos);
86  while(true) {
87  uint8 byte = m_fin->getU8();
88  switch(byte) {
89  case BINARYTREE_NODE_START: {
90  BinaryTreePtr node(new BinaryTree(m_fin));
91  children.push_back(node);
92  node->skipNodes();
93  break;
94  }
96  return children;
98  m_fin->getU8();
99  break;
100  default:
101  break;
102  }
103  }
104 }
105 
107 {
108  unserialize();
109  if(pos > m_buffer.size())
110  stdext::throw_exception("BinaryTree: seek failed");
111  m_pos = pos;
112 }
113 
115 {
116  unserialize();
117  seek(tell() + len);
118 }
119 
121 {
122  unserialize();
123  if(m_pos+1 > m_buffer.size())
124  stdext::throw_exception("BinaryTree: getU8 failed");
125  uint8 v = m_buffer[m_pos];
126  m_pos += 1;
127  return v;
128 }
129 
131 {
132  unserialize();
133  if(m_pos+2 > m_buffer.size())
134  stdext::throw_exception("BinaryTree: getU16 failed");
135  uint16 v = stdext::readULE16(&m_buffer[m_pos]);
136  m_pos += 2;
137  return v;
138 }
139 
141 {
142  unserialize();
143  if(m_pos+4 > m_buffer.size())
144  stdext::throw_exception("BinaryTree: getU32 failed");
145  uint32 v = stdext::readULE32(&m_buffer[m_pos]);
146  m_pos += 4;
147  return v;
148 }
149 
151 {
152  unserialize();
153  if(m_pos+8 > m_buffer.size())
154  stdext::throw_exception("BinaryTree: getU64 failed");
155  uint64 v = stdext::readULE64(&m_buffer[m_pos]);
156  m_pos += 8;
157  return v;
158 }
159 
161 {
162  unserialize();
163  if(len == 0)
164  len = getU16();
165 
166  if(m_pos+len > m_buffer.size())
167  stdext::throw_exception("BinaryTree: getString failed: string length exceeded buffer size.");
168 
169  std::string ret((char *)&m_buffer[m_pos], len);
170  m_pos += len;
171  return ret;
172 }
173 
175 {
176  Point ret;
177  ret.x = getU8();
178  ret.y = getU8();
179  return ret;
180 }
181 
183  : m_fin(fin)
184 {
185  startNode(0);
186 }
187 
189 {
190  write(&v, 1);
191 }
192 
194 {
195  uint8 data[2];
196  stdext::writeULE16(data, v);
197  write(data, 2);
198 }
199 
201 {
202  uint8 data[4];
203  stdext::writeULE32(data, v);
204  write(data, 4);
205 }
206 
207 void OutputBinaryTree::addString(const std::string& v)
208 {
209  if(v.size() > 0xFFFF)
210  stdext::throw_exception("too long string");
211 
212  addU16(v.length());
213  write((const uint8*)v.c_str(), v.length());
214 }
215 
217 {
218  addU16(x);
219  addU16(y);
220  addU8(z);
221 }
222 
224 {
225  addU8(point.x);
226  addU8(point.y);
227 }
228 
230 {
232  write(&node, 1);
233 }
234 
236 {
237  m_fin->addU8(BINARYTREE_NODE_END);
238 }
239 
240 void OutputBinaryTree::write(const uint8 *data, size_t size)
241 {
242  for(size_t i=0;i<size;++i) {
243  if(data[i]==BINARYTREE_NODE_START || data[i]==BINARYTREE_NODE_END||data[i]==BINARYTREE_ESCAPE_CHAR)
245  m_fin->addU8(data[i]);
246  }
247 }
248 
binarytree.h
FileStream::seek
void seek(uint pos)
Definition: filestream.cpp:142
stdext::readULE16
uint16_t readULE16(const uchar *addr)
Definition: math.h:34
BinaryTree::getU16
uint16 getU16()
Definition: binarytree.cpp:130
BinaryTree::getChildren
BinaryTreeVec getChildren()
Definition: binarytree.cpp:82
TPoint::y
T y
Definition: point.h:83
z
gc sort z
Definition: CMakeLists.txt:176
OutputBinaryTree::write
void write(const uint8 *data, size_t size)
Definition: binarytree.cpp:240
uint32
uint32_t uint32
Definition: types.h:35
BinaryTree::getU32
uint32 getU32()
Definition: binarytree.cpp:140
BinaryTree::skip
void skip(uint len)
Definition: binarytree.cpp:114
DataBuffer::size
uint size() const
Definition: databuffer.h:47
OutputBinaryTree::addString
void addString(const std::string &v)
Definition: binarytree.cpp:207
DataBuffer::add
void add(const T &v)
Definition: databuffer.h:88
stdext::writeULE16
void writeULE16(uchar *addr, uint16_t value)
Definition: math.h:38
BinaryTree::getString
std::string getString(uint16 len=0)
Definition: binarytree.cpp:160
uint16
uint16_t uint16
Definition: types.h:36
BinaryTree::BinaryTree
BinaryTree(const FileStreamPtr &fin)
Definition: binarytree.cpp:26
BinaryTree::getPoint
Point getPoint()
Definition: binarytree.cpp:174
OutputBinaryTree::OutputBinaryTree
OutputBinaryTree(const FileStreamPtr &finish)
Definition: binarytree.cpp:182
uint
unsigned int uint
Definition: types.h:31
stdext::writeULE32
void writeULE32(uchar *addr, uint32_t value)
Definition: math.h:39
BinaryTree::seek
void seek(uint pos)
Definition: binarytree.cpp:106
OutputBinaryTree::addPoint
void addPoint(const Point &point)
Definition: binarytree.cpp:223
OutputBinaryTree::addU32
void addU32(uint32 v)
Definition: binarytree.cpp:200
TPoint::x
T x
Definition: point.h:83
BINARYTREE_NODE_END
@ BINARYTREE_NODE_END
Definition: binarytree.h:32
BinaryTree::getU64
uint64 getU64()
Definition: binarytree.cpp:150
uint64
uint64_t uint64
Definition: types.h:34
stdext::throw_exception
void throw_exception(const std::string &what)
Throws a generic exception.
Definition: exception.h:43
stdext::readULE64
uint64_t readULE64(const uchar *addr)
Definition: math.h:36
OutputBinaryTree::addU16
void addU16(uint16 v)
Definition: binarytree.cpp:193
filestream.h
BinaryTree::getU8
uint8 getU8()
Definition: binarytree.cpp:120
FileStream::tell
uint tell()
Definition: filestream.cpp:167
BINARYTREE_NODE_START
@ BINARYTREE_NODE_START
Definition: binarytree.h:31
stdext::shared_object_ptr< FileStream >
OutputBinaryTree::addPos
void addPos(uint16 x, uint16 y, uint8 z)
Definition: binarytree.cpp:216
BinaryTreeVec
std::vector< BinaryTreePtr > BinaryTreeVec
Definition: declarations.h:47
BinaryTree::~BinaryTree
~BinaryTree()
Definition: binarytree.cpp:32
BINARYTREE_ESCAPE_CHAR
@ BINARYTREE_ESCAPE_CHAR
Definition: binarytree.h:30
OutputBinaryTree::endNode
void endNode()
Definition: binarytree.cpp:235
TPoint< int >
FileStream::addU8
void addU8(uint8 v)
Definition: filestream.cpp:354
OutputBinaryTree::startNode
void startNode(uint8 node)
Definition: binarytree.cpp:229
stdext::readULE32
uint32_t readULE32(const uchar *addr)
Definition: math.h:35
FileStream::getU8
uint8 getU8()
Definition: filestream.cpp:183
uint8
uint8_t uint8
Definition: types.h:37
BinaryTree::tell
uint tell()
Definition: binarytree.h:43
OutputBinaryTree::addU8
void addU8(uint8 v)
Definition: binarytree.cpp:188