FIFE  6e1afdbeda11afe9ac53e6023a4be96ef88f1dc6
zipnode.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 * Copyright (C) 2005-2017 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 
32 namespace {
38  FIFE::ZipNode* FindNameInContainer(const FIFE::ZipNodeContainer& container,
39  const std::string& name) {
40  for (FIFE::ZipNodeContainer::const_iterator iter = container.begin(); iter != container.end(); ++iter) {
41  if ((*iter)->getName() == name) {
42  return *iter;
43  }
44  }
45 
46  return 0;
47  }
48 
49  FIFE::ZipNodeContainer::iterator FindNameInContainer(FIFE::ZipNodeContainer& container,
50  const std::string& name)
51  {
52  for (FIFE::ZipNodeContainer::iterator iter = container.begin(); iter != container.end(); ++iter) {
53  if ((*iter)->getName() == name) {
54  return iter;
55  }
56  }
57 
58  return container.end();
59  }
60 }
61 
62 namespace FIFE {
64  : comp(0), crc32(0), size_comp(0), size_real(0), offset(0) {
65  }
66 
67  ZipNode::ZipNode(const std::string& name, ZipNode* parent/*=0*/)
68  : m_name(name), m_parent(parent) {
69 
70  // set the content type based on whether
71  // the name has an extension
72  if (HasExtension(m_name))
73  {
75  }
76  else
77  {
79  }
80  }
81 
83  ZipNodeContainer::iterator iter;
84  for (iter = m_fileChildren.begin(); iter != m_fileChildren.end(); ++iter) {
85  delete *iter;
86  }
87  m_fileChildren.clear();
88 
89  for (iter = m_directoryChildren.begin(); iter != m_directoryChildren.end(); ++iter) {
90  delete *iter;
91  }
92  m_directoryChildren.clear();
93  }
94 
95  std::string ZipNode::getName() const {
96  return m_name;
97  }
98 
99  std::string ZipNode::getFullName() const {
100  // traverse up the hierarchy of parents
101  // to build the full path
102  if (m_parent)
103  {
104  bfs::path path(m_parent->getFullName());
105  path /= m_name;
106  return (path.string());
107  }
108  else
109  {
110  return m_name;
111  }
112  }
113 
115  return m_contentType;
116  }
117 
119  return m_parent;
120  }
121 
122  std::vector<ZipNode*> ZipNode::getChildren(ZipContentType::Enum contentType/*=ZipContentType::All*/) const {
123  switch (contentType) {
124  default: // fall through on purpose
125  case ZipContentType::All: {
126  // concatenate directory and file children
127  // putting all directories before files
128  // reserve space in destination vector to avoid
129  // tons of vector resizing overhead
130  ZipNodeContainer allNodes;
131  allNodes.reserve(m_directoryChildren.size() + m_fileChildren.size());
132  allNodes.insert(allNodes.end(), m_directoryChildren.begin(), m_directoryChildren.end());
133  allNodes.insert(allNodes.end(), m_fileChildren.begin(), m_fileChildren.end());
134 
135  return allNodes;
136  }
137  case ZipContentType::File: {
138  return m_fileChildren;
139  }
141  return m_directoryChildren;
142  }
143  }
144  }
145 
146  ZipNode* ZipNode::getChild(const std::string& name,
147  ZipContentType::Enum contentType/*=ZipContentType::All*/) const {
148  bool hasExtension = HasExtension(name);
149 
150  switch (contentType) {
151  default: // fall through on purpose
152  case ZipContentType::All: {
153  ZipNode* node = 0;
154  if (hasExtension) {
155  node = FindNameInContainer(m_fileChildren, name);
156  }
157  else {
158  node = FindNameInContainer(m_directoryChildren, name);
159  }
160 
161  return node;
162  }
163  case ZipContentType::File: {
164  if (!hasExtension) {
165  return 0;
166  }
167 
168  return FindNameInContainer(m_fileChildren, name);
169  }
171  if (hasExtension) {
172  return 0;
173  }
174 
175  return FindNameInContainer(m_directoryChildren, name);
176  }
177  }
178  }
179 
180  ZipNode* ZipNode::addChild(const std::string& name) {
181  ZipNode* child = new ZipNode(name, this);
182  if (child) {
183  if (child->getContentType() == ZipContentType::File) {
184  m_fileChildren.push_back(child);
185  }
186  else if (child->getContentType() == ZipContentType::Directory) {
187  m_directoryChildren.push_back(child);
188  }
189  else {
190  // TODO - vtchill - error case here, maybe exception
191  }
192  }
193 
194  return child;
195  }
196 
198  if (child) {
199  if (child->getContentType() == ZipContentType::File) {
200  ZipNodeContainer::iterator iter;
201  iter = std::find(m_fileChildren.begin(), m_fileChildren.end(), child);
202 
203  if (iter != m_fileChildren.end()) {
204  delete *iter;
205  m_fileChildren.erase(iter);
206  }
207  }
208  }
209  }
210 
211  void ZipNode::removeChild(const std::string& name) {
212  if (HasExtension(name)) {
213  ZipNodeContainer::iterator iter = FindNameInContainer(m_fileChildren, name);
214 
215  if (iter != m_fileChildren.end()) {
216  delete *iter;
217  m_fileChildren.erase(iter);
218  }
219  }
220  else {
221  ZipNodeContainer::iterator iter = FindNameInContainer(m_directoryChildren, name);
222 
223  if (iter != m_directoryChildren.end()) {
224  delete *iter;
225  m_directoryChildren.erase(iter);
226  }
227  }
228  }
229 
230  bool ZipNode::isLeaf() const
231  {
232  return (m_fileChildren.empty() && m_directoryChildren.empty());
233  }
234 
235  bool ZipNode::isBranch() const
236  {
237  return (!isLeaf());
238  }
239 
240  void ZipNode::setZipEntryData(const ZipEntryData& entryData)
241  {
242  m_entryData = entryData;
243  }
244 
246  {
247  return m_entryData;
248  }
249 }
250 
251 std::ostream& operator<<(std::ostream& os, const FIFE::ZipNode& node) {
252  // print node name first
253  os << node.getName() << std::endl;
254 
255  // print all file children
257  FIFE::ZipNodeContainer::iterator iter;
258  for (iter = fileChildren.begin(); iter != fileChildren.end(); ++iter) {
259  os << *(*iter) << std::endl;
260  }
261 
262  // print all directory children (recursively)
264  for (iter = directoryChildren.begin(); iter != directoryChildren.end(); ++iter) {
265  os << *(*iter) << std::endl;
266  }
267 
268  return os;
269 }
std::string m_name
Definition: zipnode.h:152
std::vector< ZipNode * > ZipNodeContainer
Definition: zipnode.h:61
bool isBranch() const
accessor for checking if this node has children
Definition: zipnode.cpp:235
std::vector< ZipNode * > getChildren(ZipContentType::Enum contentType=ZipContentType::All) const
gives access to retrieve the children of this node
Definition: zipnode.cpp:122
ZipContentType::Enum getContentType() const
accessor for the content type of this node
Definition: zipnode.cpp:114
ZipEntryData m_entryData
Definition: zipnode.h:154
std::string getName() const
accessor for the name of this node
Definition: zipnode.cpp:95
ZipEntryData()
constructor
Definition: zipnode.cpp:63
Definition: zipnode.h:48
~ZipNode()
destructor
Definition: zipnode.cpp:82
std::ostream & operator<<(std::ostream &os, const Location &l)
Stream output operator.
Definition: location.cpp:164
void removeChild(ZipNode *child)
allows removing a child from this node
Definition: zipnode.cpp:197
ZipNodeContainer m_directoryChildren
Definition: zipnode.h:158
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:146
ZipNode(const std::string &name, ZipNode *parent=0)
constructor for creating a node
Definition: zipnode.cpp:67
bool HasExtension(const std::string &path)
Helper function to check if a filename has an extension.
ZipNode * addChild(const std::string &child)
allows adding a child node to this node
Definition: zipnode.cpp:180
ZipNode * getParent() const
accessor for the parent node of this node will be NULL if this node has no parent ...
Definition: zipnode.cpp:118
std::string getFullName() const
accessor for the absolute path name of this node
Definition: zipnode.cpp:99
ZipNode * m_parent
Definition: zipnode.h:156
void setZipEntryData(const ZipEntryData &entryData)
sets the zip file entry information for this node in the zip archive
Definition: zipnode.cpp:240
ZipNodeContainer m_fileChildren
Definition: zipnode.h:157
bool isLeaf() const
accessor for checking if this node has any children
Definition: zipnode.cpp:230
const ZipEntryData & getZipEntryData() const
accessor for the entry data associated with this node in the zip archive
Definition: zipnode.cpp:245
ZipContentType::Enum m_contentType
Definition: zipnode.h:153