FIFE  be64c707dea6b3250bd4355bf5c825d25920087d
dat1.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 // 3rd party library includes
25 
26 // FIFE includes
27 // These includes are split up in two parts, separated by one empty line
28 // First block: files included from the FIFE root src directory
29 // Second block: files included from the same folder
30 #include "vfs/raw/rawdata.h"
31 #include "util/base/exception.h"
32 #include "util/log/logger.h"
33 
34 #include "dat1.h"
35 
36 namespace FIFE {
37  static Logger _log(LM_FO_LOADERS);
38 
39  DAT1::DAT1(VFS* vfs, const std::string& file) : VFSSource(vfs), m_datpath(file), m_data(vfs->open(file)) {
40  FL_LOG(_log, LMsg("MFFalloutDAT1")
41  << "loading: " << file
42  << " filesize: " << m_data->getDataLength());
43 
44  m_data->setIndex(0);
45 
46  const uint32_t dircount = m_data->read32Big();
47  m_data->moveIndex(4*3);
48 
49  FL_LOG(_log, LMsg("MFFalloutDAT1")
50  << "number of directories " << dircount);
51 
52  // Sanity check. Each dir entry needs min. 16 bytes.
53  if( dircount*16 > m_data->getDataLength() ) {
54  throw InvalidFormat("directory count larger than filesize.");
55  }
56 
57  std::list<std::string> dir_names;
58  for (uint32_t i = 0; i < dircount; ++i) {
59  std::string name = readString();
60  if (name == ".") {
61  name = "";
62  }
63  dir_names.push_back(name);
64  }
65 
66  for(std::list<std::string>::iterator i= dir_names.begin(); i!= dir_names.end(); ++i)
67  loadFileList(*i);
68  }
69 
70  void DAT1::loadFileList(const std::string& dirname) {
71  const uint32_t filecount = m_data->read32Big();
72  m_data->moveIndex(4*3);
73  for (uint32_t i = 0; i < filecount; ++i) {
75  info.name = fixPath(dirname + "/" + readString());
76  info.type = m_data->read32Big();
77  info.offset = m_data->read32Big();
78  info.unpackedLength = m_data->read32Big();
79  info.packedLength = m_data->read32Big();
80 
81  m_filelist.insert(std::make_pair(info.name, info));
82  }
83  }
84 
85  std::string DAT1::readString() {
86  uint8_t length = m_data->read8();
87  return m_data->readString(length);
88  }
89 
90  RawData* DAT1::open(const std::string& file) const {
91  const RawDataDAT1::s_info& info = getInfo(file);
92  return new RawData(new RawDataDAT1(getVFS(), m_datpath, info));
93  }
94 
95  bool DAT1::fileExists(const std::string& name) const {
96  return m_filelist.find(name) != m_filelist.end();
97  }
98 
99  const RawDataDAT1::s_info& DAT1::getInfo(const std::string& name) const {
100  type_filelist::const_iterator i = m_filelist.find(name);
101  if (i == m_filelist.end())
102  throw NotFound(name);
103 
104  return i->second;
105  }
106 
107  std::set<std::string> DAT1::listFiles(const std::string& pathstr) const {
108  return list(pathstr, false);
109  }
110 
111  std::set<std::string> DAT1::listDirectories(const std::string& pathstr) const {
112  return list(pathstr, true);
113  }
114 
115  std::set<std::string> DAT1::list(const std::string& pathstr, bool dirs) const {
116  std::set<std::string> list;
117  std::string path = pathstr;
118 
119  // Normalize the path
120  if (path.find("./") == 0) {
121  path.erase(0, 2);
122  }
123 
124  size_t lastIndex = path.size();
125  if (lastIndex != 0 && path[lastIndex-1] != '/') {
126  path += '/';
127  }
128 
129  type_filelist::const_iterator end = m_filelist.end();
130  for (type_filelist::const_iterator i = m_filelist.begin(); i != end; ++i) {
131  const std::string& file = i->first;
132  if (file.find(path) == 0) {
133  std::string cleanedfile = file.substr(path.size(), file.size()); // strip the pathstr
134  bool isdir = cleanedfile.find('/') != std::string::npos; // if we still have a / it's a subdir
135 
136  if (isdir) {
137  cleanedfile = cleanedfile.substr(0, cleanedfile.find('/'));
138  if (cleanedfile.find('/') != cleanedfile.rfind('/')) {
139  // check if this is a direct subdir
140  continue;
141  }
142  }
143 
144  if (isdir == dirs) {
145  list.insert(cleanedfile);
146  }
147  }
148  }
149 
150  return list;
151  }
152 } // FIFE
type_filelist m_filelist
Definition: dat1.h:74
std::set< std::string > list(const std::string &pathstr, bool dirs) const
Definition: dat1.cpp:115
RawData * open(const std::string &file) const
open a file inside this source
Definition: dat1.cpp:90
Helper class to create log strings out from separate parts Usage: LMsg("some text") << variable << "...
Definition: logger.h:82
VFSSource abstract baseclass.
Definition: vfssource.h:46
bool fileExists(const std::string &name) const
check if the given file exists
Definition: dat1.cpp:95
static Logger _log(LM_AUDIO)
VFS * getVFS() const
get the VFS this source is associated with.
Definition: vfssource.h:60
unsigned char uint8_t
Definition: core.h:38
void loadFileList(const std::string &dirname)
Definition: dat1.cpp:70
const RawDataDAT1::s_info & getInfo(const std::string &name) const
Get the needed information to unpack and extract a file from the DAT file.
Definition: dat1.cpp:99
The needed information for the extraction.
Definition: rawdatadat1.h:46
std::unique_ptr< RawData > m_data
Definition: dat1.h:72
std::set< std::string > listFiles(const std::string &pathstr) const
list all files in a directory of this source
Definition: dat1.cpp:107
DAT1(VFS *vfs, const std::string &file)
Constructor Create a VFSSource for a Fallout1 DAT file.
Definition: dat1.cpp:39
std::string readString()
Definition: dat1.cpp:85
#define FL_LOG(logger, msg)
Definition: logger.h:71
A subclass of RawDataMemSource, that fills itself with a FALLOUT1 .DAT file entry.
Definition: rawdatadat1.h:42
the main VFS (virtual file system) class
Definition: vfs.h:58
std::set< std::string > listDirectories(const std::string &pathstr) const
list all directories in a directory of this source
Definition: dat1.cpp:111
std::string m_datpath
Definition: dat1.h:71
unsigned int uint32_t
Definition: core.h:40
std::string fixPath(std::string path) const
Definition: vfssource.cpp:45
Used to access diffrent kinds of data.
Definition: rawdata.h:48