Harmonic Flow Framework (libhffwk)
Cross platform C++ 2D Game Engine Framework
GenericStorage.cpp
1 /*
2  Harmonic Flow Framework
3  Copyright (C) 2011-2018 Andreas Widen <andreas@harmonicflow.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "GenericStorage.h"
22 
23 #include "util/StringUtil.h"
24 #include "unicode/UString.h"
25 #include "platform/PakInterface.h"
26 #include <stdio.h>
27 
28 using namespace HFCore;
29 
30 #include "debug/CrtDbgNew.h"
31 
33  mFileKey(0)
34 {
35 }
36 
38 {
39 }
40 
41 Storage::Result GenericStorage::FileOpen(const int8_hf *pFilePathUtf8, int32_hf modeFlags,
42  HF_FileHandle *pFileHandleOut)
43 {
44  Result result = STORAGE_FAIL;
45 
46  // must specify a read/write and a create/open flag
47  // must specify a handle to set
48  if ((modeFlags & STORAGE_MODE_MASK) && (modeFlags & STORAGE_DISPO_MASK) && pFileHandleOut)
49  {
50  const wchar_t *pModeStr = NULL;
51  switch (modeFlags)
52  {
54  pModeStr = L"rb";
55  break;
56 
58  pModeStr = L"r+b";
59  break;
60 
62  pModeStr = L"w+b";
63  break;
64  }
65 
66  // check for bad flag combo
67  if (pModeStr)
68  {
69  // FILE *f = NULL;
70  std::wstring pFilePathUnicode = StringUtil::StringToWString(pFilePathUtf8);
71 #if defined(HF_PLATFORM_WINDOWS)
72  PFILE *file = p_fopen(pFilePathUnicode.c_str(), pModeStr);
73  if (file != NULL)
74  {
75  ++mFileKey;
76  mOpenFiles[ mFileKey ] = file;
77  *pFileHandleOut = (HF_FileHandle)mFileKey;
78  result = STORAGE_OK;
79  }
80 #else // for Mac and Linux (fopen supports unicode on Mac + Linux)
81  UString modeStr;
82  modeStr = pModeStr;
83  PFILE *file = p_fopen(pFilePathUtf8, modeStr.toUtf8());
84  if (file != NULL)
85  {
86  ++mFileKey;
87  mOpenFiles[ mFileKey ] = file;
88  *pFileHandleOut = (HF_FileHandle)mFileKey;
89  result = STORAGE_OK;
90  }
91 #endif
92 
93  }
94  }
95 
96  return result;
97 }
98 
100  int32_hf readSizeBytes)
101 {
102  Result result = STORAGE_FAIL;
103 
104  // validate file handle and dest buffer
105  PFILE *f = GetFilePtr(fileHandle);
106  if (f && pBuffer)
107  {
108  int32_hf bytesRead = (int32_hf)p_fread(pBuffer, 1, readSizeBytes, f);
109  if (bytesRead == readSizeBytes)
110  {
111  // any time you don't read exactly as much as you want, the call fails
112  // always use FileGetSize() to figure out exactly how much you want to read ahead of time if need be
113  result = STORAGE_OK;
114  }
115  }
116 
117  return result;
118 }
119 
121  const void *pBuffer, int32_hf writeSizeBytes)
122 {
123  Result result = STORAGE_FAIL;
124 
125  // validate file handle and src buffer
126  PFILE *f = GetFilePtr(fileHandle);
127  if (f && pBuffer)
128  {
129  int32_hf bytesWritten = (int32_hf)p_fwrite(pBuffer, 1, writeSizeBytes, f);
130  if (bytesWritten == writeSizeBytes)
131  {
132  result = STORAGE_OK;
133  }
134  }
135 
136  return result;
137 }
138 
140 {
141  Result result = STORAGE_FAIL;
142 
143  // validate file handle
144  PFILE *f = GetFilePtr(fileHandle);
145  if (f)
146  {
147  int32_hf closeResult = p_fclose(f);
148  if (closeResult != EOF)
149  {
150  int32_hf key = (int32_hf)fileHandle;
151  mOpenFiles.erase(key);
152  result = STORAGE_OK;
153  }
154  }
155 
156  return result;
157 }
158 
160 {
161  int32_hf sizeBytes = -1;
162 
163  // validate file handle
164  PFILE *f = GetFilePtr(openFileHandle);
165  if (f)
166  {
167  long int origPos = p_ftell(f);
168  p_fseek(f, 0, SEEK_END);
169  sizeBytes = p_ftell(f);
170  p_fseek(f, origPos, SEEK_SET);
171  }
172 
173  return sizeBytes;
174 }
175 
177 {
178  PFILE *pRet = NULL;
179 
180  int32_hf key = (int32_hf)hFile;
181  std::map<int32_hf, PFILE *>::iterator i = mOpenFiles.find(key);
182  if (i != mOpenFiles.end())
183  {
184  pRet = i->second;
185  }
186 
187  return pRet;
188 }
189 
191  int32_hf *outSizeRead)
192 {
193  *outSizeRead = 0;
194 
195  PFILE *file = p_fopen(pFilePathUtf8, "rb");
196  if (file == NULL)
197  {
198  envEngineLog("WARNING: Unable to open '%s'\r\n", pFilePathUtf8);
199  return NULL;
200  }
201 
202  int32_hf fileSize = 0;
203  if (file->mRecord)
204  {
205  fileSize = file->mRecord->mSize;
206  }
207  else
208  {
209  p_fseek(file, 0, SEEK_END);
210  fileSize = p_ftell(file);
211  p_fseek(file, 0, SEEK_SET);
212  }
213  int8_hf *source = new int8_hf[fileSize];
214  if (!source)
215  {
216  p_fclose(file);
217  return NULL;
218  }
219  memset(source, 0, fileSize * sizeof(int8_hf));
220 
221  // read in contents:
222  p_fread(source, 1, fileSize, file);
223  p_fclose(file);
224 
225  *outSizeRead = fileSize;
226  return source;
227 }
Interface for unicode string class UString.
Definition: UString.h:35
Storage. Must exist.
Definition: Storage.h:57
HFCore::PFILE * p_fopen(const int8_hf *fileName, const int8_hf *access)
Open a file (within pak file or outside of it).
int int32_hf
A type definition for int.
Definition: HFDataTypes.h:349
static std::wstring StringToWString(const std::string &string)
Convert std::string to std::wstring.
Definition: StringUtil.cpp:482
Interface which implements base class Storage.
int32_hf p_fclose(HFCore::PFILE *file)
Closes and deletes a HFCore::PFILE.
Storage mode: Write.
Definition: Storage.h:54
size_t p_fread(void *ptr, int32_hf size, int32_hf count, HFCore::PFILE *file)
Reads an array of count elements, each one with a size of size bytes, from the stream and stores them...
virtual int32_hf FileGetSize(HF_FileHandle openFileHandle)
Get the size of file in bytes.
virtual ~GenericStorage()
Destructor.
virtual Result FileOpen(const int8_hf *pFilePathUtf8, int32_hf modeFlags, HF_FileHandle *pFileHandleOut)
Open a file.
Storage: Open always.
Definition: Storage.h:58
size_t p_fwrite(const void *ptr, int32_hf size, int32_hf count, HFCore::PFILE *file)
Write block of data to HFCore::PFILE stream.
#define NULL
Convenient define for 0.
Definition: HFDataTypes.h:42
GenericStorage()
Constructor.
PakRecord * mRecord
Pointer to PakRecord.
Definition: PakInterface.h:148
Storage mode: Mask.
Definition: Storage.h:55
const int8_hf * toUtf8() const
Get the utf8 encoded string.
Definition: UString.cpp:574
virtual Result FileRead(HF_FileHandle fileHandle, void *pBuffer, int32_hf readSizeBytes)
Reads an array of size readSizeBytes and stores them in the block of memory specified by pBuffer...
char int8_hf
A type definition for char.
Definition: HFDataTypes.h:329
virtual Result FileClose(HF_FileHandle fileHandle)
Close a file.
Interface for unicode string class UString.
int32_hf HF_FileHandle
A type definition for int32_hf used as File IO handle.
Definition: HFDataTypes.h:381
int32_hf p_fseek(HFCore::PFILE *file, long offset, int32_hf origin)
Sets the position indicator associated with the stream to a new position.
Storage mode: Read.
Definition: Storage.h:53
virtual int8_hf * GetFileContents(const int8_hf *pFilePathUtf8, int32_hf *outSizeRead)
Get file contents (open and read contents of file).
virtual Result FileWrite(HF_FileHandle fileHandle, const void *pBuffer, int32_hf writeSizeBytes)
Write block of pBuffer to file.
Result
Storage result enum.
Definition: Storage.h:42
Definition: Actor.h:34
#define envEngineLog(format, args...)
Shortcut macro for logging to &#39;engine.log&#39;.
Definition: Environment.h:2369
Struct holding PakRecord, pointer to actual FILE and position.
Definition: PakInterface.h:146
virtual PFILE * GetFilePtr(HF_FileHandle hFile)
Get internal HFCore::PFILE for file.
int32_hf p_ftell(HFCore::PFILE *file)
Returns the current value of the position indicator of the HFCore::PFILE stream.
int32_hf mSize
Holds file size.
Definition: PakInterface.h:94
Interface for accessing pak files created with tool hfpak.
Interface for string related helper methods.