File.cpp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include "Unzip.h"
  23. /*
  24. =================
  25. FS_WriteFloatString
  26. =================
  27. */
  28. int FS_WriteFloatString( char *buf, const char *fmt, va_list argPtr ) {
  29. long i;
  30. unsigned long u;
  31. double f;
  32. char *str;
  33. int index;
  34. idStr tmp, format;
  35. index = 0;
  36. while( *fmt ) {
  37. switch( *fmt ) {
  38. case '%':
  39. format = "";
  40. format += *fmt++;
  41. while ( (*fmt >= '0' && *fmt <= '9') ||
  42. *fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') {
  43. format += *fmt++;
  44. }
  45. format += *fmt;
  46. switch( *fmt ) {
  47. case 'f':
  48. case 'e':
  49. case 'E':
  50. case 'g':
  51. case 'G':
  52. f = va_arg( argPtr, double );
  53. if ( format.Length() <= 2 ) {
  54. // high precision floating point number without trailing zeros
  55. sprintf( tmp, "%1.10f", f );
  56. tmp.StripTrailing( '0' );
  57. tmp.StripTrailing( '.' );
  58. index += sprintf( buf+index, "%s", tmp.c_str() );
  59. }
  60. else {
  61. index += sprintf( buf+index, format.c_str(), f );
  62. }
  63. break;
  64. case 'd':
  65. case 'i':
  66. i = va_arg( argPtr, long );
  67. index += sprintf( buf+index, format.c_str(), i );
  68. break;
  69. case 'u':
  70. u = va_arg( argPtr, unsigned long );
  71. index += sprintf( buf+index, format.c_str(), u );
  72. break;
  73. case 'o':
  74. u = va_arg( argPtr, unsigned long );
  75. index += sprintf( buf+index, format.c_str(), u );
  76. break;
  77. case 'x':
  78. u = va_arg( argPtr, unsigned long );
  79. index += sprintf( buf+index, format.c_str(), u );
  80. break;
  81. case 'X':
  82. u = va_arg( argPtr, unsigned long );
  83. index += sprintf( buf+index, format.c_str(), u );
  84. break;
  85. case 'c':
  86. i = va_arg( argPtr, long );
  87. index += sprintf( buf+index, format.c_str(), (char) i );
  88. break;
  89. case 's':
  90. str = va_arg( argPtr, char * );
  91. index += sprintf( buf+index, format.c_str(), str );
  92. break;
  93. case '%':
  94. index += sprintf( buf+index, format.c_str() ); //-V618
  95. break;
  96. default:
  97. common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() );
  98. break;
  99. }
  100. fmt++;
  101. break;
  102. case '\\':
  103. fmt++;
  104. switch( *fmt ) {
  105. case 't':
  106. index += sprintf( buf+index, "\t" );
  107. break;
  108. case 'v':
  109. index += sprintf( buf+index, "\v" );
  110. break;
  111. case 'n':
  112. index += sprintf( buf+index, "\n" );
  113. break;
  114. case '\\':
  115. index += sprintf( buf+index, "\\" );
  116. break;
  117. default:
  118. common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt );
  119. break;
  120. }
  121. fmt++;
  122. break;
  123. default:
  124. index += sprintf( buf+index, "%c", *fmt );
  125. fmt++;
  126. break;
  127. }
  128. }
  129. return index;
  130. }
  131. /*
  132. =================================================================================
  133. idFile
  134. =================================================================================
  135. */
  136. /*
  137. =================
  138. idFile::GetName
  139. =================
  140. */
  141. const char *idFile::GetName() const {
  142. return "";
  143. }
  144. /*
  145. =================
  146. idFile::GetFullPath
  147. =================
  148. */
  149. const char *idFile::GetFullPath() const {
  150. return "";
  151. }
  152. /*
  153. =================
  154. idFile::Read
  155. =================
  156. */
  157. int idFile::Read( void *buffer, int len ) {
  158. common->FatalError( "idFile::Read: cannot read from idFile" );
  159. return 0;
  160. }
  161. /*
  162. =================
  163. idFile::Write
  164. =================
  165. */
  166. int idFile::Write( const void *buffer, int len ) {
  167. common->FatalError( "idFile::Write: cannot write to idFile" );
  168. return 0;
  169. }
  170. /*
  171. =================
  172. idFile::Length
  173. =================
  174. */
  175. int idFile::Length() const {
  176. return 0;
  177. }
  178. /*
  179. =================
  180. idFile::Timestamp
  181. =================
  182. */
  183. ID_TIME_T idFile::Timestamp() const {
  184. return 0;
  185. }
  186. /*
  187. =================
  188. idFile::Tell
  189. =================
  190. */
  191. int idFile::Tell() const {
  192. return 0;
  193. }
  194. /*
  195. =================
  196. idFile::ForceFlush
  197. =================
  198. */
  199. void idFile::ForceFlush() {
  200. }
  201. /*
  202. =================
  203. idFile::Flush
  204. =================
  205. */
  206. void idFile::Flush() {
  207. }
  208. /*
  209. =================
  210. idFile::Seek
  211. =================
  212. */
  213. int idFile::Seek( long offset, fsOrigin_t origin ) {
  214. return -1;
  215. }
  216. /*
  217. =================
  218. idFile::Rewind
  219. =================
  220. */
  221. void idFile::Rewind() {
  222. Seek( 0, FS_SEEK_SET );
  223. }
  224. /*
  225. =================
  226. idFile::Printf
  227. =================
  228. */
  229. int idFile::Printf( const char *fmt, ... ) {
  230. char buf[MAX_PRINT_MSG];
  231. int length;
  232. va_list argptr;
  233. va_start( argptr, fmt );
  234. length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, argptr );
  235. va_end( argptr );
  236. // so notepad formats the lines correctly
  237. idStr work( buf );
  238. work.Replace( "\n", "\r\n" );
  239. return Write( work.c_str(), work.Length() );
  240. }
  241. /*
  242. =================
  243. idFile::VPrintf
  244. =================
  245. */
  246. int idFile::VPrintf( const char *fmt, va_list args ) {
  247. char buf[MAX_PRINT_MSG];
  248. int length;
  249. length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, args );
  250. return Write( buf, length );
  251. }
  252. /*
  253. =================
  254. idFile::WriteFloatString
  255. =================
  256. */
  257. int idFile::WriteFloatString( const char *fmt, ... ) {
  258. char buf[MAX_PRINT_MSG];
  259. int len;
  260. va_list argPtr;
  261. va_start( argPtr, fmt );
  262. len = FS_WriteFloatString( buf, fmt, argPtr );
  263. va_end( argPtr );
  264. return Write( buf, len );
  265. }
  266. /*
  267. =================
  268. idFile::ReadInt
  269. =================
  270. */
  271. int idFile::ReadInt( int &value ) {
  272. int result = Read( &value, sizeof( value ) );
  273. value = LittleLong(value);
  274. return result;
  275. }
  276. /*
  277. =================
  278. idFile::ReadUnsignedInt
  279. =================
  280. */
  281. int idFile::ReadUnsignedInt( unsigned int &value ) {
  282. int result = Read( &value, sizeof( value ) );
  283. value = LittleLong(value);
  284. return result;
  285. }
  286. /*
  287. =================
  288. idFile::ReadShort
  289. =================
  290. */
  291. int idFile::ReadShort( short &value ) {
  292. int result = Read( &value, sizeof( value ) );
  293. value = LittleShort(value);
  294. return result;
  295. }
  296. /*
  297. =================
  298. idFile::ReadUnsignedShort
  299. =================
  300. */
  301. int idFile::ReadUnsignedShort( unsigned short &value ) {
  302. int result = Read( &value, sizeof( value ) );
  303. value = LittleShort(value);
  304. return result;
  305. }
  306. /*
  307. =================
  308. idFile::ReadChar
  309. =================
  310. */
  311. int idFile::ReadChar( char &value ) {
  312. return Read( &value, sizeof( value ) );
  313. }
  314. /*
  315. =================
  316. idFile::ReadUnsignedChar
  317. =================
  318. */
  319. int idFile::ReadUnsignedChar( unsigned char &value ) {
  320. return Read( &value, sizeof( value ) );
  321. }
  322. /*
  323. =================
  324. idFile::ReadFloat
  325. =================
  326. */
  327. int idFile::ReadFloat( float &value ) {
  328. int result = Read( &value, sizeof( value ) );
  329. value = LittleFloat(value);
  330. return result;
  331. }
  332. /*
  333. =================
  334. idFile::ReadBool
  335. =================
  336. */
  337. int idFile::ReadBool( bool &value ) {
  338. unsigned char c;
  339. int result = ReadUnsignedChar( c );
  340. value = c ? true : false;
  341. return result;
  342. }
  343. /*
  344. =================
  345. idFile::ReadString
  346. =================
  347. */
  348. int idFile::ReadString( idStr &string ) {
  349. int len;
  350. int result = 0;
  351. ReadInt( len );
  352. if ( len >= 0 ) {
  353. string.Fill( ' ', len );
  354. result = Read( &string[ 0 ], len );
  355. }
  356. return result;
  357. }
  358. /*
  359. =================
  360. idFile::ReadVec2
  361. =================
  362. */
  363. int idFile::ReadVec2( idVec2 &vec ) {
  364. int result = Read( &vec, sizeof( vec ) );
  365. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  366. return result;
  367. }
  368. /*
  369. =================
  370. idFile::ReadVec3
  371. =================
  372. */
  373. int idFile::ReadVec3( idVec3 &vec ) {
  374. int result = Read( &vec, sizeof( vec ) );
  375. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  376. return result;
  377. }
  378. /*
  379. =================
  380. idFile::ReadVec4
  381. =================
  382. */
  383. int idFile::ReadVec4( idVec4 &vec ) {
  384. int result = Read( &vec, sizeof( vec ) );
  385. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  386. return result;
  387. }
  388. /*
  389. =================
  390. idFile::ReadVec6
  391. =================
  392. */
  393. int idFile::ReadVec6( idVec6 &vec ) {
  394. int result = Read( &vec, sizeof( vec ) );
  395. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  396. return result;
  397. }
  398. /*
  399. =================
  400. idFile::ReadMat3
  401. =================
  402. */
  403. int idFile::ReadMat3( idMat3 &mat ) {
  404. int result = Read( &mat, sizeof( mat ) );
  405. LittleRevBytes( &mat, sizeof(float), sizeof(mat)/sizeof(float) );
  406. return result;
  407. }
  408. /*
  409. =================
  410. idFile::WriteInt
  411. =================
  412. */
  413. int idFile::WriteInt( const int value ) {
  414. int v = LittleLong(value);
  415. return Write( &v, sizeof( v ) );
  416. }
  417. /*
  418. =================
  419. idFile::WriteUnsignedInt
  420. =================
  421. */
  422. int idFile::WriteUnsignedInt( const unsigned int value ) {
  423. unsigned int v = LittleLong(value);
  424. return Write( &v, sizeof( v ) );
  425. }
  426. /*
  427. =================
  428. idFile::WriteShort
  429. =================
  430. */
  431. int idFile::WriteShort( const short value ) {
  432. short v = LittleShort(value);
  433. return Write( &v, sizeof( v ) );
  434. }
  435. /*
  436. =================
  437. idFile::WriteUnsignedShort
  438. =================
  439. */
  440. int idFile::WriteUnsignedShort( const unsigned short value ) {
  441. unsigned short v = LittleShort(value);
  442. return Write( &v, sizeof( v ) );
  443. }
  444. /*
  445. =================
  446. idFile::WriteChar
  447. =================
  448. */
  449. int idFile::WriteChar( const char value ) {
  450. return Write( &value, sizeof( value ) );
  451. }
  452. /*
  453. =================
  454. idFile::WriteUnsignedChar
  455. =================
  456. */
  457. int idFile::WriteUnsignedChar( const unsigned char value ) {
  458. return Write( &value, sizeof( value ) );
  459. }
  460. /*
  461. =================
  462. idFile::WriteFloat
  463. =================
  464. */
  465. int idFile::WriteFloat( const float value ) {
  466. float v = LittleFloat(value);
  467. return Write( &v, sizeof( v ) );
  468. }
  469. /*
  470. =================
  471. idFile::WriteBool
  472. =================
  473. */
  474. int idFile::WriteBool( const bool value ) {
  475. unsigned char c = value;
  476. return WriteUnsignedChar( c );
  477. }
  478. /*
  479. =================
  480. idFile::WriteString
  481. =================
  482. */
  483. int idFile::WriteString( const char *value ) {
  484. int len = strlen( value );
  485. WriteInt( len );
  486. return Write( value, len );
  487. }
  488. /*
  489. =================
  490. idFile::WriteVec2
  491. =================
  492. */
  493. int idFile::WriteVec2( const idVec2 &vec ) {
  494. idVec2 v = vec;
  495. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  496. return Write( &v, sizeof( v ) );
  497. }
  498. /*
  499. =================
  500. idFile::WriteVec3
  501. =================
  502. */
  503. int idFile::WriteVec3( const idVec3 &vec ) {
  504. idVec3 v = vec;
  505. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  506. return Write( &v, sizeof( v ) );
  507. }
  508. /*
  509. =================
  510. idFile::WriteVec4
  511. =================
  512. */
  513. int idFile::WriteVec4( const idVec4 &vec ) {
  514. idVec4 v = vec;
  515. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  516. return Write( &v, sizeof( v ) );
  517. }
  518. /*
  519. =================
  520. idFile::WriteVec6
  521. =================
  522. */
  523. int idFile::WriteVec6( const idVec6 &vec ) {
  524. idVec6 v = vec;
  525. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  526. return Write( &v, sizeof( v ) );
  527. }
  528. /*
  529. =================
  530. idFile::WriteMat3
  531. =================
  532. */
  533. int idFile::WriteMat3( const idMat3 &mat ) {
  534. idMat3 v = mat;
  535. LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
  536. return Write( &v, sizeof( v ) );
  537. }
  538. /*
  539. =================================================================================
  540. idFile_Memory
  541. =================================================================================
  542. */
  543. /*
  544. =================
  545. idFile_Memory::idFile_Memory
  546. =================
  547. */
  548. idFile_Memory::idFile_Memory() {
  549. name = "*unknown*";
  550. maxSize = 0;
  551. fileSize = 0;
  552. allocated = 0;
  553. granularity = 16384;
  554. mode = ( 1 << FS_WRITE );
  555. filePtr = NULL;
  556. curPtr = NULL;
  557. }
  558. /*
  559. =================
  560. idFile_Memory::idFile_Memory
  561. =================
  562. */
  563. idFile_Memory::idFile_Memory( const char *name ) {
  564. this->name = name;
  565. maxSize = 0;
  566. fileSize = 0;
  567. allocated = 0;
  568. granularity = 16384;
  569. mode = ( 1 << FS_WRITE );
  570. filePtr = NULL;
  571. curPtr = NULL;
  572. }
  573. /*
  574. =================
  575. idFile_Memory::idFile_Memory
  576. =================
  577. */
  578. idFile_Memory::idFile_Memory( const char *name, char *data, int length ) {
  579. this->name = name;
  580. maxSize = length;
  581. fileSize = 0;
  582. allocated = length;
  583. granularity = 16384;
  584. mode = ( 1 << FS_WRITE );
  585. filePtr = data;
  586. curPtr = data;
  587. }
  588. /*
  589. =================
  590. idFile_Memory::idFile_Memory
  591. =================
  592. */
  593. idFile_Memory::idFile_Memory( const char *name, const char *data, int length ) {
  594. this->name = name;
  595. maxSize = 0;
  596. fileSize = length;
  597. allocated = 0;
  598. granularity = 16384;
  599. mode = ( 1 << FS_READ );
  600. filePtr = const_cast<char *>(data);
  601. curPtr = const_cast<char *>(data);
  602. }
  603. /*
  604. =================
  605. idFile_Memory::TakeDataOwnership
  606. this also makes the file read only
  607. =================
  608. */
  609. void idFile_Memory::TakeDataOwnership() {
  610. if ( filePtr != NULL && fileSize > 0 ) {
  611. maxSize = 0;
  612. mode = ( 1 << FS_READ );
  613. allocated = fileSize;
  614. }
  615. }
  616. /*
  617. =================
  618. idFile_Memory::~idFile_Memory
  619. =================
  620. */
  621. idFile_Memory::~idFile_Memory() {
  622. if ( filePtr && allocated > 0 && maxSize == 0 ) {
  623. Mem_Free( filePtr );
  624. }
  625. }
  626. /*
  627. =================
  628. idFile_Memory::Read
  629. =================
  630. */
  631. int idFile_Memory::Read( void *buffer, int len ) {
  632. if ( !( mode & ( 1 << FS_READ ) ) ) {
  633. common->FatalError( "idFile_Memory::Read: %s not opened in read mode", name.c_str() );
  634. return 0;
  635. }
  636. if ( curPtr + len > filePtr + fileSize ) {
  637. len = filePtr + fileSize - curPtr;
  638. }
  639. memcpy( buffer, curPtr, len );
  640. curPtr += len;
  641. return len;
  642. }
  643. idCVar memcpyImpl( "memcpyImpl", "0", 0, "Which implementation of memcpy to use for idFile_Memory::Write() [0/1 - standard (1 eliminates branch misprediction), 2 - auto-vectorized]" );
  644. void * memcpy2( void * __restrict b, const void * __restrict a, size_t n ) {
  645. char * s1 = (char *)b;
  646. const char * s2 = (const char *)a;
  647. for ( ; 0 < n; --n ) {
  648. *s1++ = *s2++;
  649. }
  650. return b;
  651. }
  652. /*
  653. =================
  654. idFile_Memory::Write
  655. =================
  656. */
  657. idHashTableT< int, int > histogram;
  658. CONSOLE_COMMAND( outputHistogram, "", 0 ) {
  659. for ( int i = 0; i < histogram.Num(); i++ ) {
  660. int key;
  661. histogram.GetIndexKey( i, key );
  662. int * value = histogram.GetIndex( i );
  663. idLib::Printf( "%d\t%d\n", key, *value );
  664. }
  665. }
  666. CONSOLE_COMMAND( clearHistogram, "", 0 ) {
  667. histogram.Clear();
  668. }
  669. int idFile_Memory::Write( const void *buffer, int len ) {
  670. if ( len == 0 ) {
  671. // ~4% falls into this case for some reason...
  672. return 0;
  673. }
  674. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  675. common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
  676. return 0;
  677. }
  678. int alloc = curPtr + len + 1 - filePtr - allocated; // need room for len+1
  679. if ( alloc > 0 ) {
  680. if ( maxSize != 0 ) {
  681. common->Error( "idFile_Memory::Write: exceeded maximum size %d", maxSize );
  682. return 0;
  683. }
  684. int extra = granularity * ( 1 + alloc / granularity );
  685. char *newPtr = (char *) Mem_Alloc( allocated + extra, TAG_IDFILE );
  686. if ( allocated ) {
  687. memcpy( newPtr, filePtr, allocated );
  688. }
  689. allocated += extra;
  690. curPtr = newPtr + ( curPtr - filePtr );
  691. if ( filePtr ) {
  692. Mem_Free( filePtr );
  693. }
  694. filePtr = newPtr;
  695. }
  696. //memcpy( curPtr, buffer, len );
  697. memcpy2( curPtr, buffer, len );
  698. #if 0
  699. if ( memcpyImpl.GetInteger() == 0 ) {
  700. memcpy( curPtr, buffer, len );
  701. } else if ( memcpyImpl.GetInteger() == 1 ) {
  702. memcpy( curPtr, buffer, len );
  703. } else if ( memcpyImpl.GetInteger() == 2 ) {
  704. memcpy2( curPtr, buffer, len );
  705. }
  706. #endif
  707. #if 0
  708. int * value;
  709. if ( histogram.Get( len, &value ) && value != NULL ) {
  710. (*value)++;
  711. } else {
  712. histogram.Set( len, 1 );
  713. }
  714. #endif
  715. curPtr += len;
  716. fileSize += len;
  717. filePtr[ fileSize ] = 0; // len + 1
  718. return len;
  719. }
  720. /*
  721. =================
  722. idFile_Memory::Length
  723. =================
  724. */
  725. int idFile_Memory::Length() const {
  726. return fileSize;
  727. }
  728. /*
  729. ========================
  730. idFile_Memory::SetLength
  731. ========================
  732. */
  733. void idFile_Memory::SetLength( size_t len ) {
  734. PreAllocate( len );
  735. fileSize = len;
  736. }
  737. /*
  738. ========================
  739. idFile_Memory::PreAllocate
  740. ========================
  741. */
  742. void idFile_Memory::PreAllocate( size_t len ) {
  743. if ( len > allocated ) {
  744. if ( maxSize != 0 ) {
  745. idLib::Error( "idFile_Memory::SetLength: exceeded maximum size %d", maxSize );
  746. }
  747. char * newPtr = (char *)Mem_Alloc( len, TAG_IDFILE );
  748. if ( allocated > 0 ) {
  749. memcpy( newPtr, filePtr, allocated );
  750. }
  751. allocated = len;
  752. curPtr = newPtr + ( curPtr - filePtr );
  753. if ( filePtr != NULL ) {
  754. Mem_Free( filePtr );
  755. }
  756. filePtr = newPtr;
  757. }
  758. }
  759. /*
  760. =================
  761. idFile_Memory::Timestamp
  762. =================
  763. */
  764. ID_TIME_T idFile_Memory::Timestamp() const {
  765. return 0;
  766. }
  767. /*
  768. =================
  769. idFile_Memory::Tell
  770. =================
  771. */
  772. int idFile_Memory::Tell() const {
  773. return ( curPtr - filePtr );
  774. }
  775. /*
  776. =================
  777. idFile_Memory::ForceFlush
  778. =================
  779. */
  780. void idFile_Memory::ForceFlush() {
  781. }
  782. /*
  783. =================
  784. idFile_Memory::Flush
  785. =================
  786. */
  787. void idFile_Memory::Flush() {
  788. }
  789. /*
  790. =================
  791. idFile_Memory::Seek
  792. returns zero on success and -1 on failure
  793. =================
  794. */
  795. int idFile_Memory::Seek( long offset, fsOrigin_t origin ) {
  796. switch( origin ) {
  797. case FS_SEEK_CUR: {
  798. curPtr += offset;
  799. break;
  800. }
  801. case FS_SEEK_END: {
  802. curPtr = filePtr + fileSize - offset;
  803. break;
  804. }
  805. case FS_SEEK_SET: {
  806. curPtr = filePtr + offset;
  807. break;
  808. }
  809. default: {
  810. common->FatalError( "idFile_Memory::Seek: bad origin for %s\n", name.c_str() );
  811. return -1;
  812. }
  813. }
  814. if ( curPtr < filePtr ) {
  815. curPtr = filePtr;
  816. return -1;
  817. }
  818. if ( curPtr > filePtr + fileSize ) {
  819. curPtr = filePtr + fileSize;
  820. return -1;
  821. }
  822. return 0;
  823. }
  824. /*
  825. ========================
  826. idFile_Memory::SetMaxLength
  827. ========================
  828. */
  829. void idFile_Memory::SetMaxLength( size_t len ) {
  830. size_t oldLength = fileSize;
  831. SetLength( len );
  832. maxSize = len;
  833. fileSize = oldLength;
  834. }
  835. /*
  836. =================
  837. idFile_Memory::MakeReadOnly
  838. =================
  839. */
  840. void idFile_Memory::MakeReadOnly() {
  841. mode = ( 1 << FS_READ );
  842. Rewind();
  843. }
  844. /*
  845. ========================
  846. idFile_Memory::MakeWritable
  847. ========================
  848. */
  849. void idFile_Memory::MakeWritable() {
  850. mode = ( 1 << FS_WRITE );
  851. Rewind();
  852. }
  853. /*
  854. =================
  855. idFile_Memory::Clear
  856. =================
  857. */
  858. void idFile_Memory::Clear( bool freeMemory ) {
  859. fileSize = 0;
  860. granularity = 16384;
  861. if ( freeMemory ) {
  862. allocated = 0;
  863. Mem_Free( filePtr );
  864. filePtr = NULL;
  865. curPtr = NULL;
  866. } else {
  867. curPtr = filePtr;
  868. }
  869. }
  870. /*
  871. =================
  872. idFile_Memory::SetData
  873. =================
  874. */
  875. void idFile_Memory::SetData( const char *data, int length ) {
  876. maxSize = 0;
  877. fileSize = length;
  878. allocated = 0;
  879. granularity = 16384;
  880. mode = ( 1 << FS_READ );
  881. filePtr = const_cast<char *>(data);
  882. curPtr = const_cast<char *>(data);
  883. }
  884. /*
  885. ========================
  886. idFile_Memory::TruncateData
  887. ========================
  888. */
  889. void idFile_Memory::TruncateData( size_t len ) {
  890. if ( len > allocated ) {
  891. idLib::Error( "idFile_Memory::TruncateData: len (%d) exceeded allocated size (%d)", len, allocated );
  892. } else {
  893. fileSize = len;
  894. }
  895. }
  896. /*
  897. =================================================================================
  898. idFile_BitMsg
  899. =================================================================================
  900. */
  901. /*
  902. =================
  903. idFile_BitMsg::idFile_BitMsg
  904. =================
  905. */
  906. idFile_BitMsg::idFile_BitMsg( idBitMsg &msg ) {
  907. name = "*unknown*";
  908. mode = ( 1 << FS_WRITE );
  909. this->msg = &msg;
  910. }
  911. /*
  912. =================
  913. idFile_BitMsg::idFile_BitMsg
  914. =================
  915. */
  916. idFile_BitMsg::idFile_BitMsg( const idBitMsg &msg ) {
  917. name = "*unknown*";
  918. mode = ( 1 << FS_READ );
  919. this->msg = const_cast<idBitMsg *>(&msg);
  920. }
  921. /*
  922. =================
  923. idFile_BitMsg::~idFile_BitMsg
  924. =================
  925. */
  926. idFile_BitMsg::~idFile_BitMsg() {
  927. }
  928. /*
  929. =================
  930. idFile_BitMsg::Read
  931. =================
  932. */
  933. int idFile_BitMsg::Read( void *buffer, int len ) {
  934. if ( !( mode & ( 1 << FS_READ ) ) ) {
  935. common->FatalError( "idFile_BitMsg::Read: %s not opened in read mode", name.c_str() );
  936. return 0;
  937. }
  938. return msg->ReadData( buffer, len );
  939. }
  940. /*
  941. =================
  942. idFile_BitMsg::Write
  943. =================
  944. */
  945. int idFile_BitMsg::Write( const void *buffer, int len ) {
  946. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  947. common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
  948. return 0;
  949. }
  950. msg->WriteData( buffer, len );
  951. return len;
  952. }
  953. /*
  954. =================
  955. idFile_BitMsg::Length
  956. =================
  957. */
  958. int idFile_BitMsg::Length() const {
  959. return msg->GetSize();
  960. }
  961. /*
  962. =================
  963. idFile_BitMsg::Timestamp
  964. =================
  965. */
  966. ID_TIME_T idFile_BitMsg::Timestamp() const {
  967. return 0;
  968. }
  969. /*
  970. =================
  971. idFile_BitMsg::Tell
  972. =================
  973. */
  974. int idFile_BitMsg::Tell() const {
  975. if ( mode == FS_READ ) {
  976. return msg->GetReadCount();
  977. } else {
  978. return msg->GetSize();
  979. }
  980. }
  981. /*
  982. =================
  983. idFile_BitMsg::ForceFlush
  984. =================
  985. */
  986. void idFile_BitMsg::ForceFlush() {
  987. }
  988. /*
  989. =================
  990. idFile_BitMsg::Flush
  991. =================
  992. */
  993. void idFile_BitMsg::Flush() {
  994. }
  995. /*
  996. =================
  997. idFile_BitMsg::Seek
  998. returns zero on success and -1 on failure
  999. =================
  1000. */
  1001. int idFile_BitMsg::Seek( long offset, fsOrigin_t origin ) {
  1002. return -1;
  1003. }
  1004. /*
  1005. =================================================================================
  1006. idFile_Permanent
  1007. =================================================================================
  1008. */
  1009. /*
  1010. =================
  1011. idFile_Permanent::idFile_Permanent
  1012. =================
  1013. */
  1014. idFile_Permanent::idFile_Permanent() {
  1015. name = "invalid";
  1016. o = NULL;
  1017. mode = 0;
  1018. fileSize = 0;
  1019. handleSync = false;
  1020. }
  1021. /*
  1022. =================
  1023. idFile_Permanent::~idFile_Permanent
  1024. =================
  1025. */
  1026. idFile_Permanent::~idFile_Permanent() {
  1027. if ( o ) {
  1028. CloseHandle( o );
  1029. }
  1030. }
  1031. /*
  1032. =================
  1033. idFile_Permanent::Read
  1034. Properly handles partial reads
  1035. =================
  1036. */
  1037. int idFile_Permanent::Read( void *buffer, int len ) {
  1038. int block, remaining;
  1039. int read;
  1040. byte * buf;
  1041. int tries;
  1042. if ( !(mode & ( 1 << FS_READ ) ) ) {
  1043. common->FatalError( "idFile_Permanent::Read: %s not opened in read mode", name.c_str() );
  1044. return 0;
  1045. }
  1046. if ( !o ) {
  1047. return 0;
  1048. }
  1049. buf = (byte *)buffer;
  1050. remaining = len;
  1051. tries = 0;
  1052. while( remaining ) {
  1053. block = remaining;
  1054. DWORD bytesRead;
  1055. if ( !ReadFile( o, buf, block, &bytesRead, NULL ) ) {
  1056. idLib::Warning( "idFile_Permanent::Read failed with %d from %s", GetLastError(), name.c_str() );
  1057. }
  1058. read = bytesRead;
  1059. if ( read == 0 ) {
  1060. // we might have been trying to read from a CD, which
  1061. // sometimes returns a 0 read on windows
  1062. if ( !tries ) {
  1063. tries = 1;
  1064. }
  1065. else {
  1066. return len-remaining;
  1067. }
  1068. }
  1069. if ( read == -1 ) {
  1070. common->FatalError( "idFile_Permanent::Read: -1 bytes read from %s", name.c_str() );
  1071. }
  1072. remaining -= read;
  1073. buf += read;
  1074. }
  1075. return len;
  1076. }
  1077. /*
  1078. =================
  1079. idFile_Permanent::Write
  1080. Properly handles partial writes
  1081. =================
  1082. */
  1083. int idFile_Permanent::Write( const void *buffer, int len ) {
  1084. int block, remaining;
  1085. int written;
  1086. byte * buf;
  1087. int tries;
  1088. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  1089. common->FatalError( "idFile_Permanent::Write: %s not opened in write mode", name.c_str() );
  1090. return 0;
  1091. }
  1092. if ( !o ) {
  1093. return 0;
  1094. }
  1095. buf = (byte *)buffer;
  1096. remaining = len;
  1097. tries = 0;
  1098. while( remaining ) {
  1099. block = remaining;
  1100. DWORD bytesWritten;
  1101. WriteFile( o, buf, block, &bytesWritten, NULL );
  1102. written = bytesWritten;
  1103. if ( written == 0 ) {
  1104. if ( !tries ) {
  1105. tries = 1;
  1106. }
  1107. else {
  1108. common->Printf( "idFile_Permanent::Write: 0 bytes written to %s\n", name.c_str() );
  1109. return 0;
  1110. }
  1111. }
  1112. if ( written == -1 ) {
  1113. common->Printf( "idFile_Permanent::Write: -1 bytes written to %s\n", name.c_str() );
  1114. return 0;
  1115. }
  1116. remaining -= written;
  1117. buf += written;
  1118. fileSize += written;
  1119. }
  1120. if ( handleSync ) {
  1121. Flush();
  1122. }
  1123. return len;
  1124. }
  1125. /*
  1126. =================
  1127. idFile_Permanent::ForceFlush
  1128. =================
  1129. */
  1130. void idFile_Permanent::ForceFlush() {
  1131. FlushFileBuffers( o );
  1132. }
  1133. /*
  1134. =================
  1135. idFile_Permanent::Flush
  1136. =================
  1137. */
  1138. void idFile_Permanent::Flush() {
  1139. FlushFileBuffers( o );
  1140. }
  1141. /*
  1142. =================
  1143. idFile_Permanent::Tell
  1144. =================
  1145. */
  1146. int idFile_Permanent::Tell() const {
  1147. return SetFilePointer( o, 0, NULL, FILE_CURRENT );
  1148. }
  1149. /*
  1150. ================
  1151. idFile_Permanent::Length
  1152. ================
  1153. */
  1154. int idFile_Permanent::Length() const {
  1155. return fileSize;
  1156. }
  1157. /*
  1158. ================
  1159. idFile_Permanent::Timestamp
  1160. ================
  1161. */
  1162. ID_TIME_T idFile_Permanent::Timestamp() const {
  1163. ID_TIME_T ts = Sys_FileTimeStamp( o );
  1164. return ts;
  1165. }
  1166. /*
  1167. =================
  1168. idFile_Permanent::Seek
  1169. returns zero on success and -1 on failure
  1170. =================
  1171. */
  1172. int idFile_Permanent::Seek( long offset, fsOrigin_t origin ) {
  1173. int retVal = INVALID_SET_FILE_POINTER;
  1174. switch( origin ) {
  1175. case FS_SEEK_CUR: retVal = SetFilePointer( o, offset, NULL, FILE_CURRENT ); break;
  1176. case FS_SEEK_END: retVal = SetFilePointer( o, offset, NULL, FILE_END ); break;
  1177. case FS_SEEK_SET: retVal = SetFilePointer( o, offset, NULL, FILE_BEGIN ); break;
  1178. }
  1179. return ( retVal == INVALID_SET_FILE_POINTER ) ? -1 : 0;
  1180. }
  1181. #if 1
  1182. /*
  1183. =================================================================================
  1184. idFile_Cached
  1185. =================================================================================
  1186. */
  1187. /*
  1188. =================
  1189. idFile_Cached::idFile_Cached
  1190. =================
  1191. */
  1192. idFile_Cached::idFile_Cached() : idFile_Permanent() {
  1193. internalFilePos = 0;
  1194. bufferedStartOffset = 0;
  1195. bufferedEndOffset = 0;
  1196. buffered = NULL;
  1197. }
  1198. /*
  1199. =================
  1200. idFile_Cached::~idFile_Cached
  1201. =================
  1202. */
  1203. idFile_Cached::~idFile_Cached() {
  1204. Mem_Free( buffered );
  1205. }
  1206. /*
  1207. =================
  1208. idFile_ReadBuffered::BufferData
  1209. Buffer a section of the file
  1210. =================
  1211. */
  1212. void idFile_Cached::CacheData( uint64 offset, uint64 length ) {
  1213. Mem_Free( buffered );
  1214. bufferedStartOffset = offset;
  1215. bufferedEndOffset = offset + length;
  1216. buffered = ( byte* )Mem_Alloc( length, TAG_RESOURCE );
  1217. if ( buffered == NULL ) {
  1218. return;
  1219. }
  1220. int internalFilePos = idFile_Permanent::Tell();
  1221. idFile_Permanent::Seek( offset, FS_SEEK_SET );
  1222. idFile_Permanent::Read( buffered, length );
  1223. idFile_Permanent::Seek( internalFilePos, FS_SEEK_SET );
  1224. }
  1225. /*
  1226. =================
  1227. idFile_ReadBuffered::Read
  1228. =================
  1229. */
  1230. int idFile_Cached::Read( void *buffer, int len ) {
  1231. if ( internalFilePos >= bufferedStartOffset && internalFilePos + len < bufferedEndOffset ) {
  1232. // this is in the buffer
  1233. memcpy( buffer, (void*)&buffered[ internalFilePos - bufferedStartOffset ], len );
  1234. internalFilePos += len;
  1235. return len;
  1236. }
  1237. int read = idFile_Permanent::Read( buffer, len );
  1238. if ( read != -1 ) {
  1239. internalFilePos += ( int64 )read;
  1240. }
  1241. return read;
  1242. }
  1243. /*
  1244. =================
  1245. idFile_Cached::Tell
  1246. =================
  1247. */
  1248. int idFile_Cached::Tell() const {
  1249. return internalFilePos;
  1250. }
  1251. /*
  1252. =================
  1253. idFile_Cached::Seek
  1254. returns zero on success and -1 on failure
  1255. =================
  1256. */
  1257. int idFile_Cached::Seek( long offset, fsOrigin_t origin ) {
  1258. if ( origin == FS_SEEK_SET && offset >= bufferedStartOffset && offset < bufferedEndOffset ) {
  1259. // don't do anything to the actual file ptr, just update or internal position
  1260. internalFilePos = offset;
  1261. return 0;
  1262. }
  1263. int retVal = idFile_Permanent::Seek( offset, origin );
  1264. internalFilePos = idFile_Permanent::Tell();
  1265. return retVal;
  1266. }
  1267. #endif
  1268. /*
  1269. =================================================================================
  1270. idFile_InZip
  1271. =================================================================================
  1272. */
  1273. /*
  1274. =================
  1275. idFile_InZip::idFile_InZip
  1276. =================
  1277. */
  1278. idFile_InZip::idFile_InZip() {
  1279. name = "invalid";
  1280. zipFilePos = 0;
  1281. fileSize = 0;
  1282. memset( &z, 0, sizeof( z ) );
  1283. }
  1284. /*
  1285. =================
  1286. idFile_InZip::~idFile_InZip
  1287. =================
  1288. */
  1289. idFile_InZip::~idFile_InZip() {
  1290. unzCloseCurrentFile( z );
  1291. unzClose( z );
  1292. }
  1293. /*
  1294. =================
  1295. idFile_InZip::Read
  1296. Properly handles partial reads
  1297. =================
  1298. */
  1299. int idFile_InZip::Read( void *buffer, int len ) {
  1300. int l = unzReadCurrentFile( z, buffer, len );
  1301. return l;
  1302. }
  1303. /*
  1304. =================
  1305. idFile_InZip::Write
  1306. =================
  1307. */
  1308. int idFile_InZip::Write( const void *buffer, int len ) {
  1309. common->FatalError( "idFile_InZip::Write: cannot write to the zipped file %s", name.c_str() );
  1310. return 0;
  1311. }
  1312. /*
  1313. =================
  1314. idFile_InZip::ForceFlush
  1315. =================
  1316. */
  1317. void idFile_InZip::ForceFlush() {
  1318. common->FatalError( "idFile_InZip::ForceFlush: cannot flush the zipped file %s", name.c_str() );
  1319. }
  1320. /*
  1321. =================
  1322. idFile_InZip::Flush
  1323. =================
  1324. */
  1325. void idFile_InZip::Flush() {
  1326. common->FatalError( "idFile_InZip::Flush: cannot flush the zipped file %s", name.c_str() );
  1327. }
  1328. /*
  1329. =================
  1330. idFile_InZip::Tell
  1331. =================
  1332. */
  1333. int idFile_InZip::Tell() const {
  1334. return unztell( z );
  1335. }
  1336. /*
  1337. ================
  1338. idFile_InZip::Length
  1339. ================
  1340. */
  1341. int idFile_InZip::Length() const {
  1342. return fileSize;
  1343. }
  1344. /*
  1345. ================
  1346. idFile_InZip::Timestamp
  1347. ================
  1348. */
  1349. ID_TIME_T idFile_InZip::Timestamp() const {
  1350. return 0;
  1351. }
  1352. /*
  1353. =================
  1354. idFile_InZip::Seek
  1355. returns zero on success and -1 on failure
  1356. =================
  1357. */
  1358. #define ZIP_SEEK_BUF_SIZE (1<<15)
  1359. int idFile_InZip::Seek( long offset, fsOrigin_t origin ) {
  1360. int res, i;
  1361. char *buf;
  1362. switch( origin ) {
  1363. case FS_SEEK_END: {
  1364. offset = fileSize - offset;
  1365. }
  1366. case FS_SEEK_SET: {
  1367. // set the file position in the zip file (also sets the current file info)
  1368. unzSetCurrentFileInfoPosition( z, zipFilePos );
  1369. unzOpenCurrentFile( z );
  1370. if ( offset <= 0 ) {
  1371. return 0;
  1372. }
  1373. }
  1374. case FS_SEEK_CUR: {
  1375. buf = (char *) _alloca16( ZIP_SEEK_BUF_SIZE );
  1376. for ( i = 0; i < ( offset - ZIP_SEEK_BUF_SIZE ); i += ZIP_SEEK_BUF_SIZE ) {
  1377. res = unzReadCurrentFile( z, buf, ZIP_SEEK_BUF_SIZE );
  1378. if ( res < ZIP_SEEK_BUF_SIZE ) {
  1379. return -1;
  1380. }
  1381. }
  1382. res = i + unzReadCurrentFile( z, buf, offset - i );
  1383. return ( res == offset ) ? 0 : -1;
  1384. }
  1385. default: {
  1386. common->FatalError( "idFile_InZip::Seek: bad origin for %s\n", name.c_str() );
  1387. break;
  1388. }
  1389. }
  1390. return -1;
  1391. }
  1392. #if 1
  1393. /*
  1394. =================================================================================
  1395. idFile_InnerResource
  1396. =================================================================================
  1397. */
  1398. /*
  1399. =================
  1400. idFile_InnerResource::idFile_InnerResource
  1401. =================
  1402. */
  1403. idFile_InnerResource::idFile_InnerResource( const char *_name, idFile *rezFile, int _offset, int _len ) {
  1404. name = _name;
  1405. offset = _offset;
  1406. length = _len;
  1407. resourceFile = rezFile;
  1408. internalFilePos = 0;
  1409. resourceBuffer = NULL;
  1410. }
  1411. /*
  1412. =================
  1413. idFile_InnerResource::~idFile_InnerResource
  1414. =================
  1415. */
  1416. idFile_InnerResource::~idFile_InnerResource() {
  1417. if ( resourceBuffer != NULL ) {
  1418. fileSystem->FreeResourceBuffer();
  1419. }
  1420. }
  1421. /*
  1422. =================
  1423. idFile_InnerResource::Read
  1424. Properly handles partial reads
  1425. =================
  1426. */
  1427. int idFile_InnerResource::Read( void *buffer, int len ) {
  1428. if ( resourceFile == NULL ) {
  1429. return 0;
  1430. }
  1431. if ( internalFilePos + len > length ) {
  1432. len = length - internalFilePos;
  1433. }
  1434. int read = 0; //fileSystem->ReadFromBGL( resourceFile, (byte*)buffer, offset + internalFilePos, len );
  1435. if ( read != len ) {
  1436. if ( resourceBuffer != NULL ) {
  1437. memcpy( buffer, &resourceBuffer[ internalFilePos ], len );
  1438. read = len;
  1439. } else {
  1440. read = fileSystem->ReadFromBGL( resourceFile, buffer, offset + internalFilePos, len );
  1441. }
  1442. }
  1443. internalFilePos += read;
  1444. return read;
  1445. }
  1446. /*
  1447. =================
  1448. idFile_InnerResource::Tell
  1449. =================
  1450. */
  1451. int idFile_InnerResource::Tell() const {
  1452. return internalFilePos;
  1453. }
  1454. /*
  1455. =================
  1456. idFile_InnerResource::Seek
  1457. returns zero on success and -1 on failure
  1458. =================
  1459. */
  1460. int idFile_InnerResource::Seek( long offset, fsOrigin_t origin ) {
  1461. switch( origin ) {
  1462. case FS_SEEK_END: {
  1463. internalFilePos = length - offset - 1;
  1464. return 0;
  1465. }
  1466. case FS_SEEK_SET: {
  1467. internalFilePos = offset;
  1468. if ( internalFilePos >= 0 && internalFilePos < length ) {
  1469. return 0;
  1470. }
  1471. return -1;
  1472. }
  1473. case FS_SEEK_CUR: {
  1474. internalFilePos += offset;
  1475. if ( internalFilePos >= 0 && internalFilePos < length ) {
  1476. return 0;
  1477. }
  1478. return -1;
  1479. }
  1480. default: {
  1481. common->FatalError( "idFile_InnerResource::Seek: bad origin for %s\n", name.c_str() );
  1482. break;
  1483. }
  1484. }
  1485. return -1;
  1486. }
  1487. #endif
  1488. /*
  1489. ================================================================================================
  1490. idFileLocal
  1491. ================================================================================================
  1492. */
  1493. /*
  1494. ========================
  1495. idFileLocal::~idFileLocal
  1496. Destructor that will destroy (close) the managed file when this wrapper class goes out of scope.
  1497. ========================
  1498. */
  1499. idFileLocal::~idFileLocal() {
  1500. if ( file != NULL ) {
  1501. delete file;
  1502. file = NULL;
  1503. }
  1504. }
  1505. static const char * testEndianNessFilename = "temp.bin";
  1506. struct testEndianNess_t {
  1507. testEndianNess_t() {
  1508. a = 0x12345678;
  1509. b = 0x12345678;
  1510. c = 3.0f;
  1511. d = -4.0f;
  1512. e = "test";
  1513. f = idVec3( 1.0f, 2.0f, -3.0f );
  1514. g = false;
  1515. h = true;
  1516. for ( int index = 0; index < sizeof( i ); index++ ) {
  1517. i[index] = 0x37;
  1518. }
  1519. }
  1520. bool operator==( testEndianNess_t & test ) const {
  1521. return a == test.a &&
  1522. b == test.b &&
  1523. c == test.c &&
  1524. d == test.d &&
  1525. e == test.e &&
  1526. f == test.f &&
  1527. g == test.g &&
  1528. h == test.h &&
  1529. ( memcmp( i, test.i, sizeof( i ) ) == 0 );
  1530. }
  1531. int a;
  1532. unsigned int b;
  1533. float c;
  1534. float d;
  1535. idStr e;
  1536. idVec3 f;
  1537. bool g;
  1538. bool h;
  1539. byte i[10];
  1540. };
  1541. CONSOLE_COMMAND( testEndianNessWrite, "Tests the read/write compatibility between platforms", 0 ) {
  1542. idFileLocal file( fileSystem->OpenFileWrite( testEndianNessFilename ) );
  1543. if ( file == NULL ) {
  1544. idLib::Printf( "Couldn't open the %s testfile.\n", testEndianNessFilename );
  1545. return;
  1546. }
  1547. testEndianNess_t testData;
  1548. file->WriteBig( testData.a );
  1549. file->WriteBig( testData.b );
  1550. file->WriteFloat( testData.c );
  1551. file->WriteFloat( testData.d );
  1552. file->WriteString( testData.e );
  1553. file->WriteVec3( testData.f );
  1554. file->WriteBig( testData.g );
  1555. file->WriteBig( testData.h );
  1556. file->Write( testData.i, sizeof( testData.i )/ sizeof( testData.i[0] ) );
  1557. }
  1558. CONSOLE_COMMAND( testEndianNessRead, "Tests the read/write compatibility between platforms", 0 ) {
  1559. idFileLocal file( fileSystem->OpenFileRead( testEndianNessFilename ) );
  1560. if ( file == NULL ) {
  1561. idLib::Printf( "Couldn't find the %s testfile.\n", testEndianNessFilename );
  1562. return;
  1563. }
  1564. testEndianNess_t srcData;
  1565. testEndianNess_t testData;
  1566. memset( &testData, 0, sizeof( testData ) );
  1567. file->ReadBig( testData.a );
  1568. file->ReadBig( testData.b );
  1569. file->ReadFloat( testData.c );
  1570. file->ReadFloat( testData.d );
  1571. file->ReadString( testData.e );
  1572. file->ReadVec3( testData.f );
  1573. file->ReadBig( testData.g );
  1574. file->ReadBig( testData.h );
  1575. file->Read( testData.i, sizeof( testData.i )/ sizeof( testData.i[0] ) );
  1576. assert( srcData == testData );
  1577. }
  1578. CONSOLE_COMMAND( testEndianNessReset, "Tests the read/write compatibility between platforms", 0 ) {
  1579. fileSystem->RemoveFile( testEndianNessFilename );
  1580. }