hfile.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. ////////////////////////////////////////////////////////////////////////////////////////
  2. // RAVEN STANDARD USEFUL FUNCTION LIBRARY
  3. // (c) 2002 Activision
  4. //
  5. //
  6. // Handle File
  7. // -----------
  8. //
  9. ////////////////////////////////////////////////////////////////////////////////////////
  10. ////////////////////////////////////////////////////////////////////////////////////////
  11. // Includes
  12. ////////////////////////////////////////////////////////////////////////////////////////
  13. #include "hfile.h"
  14. #if !defined(RATL_HANDLE_POOL_VS_INC)
  15. #include "..\Ratl\handle_pool_vs.h"
  16. #endif
  17. #if !defined(RATL_VECTOR_VS_INC)
  18. #include "..\Ratl\vector_vs.h"
  19. #endif
  20. #if !defined(RUFL_HSTRING_INC)
  21. #include "hstring.h"
  22. #endif
  23. extern bool HFILEopen_read(int& handle, const char* filepath);
  24. extern bool HFILEopen_write(int& handle, const char* filepath);
  25. extern bool HFILEread(int& handle, void* data, int size);
  26. extern bool HFILEwrite(int& handle, const void* data, int size);
  27. extern bool HFILEclose(int& handle);
  28. ////////////////////////////////////////////////////////////////////////////////////////
  29. // Defines
  30. ////////////////////////////////////////////////////////////////////////////////////////
  31. #define MAX_OPEN_FILES 20
  32. ////////////////////////////////////////////////////////////////////////////////////////
  33. //
  34. ////////////////////////////////////////////////////////////////////////////////////////
  35. struct SOpenFile
  36. {
  37. #ifdef _XBOX
  38. dllNamespace::hstring mPath;
  39. #else
  40. hstring mPath;
  41. #endif
  42. bool mForRead;
  43. int mHandle;
  44. float mVersion;
  45. int mChecksum;
  46. };
  47. typedef ratl::handle_pool_vs<SOpenFile, MAX_OPEN_FILES> TFilePool;
  48. TFilePool& Pool()
  49. {
  50. static TFilePool TFP;
  51. return TFP;
  52. }
  53. ////////////////////////////////////////////////////////////////////////////////////////
  54. // Constructor
  55. //
  56. // Allocates a new OpenFile structure and initializes it. DOES NOT OPEN!
  57. //
  58. ////////////////////////////////////////////////////////////////////////////////////////
  59. hfile::hfile(const char* file)
  60. {
  61. if (Pool().full())
  62. {
  63. mHandle = 0;
  64. assert("HFILE: Too Many Files Open, Unable To Grab An Unused Handle"==0);
  65. return;
  66. }
  67. mHandle = Pool().alloc();
  68. SOpenFile& sfile = Pool()[mHandle];
  69. sfile.mPath = file;
  70. sfile.mHandle = 0;
  71. sfile.mForRead = true;
  72. }
  73. ////////////////////////////////////////////////////////////////////////////////////////
  74. // Destructor
  75. //
  76. // Releases the open file structure for resue. Also closes the file if open.
  77. //
  78. ////////////////////////////////////////////////////////////////////////////////////////
  79. hfile::~hfile()
  80. {
  81. if (is_open())
  82. {
  83. close();
  84. }
  85. if (mHandle && Pool().is_used(mHandle))
  86. {
  87. Pool().free(mHandle);
  88. }
  89. mHandle = 0;
  90. }
  91. ////////////////////////////////////////////////////////////////////////////////////////
  92. //
  93. ////////////////////////////////////////////////////////////////////////////////////////
  94. bool hfile::is_open(void) const
  95. {
  96. if (mHandle && Pool().is_used(mHandle))
  97. {
  98. return (Pool()[mHandle].mHandle!=0);
  99. }
  100. return false;
  101. }
  102. ////////////////////////////////////////////////////////////////////////////////////////
  103. //
  104. ////////////////////////////////////////////////////////////////////////////////////////
  105. bool hfile::is_open_for_read(void) const
  106. {
  107. if (mHandle && Pool().is_used(mHandle))
  108. {
  109. SOpenFile& sfile = Pool()[mHandle];
  110. return (sfile.mHandle!=0 && sfile.mForRead);
  111. }
  112. return false;
  113. }
  114. ////////////////////////////////////////////////////////////////////////////////////////
  115. //
  116. ////////////////////////////////////////////////////////////////////////////////////////
  117. bool hfile::is_open_for_write(void) const
  118. {
  119. if (mHandle && Pool().is_used(mHandle))
  120. {
  121. SOpenFile& sfile = Pool()[mHandle];
  122. return (sfile.mHandle!=0 && !sfile.mForRead);
  123. }
  124. return false;
  125. }
  126. ////////////////////////////////////////////////////////////////////////////////////
  127. //
  128. ////////////////////////////////////////////////////////////////////////////////////
  129. bool hfile::open(float version, int checksum, bool read)
  130. {
  131. // Make Sure This Is A Valid Handle
  132. //----------------------------------
  133. if (!mHandle || !Pool().is_used(mHandle))
  134. {
  135. assert("HFILE: Invalid Handle"==0);
  136. return false;
  137. }
  138. // Make Sure The File Is Not ALREADY Open
  139. //----------------------------------------
  140. SOpenFile& sfile = Pool()[mHandle];
  141. if (sfile.mHandle!=0)
  142. {
  143. assert("HFILE: Attempt To Open An Already Open File"==0);
  144. return false;
  145. }
  146. sfile.mForRead = read;
  147. if (read)
  148. {
  149. HFILEopen_read(sfile.mHandle, *sfile.mPath);
  150. }
  151. else
  152. {
  153. HFILEopen_write(sfile.mHandle, *sfile.mPath);
  154. }
  155. // If The Open Failed, Report It And Free The SOpenFile
  156. //------------------------------------------------------
  157. if (sfile.mHandle==0)
  158. {
  159. if (!read)
  160. {
  161. assert("HFILE: Unable To Open File"==0);
  162. }
  163. return false;
  164. }
  165. // Read The File's Header
  166. //------------------------
  167. if (read)
  168. {
  169. if (!HFILEread(sfile.mHandle, &sfile.mVersion, sizeof(sfile.mVersion)))
  170. {
  171. assert("HFILE: Unable To Read File Header"==0);
  172. close();
  173. return false;
  174. }
  175. if (!HFILEread(sfile.mHandle, &sfile.mChecksum, sizeof(sfile.mChecksum)))
  176. {
  177. assert("HFILE: Unable To Read File Header"==0);
  178. close();
  179. return false;
  180. }
  181. // Make Sure The Checksum & Version Match
  182. //----------------------------------------
  183. if (sfile.mVersion!=version || sfile.mChecksum!=checksum)
  184. {
  185. close();
  186. return false; // Failed To Match Checksum Or Version Number -> Old Data
  187. }
  188. }
  189. else
  190. {
  191. sfile.mVersion = version;
  192. sfile.mChecksum = checksum;
  193. if (!HFILEwrite(sfile.mHandle, &sfile.mVersion, sizeof(sfile.mVersion)))
  194. {
  195. assert("HFILE: Unable To Write File Header"==0);
  196. close();
  197. return false;
  198. }
  199. if (!HFILEwrite(sfile.mHandle, &sfile.mChecksum, sizeof(sfile.mChecksum)))
  200. {
  201. assert("HFILE: Unable To Write File Header"==0);
  202. close();
  203. return false;
  204. }
  205. }
  206. return true;
  207. }
  208. ////////////////////////////////////////////////////////////////////////////////////
  209. //
  210. ////////////////////////////////////////////////////////////////////////////////////
  211. bool hfile::close()
  212. {
  213. if (!mHandle || !Pool().is_used(mHandle))
  214. {
  215. assert("HFILE: Invalid Handle"==0);
  216. return false;
  217. }
  218. SOpenFile& sfile = Pool()[mHandle];
  219. if (sfile.mHandle==0)
  220. {
  221. assert("HFILE: Unable TO Close Unopened File"==0);
  222. return false;
  223. }
  224. if (!HFILEclose(sfile.mHandle))
  225. {
  226. sfile.mHandle = 0;
  227. assert("HFILE: Unable To Close File"==0);
  228. return false;
  229. }
  230. sfile.mHandle = 0;
  231. return true;
  232. }
  233. ////////////////////////////////////////////////////////////////////////////////////
  234. // Searches for the first block with the matching data size, and reads it in.
  235. ////////////////////////////////////////////////////////////////////////////////////
  236. bool hfile::load(void* data, int datasize)
  237. {
  238. // Go Ahead And Open The File For Reading
  239. //----------------------------------------
  240. bool auto_opened = false;
  241. if (!is_open())
  242. {
  243. if (!open_read())
  244. {
  245. return false;
  246. }
  247. auto_opened = true;
  248. }
  249. // Make Sure That The File Is Readable
  250. //-------------------------------------
  251. SOpenFile& sfile = Pool()[mHandle];
  252. if (!sfile.mForRead)
  253. {
  254. assert("HFILE: Unable to load from a file that is opened for save"==0);
  255. if (auto_opened)
  256. {
  257. close();
  258. }
  259. return false;
  260. }
  261. // Now Read It
  262. //-------------
  263. if (!HFILEread(sfile.mHandle, data, datasize))
  264. {
  265. assert("HFILE: Unable To Read Object"==0);
  266. if (auto_opened)
  267. {
  268. close();
  269. }
  270. return false;
  271. }
  272. // Success!
  273. //----------
  274. if (auto_opened)
  275. {
  276. close();
  277. }
  278. return true;
  279. }
  280. ////////////////////////////////////////////////////////////////////////////////////
  281. //
  282. ////////////////////////////////////////////////////////////////////////////////////
  283. bool hfile::save(void* data, int datasize)
  284. {
  285. // Go Ahead And Open The File For Reading
  286. //----------------------------------------
  287. bool auto_opened = false;
  288. if (!is_open())
  289. {
  290. if (!open_write())
  291. {
  292. return false;
  293. }
  294. auto_opened = true;
  295. }
  296. // Make Sure That The File Is Readable
  297. //-------------------------------------
  298. SOpenFile& sfile = Pool()[mHandle];
  299. if (sfile.mForRead)
  300. {
  301. assert("HFILE: Unable to save to a file that is opened for read"==0);
  302. if (auto_opened)
  303. {
  304. close();
  305. }
  306. return false;
  307. }
  308. // Write The Actual Object
  309. //-------------------------
  310. if (!HFILEwrite(sfile.mHandle, data, datasize))
  311. {
  312. assert("HFILE: Unable To Write File Data"==0);
  313. if (auto_opened)
  314. {
  315. close();
  316. }
  317. return false;
  318. }
  319. if (auto_opened)
  320. {
  321. close();
  322. }
  323. return true;
  324. }