1 /*
2  * HLLib
3  * Copyright (C) 2006-2010 Ryan Gregg
4 
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later
9  * version.
10  */
11 
12 #include "HLLib.h"
13 #include "Package.h"
14 #include "Mappings.h"
15 #include "Streams.h"
16 
17 using namespace HLLib;
18 
CPackage()19 CPackage::CPackage() : bDeleteStream(hlFalse), bDeleteMapping(hlFalse), pStream(0), pMapping(0), pRoot(0), pStreams(0)
20 {
21 
22 }
23 
~CPackage()24 CPackage::~CPackage()
25 {
26 	assert(this->pStream == 0);
27 	assert(this->pMapping == 0);
28 	assert(this->pRoot == 0);
29 	assert(this->pStreams == 0);
30 }
31 
GetOpened() const32 hlBool CPackage::GetOpened() const
33 {
34 	return this->pMapping != 0;
35 }
36 
Open(Streams::IStream & Stream,hlUInt uiMode)37 hlBool CPackage::Open(Streams::IStream &Stream, hlUInt uiMode)
38 {
39 	return this->Open(&Stream, uiMode, hlFalse);
40 }
41 
Open(Mapping::CMapping & Mapping,hlUInt uiMode)42 hlBool CPackage::Open(Mapping::CMapping &Mapping, hlUInt uiMode)
43 {
44 	return this->Open(&Mapping, uiMode, hlFalse);
45 }
46 
Open(const hlChar * lpFileName,hlUInt uiMode)47 hlBool CPackage::Open(const hlChar *lpFileName, hlUInt uiMode)
48 {
49 	if(uiMode & HL_MODE_NO_FILEMAPPING)
50 	{
51 		return this->Open(new Streams::CFileStream(lpFileName), uiMode, hlTrue);
52 	}
53 	else
54 	{
55 		return this->Open(new Mapping::CFileMapping(lpFileName), uiMode, hlTrue);
56 	}
57 }
58 
Open(hlVoid * lpData,hlUInt uiBufferSize,hlUInt uiMode)59 hlBool CPackage::Open(hlVoid *lpData, hlUInt uiBufferSize, hlUInt uiMode)
60 {
61 	return this->Open(new Mapping::CMemoryMapping(lpData, uiBufferSize), uiMode, hlTrue);
62 }
63 
Open(hlVoid * pUserData,hlUInt uiMode)64 hlBool CPackage::Open(hlVoid *pUserData, hlUInt uiMode)
65 {
66 	return this->Open(new Streams::CProcStream(pUserData), uiMode, hlTrue);
67 }
68 
Open(Streams::IStream * pStream,hlUInt uiMode,hlBool bDeleteStream)69 hlBool CPackage::Open(Streams::IStream *pStream, hlUInt uiMode, hlBool bDeleteStream)
70 {
71 	this->Close();
72 
73 	this->pStream = pStream;
74 	this->bDeleteStream = bDeleteStream;
75 
76 	this->bDeleteMapping = hlTrue;
77 	this->pMapping = new Mapping::CStreamMapping(*this->pStream);
78 
79 	if(!this->pMapping->Open(uiMode))
80 	{
81 		this->Close();
82 		return hlFalse;
83 	}
84 
85 	if(!this->MapDataStructures())
86 	{
87 		this->UnmapDataStructures();
88 		this->Close();
89 		return hlFalse;
90 	}
91 
92 	this->pStreams = new CStreamList();
93 
94 	return hlTrue;
95 }
96 
Open(Mapping::CMapping * pMapping,hlUInt uiMode,hlBool bDeleteMapping)97 hlBool CPackage::Open(Mapping::CMapping *pMapping, hlUInt uiMode, hlBool bDeleteMapping)
98 {
99 	this->Close();
100 
101 	this->bDeleteMapping = bDeleteMapping;
102 	this->pMapping = pMapping;
103 
104 	if(!this->pMapping->Open(uiMode))
105 	{
106 		this->Close();
107 		return hlFalse;
108 	}
109 
110 	if(!this->MapDataStructures())
111 	{
112 		this->UnmapDataStructures();
113 		this->Close();
114 		return hlFalse;
115 	}
116 
117 	this->pStreams = new CStreamList();
118 
119 	return hlTrue;
120 }
121 
Close()122 hlVoid CPackage::Close()
123 {
124 	if(this->pStreams != 0)
125 	{
126 		for(CStreamList::iterator i = this->pStreams->begin(); i != this->pStreams->end(); ++i)
127 		{
128 			Streams::IStream *pStream = *i;
129 
130 			pStream->Close();
131 			this->ReleaseStreamInternal(*pStream);
132 			delete pStream;
133 		}
134 
135 		delete this->pStreams;
136 		this->pStreams = 0;
137 	}
138 
139 	if(this->pMapping != 0)
140 	{
141 		this->UnmapDataStructures();
142 
143 		this->pMapping->Close();
144 	}
145 
146 	if(this->pRoot != 0)
147 	{
148 		this->ReleaseRoot();
149 		delete this->pRoot;
150 		this->pRoot = 0;
151 	}
152 
153 	if(this->bDeleteMapping)
154 	{
155 		delete this->pMapping;
156 		this->bDeleteMapping = hlFalse;
157 	}
158 	this->pMapping = 0;
159 
160 	if(this->bDeleteStream)
161 	{
162 		delete this->pStream;
163 		this->bDeleteStream = hlFalse;
164 	}
165 	this->pStream = 0;
166 }
167 
Defragment()168 hlBool CPackage::Defragment()
169 {
170 	if(!this->GetOpened())
171 	{
172 		LastError.SetErrorMessage("Package not opened.");
173 		return hlFalse;
174 	}
175 
176 	if(!(this->GetMapping()->GetMode() & HL_MODE_WRITE))
177 	{
178 		LastError.SetErrorMessage("Package does not have write privileges, please enable them.");
179 		return hlFalse;
180 	}
181 
182 	if(this->GetMapping()->GetMode() & HL_MODE_VOLATILE)
183 	{
184 		LastError.SetErrorMessage("Package has volatile access enabled, please disable it.");
185 		return hlFalse;
186 	}
187 
188 	return this->DefragmentInternal();
189 }
190 
DefragmentInternal()191 hlBool CPackage::DefragmentInternal()
192 {
193 	return hlTrue;
194 }
195 
GetMapping() const196 const Mapping::CMapping* CPackage::GetMapping() const
197 {
198 	return this->pMapping;
199 }
200 
GetRoot()201 CDirectoryFolder *CPackage::GetRoot()
202 {
203 	if(!this->GetOpened())
204 	{
205 		return 0;
206 	}
207 
208 	if(this->pRoot == 0)
209 	{
210 		this->pRoot = this->CreateRoot();
211 		this->pRoot->Sort();
212 	}
213 
214 	return this->pRoot;
215 }
216 
GetRoot() const217 const CDirectoryFolder *CPackage::GetRoot() const
218 {
219 	if(!this->GetOpened())
220 	{
221 		return 0;
222 	}
223 
224 	return this->pRoot;
225 }
226 
ReleaseRoot()227 hlVoid CPackage::ReleaseRoot()
228 {
229 
230 }
231 
GetAttributeCount() const232 hlUInt CPackage::GetAttributeCount() const
233 {
234 	if(!this->GetOpened())
235 	{
236 		return 0;
237 	}
238 
239 	return this->GetAttributeCountInternal();
240 }
241 
GetAttributeName(HLPackageAttribute eAttribute) const242 const hlChar *CPackage::GetAttributeName(HLPackageAttribute eAttribute) const
243 {
244 	if(!this->GetOpened())
245 	{
246 		return 0;
247 	}
248 
249 	return this->GetAttributeNameInternal(eAttribute);
250 }
251 
GetAttribute(HLPackageAttribute eAttribute,HLAttribute & Attribute) const252 hlBool CPackage::GetAttribute(HLPackageAttribute eAttribute, HLAttribute &Attribute) const
253 {
254 	Attribute.eAttributeType = HL_ATTRIBUTE_INVALID;
255 
256 	if(!this->GetOpened())
257 	{
258 		//LastError.SetErrorMessage("Package not open.");
259 		return hlFalse;
260 	}
261 
262 	return this->GetAttributeInternal(eAttribute, Attribute);
263 }
264 
GetAttributeCountInternal() const265 hlUInt CPackage::GetAttributeCountInternal() const
266 {
267 	return 0;
268 }
269 
GetAttributeNameInternal(HLPackageAttribute eAttribute) const270 const hlChar *CPackage::GetAttributeNameInternal(HLPackageAttribute eAttribute) const
271 {
272 	return 0;
273 }
274 
GetAttributeInternal(HLPackageAttribute eAttribute,HLAttribute & Attribute) const275 hlBool CPackage::GetAttributeInternal(HLPackageAttribute eAttribute, HLAttribute &Attribute) const
276 {
277 	return hlFalse;
278 }
279 
GetItemAttributeCount() const280 hlUInt CPackage::GetItemAttributeCount() const
281 {
282 	if(!this->GetOpened())
283 	{
284 		return 0;
285 	}
286 
287 	return this->GetItemAttributeCountInternal();
288 }
289 
GetItemAttributeName(HLPackageAttribute eAttribute) const290 const hlChar *CPackage::GetItemAttributeName(HLPackageAttribute eAttribute) const
291 {
292 	if(!this->GetOpened())
293 	{
294 		return 0;
295 	}
296 
297 	return this->GetItemAttributeNameInternal(eAttribute);
298 }
299 
GetItemAttribute(const CDirectoryItem * pItem,HLPackageAttribute eAttribute,HLAttribute & Attribute) const300 hlBool CPackage::GetItemAttribute(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
301 {
302 	Attribute.eAttributeType = HL_ATTRIBUTE_INVALID;
303 
304 	if(!this->GetOpened() || pItem == 0 || pItem->GetPackage() != this)
305 	{
306 		LastError.SetErrorMessage("Item does not belong to package.");
307 		return hlFalse;
308 	}
309 
310 	return this->GetItemAttributeInternal(pItem, eAttribute, Attribute);
311 }
312 
GetItemAttributeCountInternal() const313 hlUInt CPackage::GetItemAttributeCountInternal() const
314 {
315 	return 0;
316 }
317 
GetItemAttributeNameInternal(HLPackageAttribute eAttribute) const318 const hlChar *CPackage::GetItemAttributeNameInternal(HLPackageAttribute eAttribute) const
319 {
320 	return 0;
321 }
322 
GetItemAttributeInternal(const CDirectoryItem * pItem,HLPackageAttribute eAttribute,HLAttribute & Attribute) const323 hlBool CPackage::GetItemAttributeInternal(const CDirectoryItem *pItem, HLPackageAttribute eAttribute, HLAttribute &Attribute) const
324 {
325 	return hlFalse;
326 }
327 
GetFileExtractable(const CDirectoryFile * pFile,hlBool & bExtractable) const328 hlBool CPackage::GetFileExtractable(const CDirectoryFile *pFile, hlBool &bExtractable) const
329 {
330 	bExtractable = hlFalse;
331 
332 	if(!this->GetOpened() || pFile == 0 || pFile->GetPackage() != this)
333 	{
334 		LastError.SetErrorMessage("File does not belong to package.");
335 		return hlFalse;
336 	}
337 
338 	return this->GetFileExtractableInternal(pFile, bExtractable);
339 }
340 
GetFileExtractableInternal(const CDirectoryFile * pFile,hlBool & bExtractable) const341 hlBool CPackage::GetFileExtractableInternal(const CDirectoryFile *pFile, hlBool &bExtractable) const
342 {
343 	bExtractable = hlTrue;
344 	return hlTrue;
345 }
346 
GetFileValidation(const CDirectoryFile * pFile,HLValidation & eValidation) const347 hlBool CPackage::GetFileValidation(const CDirectoryFile *pFile, HLValidation &eValidation) const
348 {
349 	eValidation = HL_VALIDATES_ASSUMED_OK;
350 
351 	if(!this->GetOpened() || pFile == 0 || pFile->GetPackage() != this)
352 	{
353 		LastError.SetErrorMessage("File does not belong to package.");
354 		return hlFalse;
355 	}
356 
357 	return this->GetFileValidationInternal(pFile, eValidation);
358 }
359 
GetFileValidationInternal(const CDirectoryFile * pFile,HLValidation & eValidation) const360 hlBool CPackage::GetFileValidationInternal(const CDirectoryFile *pFile, HLValidation &eValidation) const
361 {
362 	eValidation = HL_VALIDATES_ASSUMED_OK;
363 	return hlTrue;
364 }
365 
GetFileSize(const CDirectoryFile * pFile,hlUInt & uiSize) const366 hlBool CPackage::GetFileSize(const CDirectoryFile *pFile, hlUInt &uiSize) const
367 {
368 	uiSize = 0;
369 
370 	if(!this->GetOpened() || pFile == 0 || pFile->GetPackage() != this)
371 	{
372 		LastError.SetErrorMessage("File does not belong to package.");
373 		return hlFalse;
374 	}
375 
376 	return this->GetFileSizeInternal(pFile, uiSize);
377 }
378 
GetFileSizeOnDisk(const CDirectoryFile * pFile,hlUInt & uiSize) const379 hlBool CPackage::GetFileSizeOnDisk(const CDirectoryFile *pFile, hlUInt &uiSize) const
380 {
381 	uiSize = 0;
382 
383 	if(!this->GetOpened() || pFile == 0 || pFile->GetPackage() != this)
384 	{
385 		LastError.SetErrorMessage("File does not belong to package.");
386 		return hlFalse;
387 	}
388 
389 	return this->GetFileSizeOnDiskInternal(pFile, uiSize);
390 }
391 
CreateStream(const CDirectoryFile * pFile,Streams::IStream * & pStream) const392 hlBool CPackage::CreateStream(const CDirectoryFile *pFile, Streams::IStream *&pStream) const
393 {
394 	pStream = 0;
395 
396 	if(!this->GetOpened() || pFile == 0 || pFile->GetPackage() != this)
397 	{
398 		LastError.SetErrorMessage("File does not belong to package.");
399 		return hlFalse;
400 	}
401 
402 	if(!this->CreateStreamInternal(pFile, pStream))
403 	{
404 		return hlFalse;
405 	}
406 
407 	this->pStreams->push_back(pStream);
408 	return hlTrue;
409 }
410 
ReleaseStream(Streams::IStream * pStream) const411 hlVoid CPackage::ReleaseStream(Streams::IStream *pStream) const
412 {
413 	if(!this->GetOpened())
414 	{
415 		return;
416 	}
417 
418 	for(CStreamList::iterator i = this->pStreams->begin(); i != this->pStreams->end(); ++i)
419 	{
420 		if(*i == pStream)
421 		{
422 			pStream->Close();
423 			this->ReleaseStreamInternal(*pStream);
424 			delete pStream;
425 
426 			this->pStreams->erase(i);
427 			break;
428 		}
429 	}
430 }
431 
ReleaseStreamInternal(Streams::IStream & Stream) const432 hlVoid CPackage::ReleaseStreamInternal(Streams::IStream &Stream) const
433 {
434 
435 }
436