FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
zipnode.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 * Copyright (C) 2005-2019 by the FIFE team *
3 * http://www.fifengine.net *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU Lesser General Public *
8 * License as published by the Free Software Foundation; either *
9 * version 2.1 of the License, or (at your option) any later version. *
10 * *
11 * This library is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14 * Lesser General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU Lesser General Public *
17 * License along with this library; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21 
22 // Standard C++ library includes
23 
24 // FIFE includes
25 // These includes are split up in two parts, separated by one empty line
26 // First block: files included from the FIFE root src directory
27 // Second block: files included from the same folder
29 
30 #include "zipnode.h"
31 #include <algorithm>
32 
33 namespace {
39  FIFE::ZipNode* FindNameInContainer(const FIFE::ZipNodeContainer& container,
40  const std::string& name) {
41  for (FIFE::ZipNodeContainer::const_iterator iter = container.begin(); iter != container.end(); ++iter) {
42  if ((*iter)->getName() == name) {
43  return *iter;
44  }
45  }
46 
47  return 0;
48  }
49 
50  FIFE::ZipNodeContainer::iterator FindNameInContainer(FIFE::ZipNodeContainer& container,
51  const std::string& name)
52  {
53  for (FIFE::ZipNodeContainer::iterator iter = container.begin(); iter != container.end(); ++iter) {
54  if ((*iter)->getName() == name) {
55  return iter;
56  }
57  }
58 
59  return container.end();
60  }
61 }
62 
63 namespace FIFE {
65  : comp(0), crc32(0), size_comp(0), size_real(0), offset(0) {
66  }
67 
68  ZipNode::ZipNode(const std::string& name, ZipNode* parent/*=0*/)
69  : m_name(name), m_parent(parent) {
70 
71  // set the content type based on whether
72  // the name has an extension
73  if (HasExtension(m_name))
74  {
76  }
77  else
78  {
80  }
81  }
82 
84  ZipNodeContainer::iterator iter;
85  for (iter = m_fileChildren.begin(); iter != m_fileChildren.end(); ++iter) {
86  delete *iter;
87  }
88  m_fileChildren.clear();
89 
90  for (iter = m_directoryChildren.begin(); iter != m_directoryChildren.end(); ++iter) {
91  delete *iter;
92  }
93  m_directoryChildren.clear();
94  }
95 
96  std::string ZipNode::getName() const {
97  return m_name;
98  }
99 
100  std::string ZipNode::getFullName() const {
101  // traverse up the hierarchy of parents
102  // to build the full path
103  if (m_parent)
104  {
105  bfs::path path(m_parent->getFullName());
106  path /= m_name;
107  return (path.string());
108  }
109  else
110  {
111  return m_name;
112  }
113  }
114 
116  return m_contentType;
117  }
118 
120  return m_parent;
121  }
122 
123  std::vector<ZipNode*> ZipNode::getChildren(ZipContentType::Enum contentType/*=ZipContentType::All*/) const {
124  switch (contentType) {
125  default: // fall through on purpose
126  case ZipContentType::All: {
127  // concatenate directory and file children
128  // putting all directories before files
129  // reserve space in destination vector to avoid
130  // tons of vector resizing overhead
131  ZipNodeContainer allNodes;
132  allNodes.reserve(m_directoryChildren.size() + m_fileChildren.size());
133  allNodes.insert(allNodes.end(), m_directoryChildren.begin(), m_directoryChildren.end());
134  allNodes.insert(allNodes.end(), m_fileChildren.begin(), m_fileChildren.end());
135 
136  return allNodes;
137  }
138  case ZipContentType::File: {
139  return m_fileChildren;
140  }
142  return m_directoryChildren;
143  }
144  }
145  }
146 
147  ZipNode* ZipNode::getChild(const std::string& name,
148  ZipContentType::Enum contentType/*=ZipContentType::All*/) const {
149  bool hasExtension = HasExtension(name);
150 
151  switch (contentType) {
152  default: // fall through on purpose
153  case ZipContentType::All: {
154  ZipNode* node = 0;
155  if (hasExtension) {
156  node = FindNameInContainer(m_fileChildren, name);
157  }
158  else {
159  node = FindNameInContainer(m_directoryChildren, name);
160  }
161 
162  return node;
163  }
164  case ZipContentType::File: {
165  if (!hasExtension) {
166  return 0;
167  }
168 
169  return FindNameInContainer(m_fileChildren, name);
170  }
172  if (hasExtension) {
173  return 0;
174  }
175 
176  return FindNameInContainer(m_directoryChildren, name);
177  }
178  }
179  }
180 
181  ZipNode* ZipNode::addChild(const std::string& name) {
182  ZipNode* child = new ZipNode(name, this);
183  if (child) {
184  if (child->getContentType() == ZipContentType::File) {
185  m_fileChildren.push_back(child);
186  }
187  else if (child->getContentType() == ZipContentType::Directory) {
188  m_directoryChildren.push_back(child);
189  }
190  else {
191  // TODO - vtchill - error case here, maybe exception
192  }
193  }
194 
195  return child;
196  }
197 
199  if (child) {
200  if (child->getContentType() == ZipContentType::File) {
201  ZipNodeContainer::iterator iter;
202  iter = std::find(m_fileChildren.begin(), m_fileChildren.end(), child);
203 
204  if (iter != m_fileChildren.end()) {
205  delete *iter;
206  m_fileChildren.erase(iter);
207  }
208  }
209  }
210  }
211 
212  void ZipNode::removeChild(const std::string& name) {
213  if (HasExtension(name)) {
214  ZipNodeContainer::iterator iter = FindNameInContainer(m_fileChildren, name);
215 
216  if (iter != m_fileChildren.end()) {
217  delete *iter;
218  m_fileChildren.erase(iter);
219  }
220  }
221  else {
222  ZipNodeContainer::iterator iter = FindNameInContainer(m_directoryChildren, name);
223 
224  if (iter != m_directoryChildren.end()) {
225  delete *iter;
226  m_directoryChildren.erase(iter);
227  }
228  }
229  }
230 
231  bool ZipNode::isLeaf() const
232  {
233  return (m_fileChildren.empty() && m_directoryChildren.empty());
234  }
235 
236  bool ZipNode::isBranch() const
237  {
238  return (!isLeaf());
239  }
240 
241  void ZipNode::setZipEntryData(const ZipEntryData& entryData)
242  {
243  m_entryData = entryData;
244  }
245 
247  {
248  return m_entryData;
249  }
250 }
251 
252 std::ostream& operator<<(std::ostream& os, const FIFE::ZipNode& node) {
253  // print node name first
254  os << node.getName() << std::endl;
255 
256  // print all file children
258  FIFE::ZipNodeContainer::iterator iter;
259  for (iter = fileChildren.begin(); iter != fileChildren.end(); ++iter) {
260  os << *(*iter) << std::endl;
261  }
262 
263  // print all directory children (recursively)
265  for (iter = directoryChildren.begin(); iter != directoryChildren.end(); ++iter) {
266  os << *(*iter) << std::endl;
267  }
268 
269  return os;
270 }
std::string m_name
Definition: zipnode.h:152
std::vector< ZipNode * > ZipNodeContainer
Definition: zipnode.h:61
std::string getName() const
accessor for the name of this node
Definition: zipnode.cpp:96
ZipEntryData m_entryData
Definition: zipnode.h:154
std::string getFullName() const
accessor for the absolute path name of this node
Definition: zipnode.cpp:100
ZipEntryData()
constructor
Definition: zipnode.cpp:64
Definition: zipnode.h:48
std::vector< ZipNode * > getChildren(ZipContentType::Enum contentType=ZipContentType::All) const
gives access to retrieve the children of this node
Definition: zipnode.cpp:123
~ZipNode()
destructor
Definition: zipnode.cpp:83
std::ostream & operator<<(std::ostream &os, const Location &l)
Stream output operator.
Definition: location.cpp:164
bool isLeaf() const
accessor for checking if this node has any children
Definition: zipnode.cpp:231
void removeChild(ZipNode *child)
allows removing a child from this node
Definition: zipnode.cpp:198
const ZipEntryData & getZipEntryData() const
accessor for the entry data associated with this node in the zip archive
Definition: zipnode.cpp:246
ZipNodeContainer m_directoryChildren
Definition: zipnode.h:158
ZipNode(const std::string &name, ZipNode *parent=0)
constructor for creating a node
Definition: zipnode.cpp:68
bool HasExtension(const std::string &path)
Helper function to check if a filename has an extension.
ZipNode * getParent() const
accessor for the parent node of this node will be NULL if this node has no parent ...
Definition: zipnode.cpp:119
ZipContentType::Enum getContentType() const
accessor for the content type of this node
Definition: zipnode.cpp:115
ZipNode * addChild(const std::string &child)
allows adding a child node to this node
Definition: zipnode.cpp:181
ZipNode * m_parent
Definition: zipnode.h:156
ZipNode * getChild(const std::string &name, ZipContentType::Enum contentType=ZipContentType::All) const
gives access to retrieving a specific child node by name
Definition: zipnode.cpp:147
void setZipEntryData(const ZipEntryData &entryData)
sets the zip file entry information for this node in the zip archive
Definition: zipnode.cpp:241
ZipNodeContainer m_fileChildren
Definition: zipnode.h:157
bool isBranch() const
accessor for checking if this node has children
Definition: zipnode.cpp:236
ZipContentType::Enum m_contentType
Definition: zipnode.h:153