File.cpp 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 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 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. #define MAX_PRINT_MSG 4096
  24. /*
  25. =================
  26. FS_WriteFloatString
  27. =================
  28. */
  29. int FS_WriteFloatString( char *buf, const char *fmt, va_list argPtr ) {
  30. long i;
  31. unsigned long u;
  32. double f;
  33. char *str;
  34. int index;
  35. idStr tmp, format;
  36. index = 0;
  37. while( *fmt ) {
  38. switch( *fmt ) {
  39. case '%':
  40. format = "";
  41. format += *fmt++;
  42. while ( (*fmt >= '0' && *fmt <= '9') ||
  43. *fmt == '.' || *fmt == '-' || *fmt == '+' || *fmt == '#') {
  44. format += *fmt++;
  45. }
  46. format += *fmt;
  47. switch( *fmt ) {
  48. case 'f':
  49. case 'e':
  50. case 'E':
  51. case 'g':
  52. case 'G':
  53. f = va_arg( argPtr, double );
  54. if ( format.Length() <= 2 ) {
  55. // high precision floating point number without trailing zeros
  56. sprintf( tmp, "%1.10f", f );
  57. tmp.StripTrailing( '0' );
  58. tmp.StripTrailing( '.' );
  59. index += sprintf( buf+index, "%s", tmp.c_str() );
  60. }
  61. else {
  62. index += sprintf( buf+index, format.c_str(), f );
  63. }
  64. break;
  65. case 'd':
  66. case 'i':
  67. i = va_arg( argPtr, long );
  68. index += sprintf( buf+index, format.c_str(), i );
  69. break;
  70. case 'u':
  71. u = va_arg( argPtr, unsigned long );
  72. index += sprintf( buf+index, format.c_str(), u );
  73. break;
  74. case 'o':
  75. u = va_arg( argPtr, unsigned long );
  76. index += sprintf( buf+index, format.c_str(), u );
  77. break;
  78. case 'x':
  79. u = va_arg( argPtr, unsigned long );
  80. index += sprintf( buf+index, format.c_str(), u );
  81. break;
  82. case 'X':
  83. u = va_arg( argPtr, unsigned long );
  84. index += sprintf( buf+index, format.c_str(), u );
  85. break;
  86. case 'c':
  87. i = va_arg( argPtr, long );
  88. index += sprintf( buf+index, format.c_str(), (char) i );
  89. break;
  90. case 's':
  91. str = va_arg( argPtr, char * );
  92. index += sprintf( buf+index, format.c_str(), str );
  93. break;
  94. case '%':
  95. index += sprintf( buf+index, format.c_str() );
  96. break;
  97. default:
  98. common->Error( "FS_WriteFloatString: invalid format %s", format.c_str() );
  99. break;
  100. }
  101. fmt++;
  102. break;
  103. case '\\':
  104. fmt++;
  105. switch( *fmt ) {
  106. case 't':
  107. index += sprintf( buf+index, "\t" );
  108. break;
  109. case 'v':
  110. index += sprintf( buf+index, "\v" );
  111. break;
  112. case 'n':
  113. index += sprintf( buf+index, "\n" );
  114. break;
  115. case '\\':
  116. index += sprintf( buf+index, "\\" );
  117. break;
  118. default:
  119. common->Error( "FS_WriteFloatString: unknown escape character \'%c\'", *fmt );
  120. break;
  121. }
  122. fmt++;
  123. break;
  124. default:
  125. index += sprintf( buf+index, "%c", *fmt );
  126. fmt++;
  127. break;
  128. }
  129. }
  130. return index;
  131. }
  132. /*
  133. =================================================================================
  134. idFile
  135. =================================================================================
  136. */
  137. /*
  138. =================
  139. idFile::GetName
  140. =================
  141. */
  142. const char *idFile::GetName( void ) {
  143. return "";
  144. }
  145. /*
  146. =================
  147. idFile::GetFullPath
  148. =================
  149. */
  150. const char *idFile::GetFullPath( void ) {
  151. return "";
  152. }
  153. /*
  154. =================
  155. idFile::Read
  156. =================
  157. */
  158. int idFile::Read( void *buffer, int len ) {
  159. common->FatalError( "idFile::Read: cannot read from idFile" );
  160. return 0;
  161. }
  162. /*
  163. =================
  164. idFile::Write
  165. =================
  166. */
  167. int idFile::Write( const void *buffer, int len ) {
  168. common->FatalError( "idFile::Write: cannot write to idFile" );
  169. return 0;
  170. }
  171. /*
  172. =================
  173. idFile::Length
  174. =================
  175. */
  176. int idFile::Length( void ) {
  177. return 0;
  178. }
  179. /*
  180. =================
  181. idFile::Timestamp
  182. =================
  183. */
  184. ID_TIME_T idFile::Timestamp( void ) {
  185. return 0;
  186. }
  187. /*
  188. =================
  189. idFile::Tell
  190. =================
  191. */
  192. int idFile::Tell( void ) {
  193. return 0;
  194. }
  195. /*
  196. =================
  197. idFile::ForceFlush
  198. =================
  199. */
  200. void idFile::ForceFlush( void ) {
  201. }
  202. /*
  203. =================
  204. idFile::Flush
  205. =================
  206. */
  207. void idFile::Flush( void ) {
  208. }
  209. /*
  210. =================
  211. idFile::Seek
  212. =================
  213. */
  214. int idFile::Seek( long offset, fsOrigin_t origin ) {
  215. return -1;
  216. }
  217. /*
  218. =================
  219. idFile::Rewind
  220. =================
  221. */
  222. void idFile::Rewind( void ) {
  223. Seek( 0, FS_SEEK_SET );
  224. }
  225. /*
  226. =================
  227. idFile::Printf
  228. =================
  229. */
  230. int idFile::Printf( const char *fmt, ... ) {
  231. char buf[MAX_PRINT_MSG];
  232. int length;
  233. va_list argptr;
  234. va_start( argptr, fmt );
  235. length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, argptr );
  236. va_end( argptr );
  237. // so notepad formats the lines correctly
  238. idStr work( buf );
  239. work.Replace( "\n", "\r\n" );
  240. return Write( work.c_str(), work.Length() );
  241. }
  242. /*
  243. =================
  244. idFile::VPrintf
  245. =================
  246. */
  247. int idFile::VPrintf( const char *fmt, va_list args ) {
  248. char buf[MAX_PRINT_MSG];
  249. int length;
  250. length = idStr::vsnPrintf( buf, MAX_PRINT_MSG-1, fmt, args );
  251. return Write( buf, length );
  252. }
  253. /*
  254. =================
  255. idFile::WriteFloatString
  256. =================
  257. */
  258. int idFile::WriteFloatString( const char *fmt, ... ) {
  259. char buf[MAX_PRINT_MSG];
  260. int len;
  261. va_list argPtr;
  262. va_start( argPtr, fmt );
  263. len = FS_WriteFloatString( buf, fmt, argPtr );
  264. va_end( argPtr );
  265. return Write( buf, len );
  266. }
  267. /*
  268. =================
  269. idFile::ReadInt
  270. =================
  271. */
  272. int idFile::ReadInt( int &value ) {
  273. int result = Read( &value, sizeof( value ) );
  274. value = LittleLong(value);
  275. return result;
  276. }
  277. /*
  278. =================
  279. idFile::ReadUnsignedInt
  280. =================
  281. */
  282. int idFile::ReadUnsignedInt( unsigned int &value ) {
  283. int result = Read( &value, sizeof( value ) );
  284. value = LittleLong(value);
  285. return result;
  286. }
  287. /*
  288. =================
  289. idFile::ReadShort
  290. =================
  291. */
  292. int idFile::ReadShort( short &value ) {
  293. int result = Read( &value, sizeof( value ) );
  294. value = LittleShort(value);
  295. return result;
  296. }
  297. /*
  298. =================
  299. idFile::ReadUnsignedShort
  300. =================
  301. */
  302. int idFile::ReadUnsignedShort( unsigned short &value ) {
  303. int result = Read( &value, sizeof( value ) );
  304. value = LittleShort(value);
  305. return result;
  306. }
  307. /*
  308. =================
  309. idFile::ReadChar
  310. =================
  311. */
  312. int idFile::ReadChar( char &value ) {
  313. return Read( &value, sizeof( value ) );
  314. }
  315. /*
  316. =================
  317. idFile::ReadUnsignedChar
  318. =================
  319. */
  320. int idFile::ReadUnsignedChar( unsigned char &value ) {
  321. return Read( &value, sizeof( value ) );
  322. }
  323. /*
  324. =================
  325. idFile::ReadFloat
  326. =================
  327. */
  328. int idFile::ReadFloat( float &value ) {
  329. int result = Read( &value, sizeof( value ) );
  330. value = LittleFloat(value);
  331. return result;
  332. }
  333. /*
  334. =================
  335. idFile::ReadBool
  336. =================
  337. */
  338. int idFile::ReadBool( bool &value ) {
  339. unsigned char c;
  340. int result = ReadUnsignedChar( c );
  341. value = c ? true : false;
  342. return result;
  343. }
  344. /*
  345. =================
  346. idFile::ReadString
  347. =================
  348. */
  349. int idFile::ReadString( idStr &string ) {
  350. int len;
  351. int result = 0;
  352. ReadInt( len );
  353. if ( len >= 0 ) {
  354. string.Fill( ' ', len );
  355. result = Read( &string[ 0 ], len );
  356. }
  357. return result;
  358. }
  359. /*
  360. =================
  361. idFile::ReadVec2
  362. =================
  363. */
  364. int idFile::ReadVec2( idVec2 &vec ) {
  365. int result = Read( &vec, sizeof( vec ) );
  366. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  367. return result;
  368. }
  369. /*
  370. =================
  371. idFile::ReadVec3
  372. =================
  373. */
  374. int idFile::ReadVec3( idVec3 &vec ) {
  375. int result = Read( &vec, sizeof( vec ) );
  376. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  377. return result;
  378. }
  379. /*
  380. =================
  381. idFile::ReadVec4
  382. =================
  383. */
  384. int idFile::ReadVec4( idVec4 &vec ) {
  385. int result = Read( &vec, sizeof( vec ) );
  386. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  387. return result;
  388. }
  389. /*
  390. =================
  391. idFile::ReadVec6
  392. =================
  393. */
  394. int idFile::ReadVec6( idVec6 &vec ) {
  395. int result = Read( &vec, sizeof( vec ) );
  396. LittleRevBytes( &vec, sizeof(float), sizeof(vec)/sizeof(float) );
  397. return result;
  398. }
  399. /*
  400. =================
  401. idFile::ReadMat3
  402. =================
  403. */
  404. int idFile::ReadMat3( idMat3 &mat ) {
  405. int result = Read( &mat, sizeof( mat ) );
  406. LittleRevBytes( &mat, sizeof(float), sizeof(mat)/sizeof(float) );
  407. return result;
  408. }
  409. /*
  410. =================
  411. idFile::WriteInt
  412. =================
  413. */
  414. int idFile::WriteInt( const int value ) {
  415. int v = LittleLong(value);
  416. return Write( &v, sizeof( v ) );
  417. }
  418. /*
  419. =================
  420. idFile::WriteUnsignedInt
  421. =================
  422. */
  423. int idFile::WriteUnsignedInt( const unsigned int value ) {
  424. unsigned int v = LittleLong(value);
  425. return Write( &v, sizeof( v ) );
  426. }
  427. /*
  428. =================
  429. idFile::WriteShort
  430. =================
  431. */
  432. int idFile::WriteShort( const short value ) {
  433. short v = LittleShort(value);
  434. return Write( &v, sizeof( v ) );
  435. }
  436. /*
  437. =================
  438. idFile::WriteUnsignedShort
  439. =================
  440. */
  441. int idFile::WriteUnsignedShort( const unsigned short value ) {
  442. unsigned short v = LittleShort(value);
  443. return Write( &v, sizeof( v ) );
  444. }
  445. /*
  446. =================
  447. idFile::WriteChar
  448. =================
  449. */
  450. int idFile::WriteChar( const char value ) {
  451. return Write( &value, sizeof( value ) );
  452. }
  453. /*
  454. =================
  455. idFile::WriteUnsignedChar
  456. =================
  457. */
  458. int idFile::WriteUnsignedChar( const unsigned char value ) {
  459. return Write( &value, sizeof( value ) );
  460. }
  461. /*
  462. =================
  463. idFile::WriteFloat
  464. =================
  465. */
  466. int idFile::WriteFloat( const float value ) {
  467. float v = LittleFloat(value);
  468. return Write( &v, sizeof( v ) );
  469. }
  470. /*
  471. =================
  472. idFile::WriteBool
  473. =================
  474. */
  475. int idFile::WriteBool( const bool value ) {
  476. unsigned char c = value;
  477. return WriteUnsignedChar( c );
  478. }
  479. /*
  480. =================
  481. idFile::WriteString
  482. =================
  483. */
  484. int idFile::WriteString( const char *value ) {
  485. int len;
  486. len = strlen( value );
  487. WriteInt( len );
  488. return Write( value, len );
  489. }
  490. /*
  491. =================
  492. idFile::WriteVec2
  493. =================
  494. */
  495. int idFile::WriteVec2( const idVec2 &vec ) {
  496. idVec2 v = vec;
  497. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  498. return Write( &v, sizeof( v ) );
  499. }
  500. /*
  501. =================
  502. idFile::WriteVec3
  503. =================
  504. */
  505. int idFile::WriteVec3( const idVec3 &vec ) {
  506. idVec3 v = vec;
  507. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  508. return Write( &v, sizeof( v ) );
  509. }
  510. /*
  511. =================
  512. idFile::WriteVec4
  513. =================
  514. */
  515. int idFile::WriteVec4( const idVec4 &vec ) {
  516. idVec4 v = vec;
  517. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  518. return Write( &v, sizeof( v ) );
  519. }
  520. /*
  521. =================
  522. idFile::WriteVec6
  523. =================
  524. */
  525. int idFile::WriteVec6( const idVec6 &vec ) {
  526. idVec6 v = vec;
  527. LittleRevBytes( &v, sizeof(float), sizeof(v)/sizeof(float) );
  528. return Write( &v, sizeof( v ) );
  529. }
  530. /*
  531. =================
  532. idFile::WriteMat3
  533. =================
  534. */
  535. int idFile::WriteMat3( const idMat3 &mat ) {
  536. idMat3 v = mat;
  537. LittleRevBytes(&v, sizeof(float), sizeof(v)/sizeof(float) );
  538. return Write( &v, sizeof( v ) );
  539. }
  540. /*
  541. =================================================================================
  542. idFile_Memory
  543. =================================================================================
  544. */
  545. /*
  546. =================
  547. idFile_Memory::idFile_Memory
  548. =================
  549. */
  550. idFile_Memory::idFile_Memory( void ) {
  551. name = "*unknown*";
  552. maxSize = 0;
  553. fileSize = 0;
  554. allocated = 0;
  555. granularity = 16384;
  556. mode = ( 1 << FS_WRITE );
  557. filePtr = NULL;
  558. curPtr = NULL;
  559. }
  560. /*
  561. =================
  562. idFile_Memory::idFile_Memory
  563. =================
  564. */
  565. idFile_Memory::idFile_Memory( const char *name ) {
  566. this->name = name;
  567. maxSize = 0;
  568. fileSize = 0;
  569. allocated = 0;
  570. granularity = 16384;
  571. mode = ( 1 << FS_WRITE );
  572. filePtr = NULL;
  573. curPtr = NULL;
  574. }
  575. /*
  576. =================
  577. idFile_Memory::idFile_Memory
  578. =================
  579. */
  580. idFile_Memory::idFile_Memory( const char *name, char *data, int length ) {
  581. this->name = name;
  582. maxSize = length;
  583. fileSize = 0;
  584. allocated = length;
  585. granularity = 16384;
  586. mode = ( 1 << FS_WRITE );
  587. filePtr = data;
  588. curPtr = data;
  589. }
  590. /*
  591. =================
  592. idFile_Memory::idFile_Memory
  593. =================
  594. */
  595. idFile_Memory::idFile_Memory( const char *name, const char *data, int length ) {
  596. this->name = name;
  597. maxSize = 0;
  598. fileSize = length;
  599. allocated = 0;
  600. granularity = 16384;
  601. mode = ( 1 << FS_READ );
  602. filePtr = const_cast<char *>(data);
  603. curPtr = const_cast<char *>(data);
  604. }
  605. /*
  606. =================
  607. idFile_Memory::~idFile_Memory
  608. =================
  609. */
  610. idFile_Memory::~idFile_Memory( void ) {
  611. if ( filePtr && allocated > 0 && maxSize == 0 ) {
  612. Mem_Free( filePtr );
  613. }
  614. }
  615. /*
  616. =================
  617. idFile_Memory::Read
  618. =================
  619. */
  620. int idFile_Memory::Read( void *buffer, int len ) {
  621. if ( !( mode & ( 1 << FS_READ ) ) ) {
  622. common->FatalError( "idFile_Memory::Read: %s not opened in read mode", name.c_str() );
  623. return 0;
  624. }
  625. if ( curPtr + len > filePtr + fileSize ) {
  626. len = filePtr + fileSize - curPtr;
  627. }
  628. memcpy( buffer, curPtr, len );
  629. curPtr += len;
  630. return len;
  631. }
  632. /*
  633. =================
  634. idFile_Memory::Write
  635. =================
  636. */
  637. int idFile_Memory::Write( const void *buffer, int len ) {
  638. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  639. common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
  640. return 0;
  641. }
  642. int alloc = curPtr + len + 1 - filePtr - allocated; // need room for len+1
  643. if ( alloc > 0 ) {
  644. if ( maxSize != 0 ) {
  645. common->Error( "idFile_Memory::Write: exceeded maximum size %d", maxSize );
  646. return 0;
  647. }
  648. int extra = granularity * ( 1 + alloc / granularity );
  649. char *newPtr = (char *) Mem_Alloc( allocated + extra );
  650. if ( allocated ) {
  651. memcpy( newPtr, filePtr, allocated );
  652. }
  653. allocated += extra;
  654. curPtr = newPtr + ( curPtr - filePtr );
  655. if ( filePtr ) {
  656. Mem_Free( filePtr );
  657. }
  658. filePtr = newPtr;
  659. }
  660. memcpy( curPtr, buffer, len );
  661. curPtr += len;
  662. fileSize += len;
  663. filePtr[ fileSize ] = 0; // len + 1
  664. return len;
  665. }
  666. /*
  667. =================
  668. idFile_Memory::Length
  669. =================
  670. */
  671. int idFile_Memory::Length( void ) {
  672. return fileSize;
  673. }
  674. /*
  675. =================
  676. idFile_Memory::Timestamp
  677. =================
  678. */
  679. ID_TIME_T idFile_Memory::Timestamp( void ) {
  680. return 0;
  681. }
  682. /*
  683. =================
  684. idFile_Memory::Tell
  685. =================
  686. */
  687. int idFile_Memory::Tell( void ) {
  688. return ( curPtr - filePtr );
  689. }
  690. /*
  691. =================
  692. idFile_Memory::ForceFlush
  693. =================
  694. */
  695. void idFile_Memory::ForceFlush( void ) {
  696. }
  697. /*
  698. =================
  699. idFile_Memory::Flush
  700. =================
  701. */
  702. void idFile_Memory::Flush( void ) {
  703. }
  704. /*
  705. =================
  706. idFile_Memory::Seek
  707. returns zero on success and -1 on failure
  708. =================
  709. */
  710. int idFile_Memory::Seek( long offset, fsOrigin_t origin ) {
  711. switch( origin ) {
  712. case FS_SEEK_CUR: {
  713. curPtr += offset;
  714. break;
  715. }
  716. case FS_SEEK_END: {
  717. curPtr = filePtr + fileSize - offset;
  718. break;
  719. }
  720. case FS_SEEK_SET: {
  721. curPtr = filePtr + offset;
  722. break;
  723. }
  724. default: {
  725. common->FatalError( "idFile_Memory::Seek: bad origin for %s\n", name.c_str() );
  726. return -1;
  727. }
  728. }
  729. if ( curPtr < filePtr ) {
  730. curPtr = filePtr;
  731. return -1;
  732. }
  733. if ( curPtr > filePtr + fileSize ) {
  734. curPtr = filePtr + fileSize;
  735. return -1;
  736. }
  737. return 0;
  738. }
  739. /*
  740. =================
  741. idFile_Memory::MakeReadOnly
  742. =================
  743. */
  744. void idFile_Memory::MakeReadOnly( void ) {
  745. mode = ( 1 << FS_READ );
  746. Rewind();
  747. }
  748. /*
  749. =================
  750. idFile_Memory::Clear
  751. =================
  752. */
  753. void idFile_Memory::Clear( bool freeMemory ) {
  754. fileSize = 0;
  755. granularity = 16384;
  756. if ( freeMemory ) {
  757. allocated = 0;
  758. Mem_Free( filePtr );
  759. filePtr = NULL;
  760. curPtr = NULL;
  761. } else {
  762. curPtr = filePtr;
  763. }
  764. }
  765. /*
  766. =================
  767. idFile_Memory::SetData
  768. =================
  769. */
  770. void idFile_Memory::SetData( const char *data, int length ) {
  771. maxSize = 0;
  772. fileSize = length;
  773. allocated = 0;
  774. granularity = 16384;
  775. mode = ( 1 << FS_READ );
  776. filePtr = const_cast<char *>(data);
  777. curPtr = const_cast<char *>(data);
  778. }
  779. /*
  780. =================================================================================
  781. idFile_BitMsg
  782. =================================================================================
  783. */
  784. /*
  785. =================
  786. idFile_BitMsg::idFile_BitMsg
  787. =================
  788. */
  789. idFile_BitMsg::idFile_BitMsg( idBitMsg &msg ) {
  790. name = "*unknown*";
  791. mode = ( 1 << FS_WRITE );
  792. this->msg = &msg;
  793. }
  794. /*
  795. =================
  796. idFile_BitMsg::idFile_BitMsg
  797. =================
  798. */
  799. idFile_BitMsg::idFile_BitMsg( const idBitMsg &msg ) {
  800. name = "*unknown*";
  801. mode = ( 1 << FS_READ );
  802. this->msg = const_cast<idBitMsg *>(&msg);
  803. }
  804. /*
  805. =================
  806. idFile_BitMsg::~idFile_BitMsg
  807. =================
  808. */
  809. idFile_BitMsg::~idFile_BitMsg( void ) {
  810. }
  811. /*
  812. =================
  813. idFile_BitMsg::Read
  814. =================
  815. */
  816. int idFile_BitMsg::Read( void *buffer, int len ) {
  817. if ( !( mode & ( 1 << FS_READ ) ) ) {
  818. common->FatalError( "idFile_BitMsg::Read: %s not opened in read mode", name.c_str() );
  819. return 0;
  820. }
  821. return msg->ReadData( buffer, len );
  822. }
  823. /*
  824. =================
  825. idFile_BitMsg::Write
  826. =================
  827. */
  828. int idFile_BitMsg::Write( const void *buffer, int len ) {
  829. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  830. common->FatalError( "idFile_Memory::Write: %s not opened in write mode", name.c_str() );
  831. return 0;
  832. }
  833. msg->WriteData( buffer, len );
  834. return len;
  835. }
  836. /*
  837. =================
  838. idFile_BitMsg::Length
  839. =================
  840. */
  841. int idFile_BitMsg::Length( void ) {
  842. return msg->GetSize();
  843. }
  844. /*
  845. =================
  846. idFile_BitMsg::Timestamp
  847. =================
  848. */
  849. ID_TIME_T idFile_BitMsg::Timestamp( void ) {
  850. return 0;
  851. }
  852. /*
  853. =================
  854. idFile_BitMsg::Tell
  855. =================
  856. */
  857. int idFile_BitMsg::Tell( void ) {
  858. if ( mode & FS_READ ) {
  859. return msg->GetReadCount();
  860. } else {
  861. return msg->GetSize();
  862. }
  863. }
  864. /*
  865. =================
  866. idFile_BitMsg::ForceFlush
  867. =================
  868. */
  869. void idFile_BitMsg::ForceFlush( void ) {
  870. }
  871. /*
  872. =================
  873. idFile_BitMsg::Flush
  874. =================
  875. */
  876. void idFile_BitMsg::Flush( void ) {
  877. }
  878. /*
  879. =================
  880. idFile_BitMsg::Seek
  881. returns zero on success and -1 on failure
  882. =================
  883. */
  884. int idFile_BitMsg::Seek( long offset, fsOrigin_t origin ) {
  885. return -1;
  886. }
  887. /*
  888. =================================================================================
  889. idFile_Permanent
  890. =================================================================================
  891. */
  892. /*
  893. =================
  894. idFile_Permanent::idFile_Permanent
  895. =================
  896. */
  897. idFile_Permanent::idFile_Permanent( void ) {
  898. name = "invalid";
  899. o = NULL;
  900. mode = 0;
  901. fileSize = 0;
  902. handleSync = false;
  903. }
  904. /*
  905. =================
  906. idFile_Permanent::~idFile_Permanent
  907. =================
  908. */
  909. idFile_Permanent::~idFile_Permanent( void ) {
  910. if ( o ) {
  911. fclose( o );
  912. }
  913. }
  914. /*
  915. =================
  916. idFile_Permanent::Read
  917. Properly handles partial reads
  918. =================
  919. */
  920. int idFile_Permanent::Read( void *buffer, int len ) {
  921. int block, remaining;
  922. int read;
  923. byte * buf;
  924. int tries;
  925. if ( !(mode & ( 1 << FS_READ ) ) ) {
  926. common->FatalError( "idFile_Permanent::Read: %s not opened in read mode", name.c_str() );
  927. return 0;
  928. }
  929. if ( !o ) {
  930. return 0;
  931. }
  932. buf = (byte *)buffer;
  933. remaining = len;
  934. tries = 0;
  935. while( remaining ) {
  936. block = remaining;
  937. read = fread( buf, 1, block, o );
  938. if ( read == 0 ) {
  939. // we might have been trying to read from a CD, which
  940. // sometimes returns a 0 read on windows
  941. if ( !tries ) {
  942. tries = 1;
  943. }
  944. else {
  945. fileSystem->AddToReadCount( len - remaining );
  946. return len-remaining;
  947. }
  948. }
  949. if ( read == -1 ) {
  950. common->FatalError( "idFile_Permanent::Read: -1 bytes read from %s", name.c_str() );
  951. }
  952. remaining -= read;
  953. buf += read;
  954. }
  955. fileSystem->AddToReadCount( len );
  956. return len;
  957. }
  958. /*
  959. =================
  960. idFile_Permanent::Write
  961. Properly handles partial writes
  962. =================
  963. */
  964. int idFile_Permanent::Write( const void *buffer, int len ) {
  965. int block, remaining;
  966. int written;
  967. byte * buf;
  968. int tries;
  969. if ( !( mode & ( 1 << FS_WRITE ) ) ) {
  970. common->FatalError( "idFile_Permanent::Write: %s not opened in write mode", name.c_str() );
  971. return 0;
  972. }
  973. if ( !o ) {
  974. return 0;
  975. }
  976. buf = (byte *)buffer;
  977. remaining = len;
  978. tries = 0;
  979. while( remaining ) {
  980. block = remaining;
  981. written = fwrite( buf, 1, block, o );
  982. if ( written == 0 ) {
  983. if ( !tries ) {
  984. tries = 1;
  985. }
  986. else {
  987. common->Printf( "idFile_Permanent::Write: 0 bytes written to %s\n", name.c_str() );
  988. return 0;
  989. }
  990. }
  991. if ( written == -1 ) {
  992. common->Printf( "idFile_Permanent::Write: -1 bytes written to %s\n", name.c_str() );
  993. return 0;
  994. }
  995. remaining -= written;
  996. buf += written;
  997. fileSize += written;
  998. }
  999. if ( handleSync ) {
  1000. fflush( o );
  1001. }
  1002. return len;
  1003. }
  1004. /*
  1005. =================
  1006. idFile_Permanent::ForceFlush
  1007. =================
  1008. */
  1009. void idFile_Permanent::ForceFlush( void ) {
  1010. setvbuf( o, NULL, _IONBF, 0 );
  1011. }
  1012. /*
  1013. =================
  1014. idFile_Permanent::Flush
  1015. =================
  1016. */
  1017. void idFile_Permanent::Flush( void ) {
  1018. fflush( o );
  1019. }
  1020. /*
  1021. =================
  1022. idFile_Permanent::Tell
  1023. =================
  1024. */
  1025. int idFile_Permanent::Tell( void ) {
  1026. return ftell( o );
  1027. }
  1028. /*
  1029. ================
  1030. idFile_Permanent::Length
  1031. ================
  1032. */
  1033. int idFile_Permanent::Length( void ) {
  1034. return fileSize;
  1035. }
  1036. /*
  1037. ================
  1038. idFile_Permanent::Timestamp
  1039. ================
  1040. */
  1041. ID_TIME_T idFile_Permanent::Timestamp( void ) {
  1042. return Sys_FileTimeStamp( o );
  1043. }
  1044. /*
  1045. =================
  1046. idFile_Permanent::Seek
  1047. returns zero on success and -1 on failure
  1048. =================
  1049. */
  1050. int idFile_Permanent::Seek( long offset, fsOrigin_t origin ) {
  1051. int _origin;
  1052. switch( origin ) {
  1053. case FS_SEEK_CUR: {
  1054. _origin = SEEK_CUR;
  1055. break;
  1056. }
  1057. case FS_SEEK_END: {
  1058. _origin = SEEK_END;
  1059. break;
  1060. }
  1061. case FS_SEEK_SET: {
  1062. _origin = SEEK_SET;
  1063. break;
  1064. }
  1065. default: {
  1066. _origin = SEEK_CUR;
  1067. common->FatalError( "idFile_Permanent::Seek: bad origin for %s\n", name.c_str() );
  1068. break;
  1069. }
  1070. }
  1071. return fseek( o, offset, _origin );
  1072. }
  1073. /*
  1074. =================================================================================
  1075. idFile_InZip
  1076. =================================================================================
  1077. */
  1078. /*
  1079. =================
  1080. idFile_InZip::idFile_InZip
  1081. =================
  1082. */
  1083. idFile_InZip::idFile_InZip( void ) {
  1084. name = "invalid";
  1085. zipFilePos = 0;
  1086. fileSize = 0;
  1087. memset( &z, 0, sizeof( z ) );
  1088. }
  1089. /*
  1090. =================
  1091. idFile_InZip::~idFile_InZip
  1092. =================
  1093. */
  1094. idFile_InZip::~idFile_InZip( void ) {
  1095. unzCloseCurrentFile( z );
  1096. unzClose( z );
  1097. }
  1098. /*
  1099. =================
  1100. idFile_InZip::Read
  1101. Properly handles partial reads
  1102. =================
  1103. */
  1104. int idFile_InZip::Read( void *buffer, int len ) {
  1105. int l = unzReadCurrentFile( z, buffer, len );
  1106. fileSystem->AddToReadCount( l );
  1107. return l;
  1108. }
  1109. /*
  1110. =================
  1111. idFile_InZip::Write
  1112. =================
  1113. */
  1114. int idFile_InZip::Write( const void *buffer, int len ) {
  1115. common->FatalError( "idFile_InZip::Write: cannot write to the zipped file %s", name.c_str() );
  1116. return 0;
  1117. }
  1118. /*
  1119. =================
  1120. idFile_InZip::ForceFlush
  1121. =================
  1122. */
  1123. void idFile_InZip::ForceFlush( void ) {
  1124. common->FatalError( "idFile_InZip::ForceFlush: cannot flush the zipped file %s", name.c_str() );
  1125. }
  1126. /*
  1127. =================
  1128. idFile_InZip::Flush
  1129. =================
  1130. */
  1131. void idFile_InZip::Flush( void ) {
  1132. common->FatalError( "idFile_InZip::Flush: cannot flush the zipped file %s", name.c_str() );
  1133. }
  1134. /*
  1135. =================
  1136. idFile_InZip::Tell
  1137. =================
  1138. */
  1139. int idFile_InZip::Tell( void ) {
  1140. return unztell( z );
  1141. }
  1142. /*
  1143. ================
  1144. idFile_InZip::Length
  1145. ================
  1146. */
  1147. int idFile_InZip::Length( void ) {
  1148. return fileSize;
  1149. }
  1150. /*
  1151. ================
  1152. idFile_InZip::Timestamp
  1153. ================
  1154. */
  1155. ID_TIME_T idFile_InZip::Timestamp( void ) {
  1156. return 0;
  1157. }
  1158. /*
  1159. =================
  1160. idFile_InZip::Seek
  1161. returns zero on success and -1 on failure
  1162. =================
  1163. */
  1164. #define ZIP_SEEK_BUF_SIZE (1<<15)
  1165. int idFile_InZip::Seek( long offset, fsOrigin_t origin ) {
  1166. int res, i;
  1167. char *buf;
  1168. switch( origin ) {
  1169. case FS_SEEK_END: {
  1170. offset = fileSize - offset;
  1171. }
  1172. case FS_SEEK_SET: {
  1173. // set the file position in the zip file (also sets the current file info)
  1174. unzSetCurrentFileInfoPosition( z, zipFilePos );
  1175. unzOpenCurrentFile( z );
  1176. if ( offset <= 0 ) {
  1177. return 0;
  1178. }
  1179. }
  1180. case FS_SEEK_CUR: {
  1181. buf = (char *) _alloca16( ZIP_SEEK_BUF_SIZE );
  1182. for ( i = 0; i < ( offset - ZIP_SEEK_BUF_SIZE ); i += ZIP_SEEK_BUF_SIZE ) {
  1183. res = unzReadCurrentFile( z, buf, ZIP_SEEK_BUF_SIZE );
  1184. if ( res < ZIP_SEEK_BUF_SIZE ) {
  1185. return -1;
  1186. }
  1187. }
  1188. res = i + unzReadCurrentFile( z, buf, offset - i );
  1189. return ( res == offset ) ? 0 : -1;
  1190. }
  1191. default: {
  1192. common->FatalError( "idFile_InZip::Seek: bad origin for %s\n", name.c_str() );
  1193. break;
  1194. }
  1195. }
  1196. return -1;
  1197. }