readTextFile.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:20k
源码类别:

DVD

开发平台:

Others

  1. /**************************************************************
  2.  *  readTextFile.c
  3.  **************************************************************
  4.  *  Description:
  5.  *  ============
  6.  *  Functions for reading text file using caching.
  7.  **************************************************************
  8.  *
  9.  *  Hagayb 14.11.03
  10.  **************************************************************/
  11. #include "Config.h" // Global Configuration - do not remove!
  12. #ifdef USE_AUX_SUBTITLES
  13. #ifdef _DEBUG
  14. #undef IFTRACE
  15. #define IFTRACE if (gTraceNavigator)
  16. #include "Debugdbgmain.h"
  17. #endif
  18. #include "PlaycoreAuxCacheAuxCache.h"
  19. #include "PlaycoreNav_ClipsreadTextFile.h"
  20. #ifdef DEBUG_AUX_SUBTITLES
  21. DWORD gen_timer(void);
  22. #endif
  23. extern DWORD g_dwSubtitleExtraOffset;
  24. BOOL textFileFillBuffer(textFilePtr tfpFile,DWORD dwOffset,WORD wReserveLast);
  25. /////////////////////////////////////////////////////////////////////////////////////////////
  26. // Function name : textFileOpen
  27. // Purpose : Open a text file for reading with buffering
  28. // Input Parameters : dwStartAddress - Address of the file on disc
  29. //   dwFileSize  - Size if the file
  30. // Return type : Handle to textFile on success, NULL on failure.
  31. // Description : The function allocates a textFile struct and sets up a buffer for reading
  32. /////////////////////////////////////////////////////////////////////////////////////////////
  33. textFilePtr textFileOpen(DWORD dwStartAddress, DWORD dwFileSize)
  34. {
  35. textFilePtr tfpFile;
  36. tfpFile=(textFilePtr)malloc(sizeof(textFile));
  37. if ( NULL == tfpFile ) {
  38. tr_printf(("textFileOpen - Error allocating memory for textFile structn"));
  39. return NULL;
  40. }
  41. tfpFile->caBuffer=(char *)malloc(sizeof(char)*TF_BUFFER_SIZE);
  42. if ( NULL == tfpFile->caBuffer ) {
  43. tr_printf(("textFileOpen - Error allocating memory for buffern"));
  44. free(tfpFile);
  45. return NULL;
  46. }
  47. tfpFile->dwStartAddress=dwStartAddress;
  48. tfpFile->dwFileSize=dwFileSize;
  49. tfpFile->dwCurrentDiscOffset = 0;
  50. tfpFile->pcCurrentBufferPosition = NULL;
  51. tfpFile->wCurrentBufferSize = 0;
  52. return tfpFile;
  53. }
  54. /////////////////////////////////////////////////////////////////////////////////////////////
  55. // Function name : textFileClose
  56. // Purpose : Closes a text file
  57. // Input Parameters : tfpFile - Handle to the file
  58. // Return type : void.
  59. // Description : The function deallocates the buffer and textFile struct for the file
  60. /////////////////////////////////////////////////////////////////////////////////////////////
  61. void textFileClose(textFilePtr tfpFile)
  62. {
  63. if ( NULL != tfpFile) {
  64. if ( NULL != tfpFile->caBuffer )
  65. free ( tfpFile->caBuffer );
  66. free ( tfpFile );
  67. }
  68. }
  69. /////////////////////////////////////////////////////////////////////////////////////////////
  70. // Function name : textFileSeek
  71. // Purpose : Seeks to a position in the file
  72. // Input Parameters : tfpFile - Handle to the file
  73. //   dwOffset - Offset in bytes, relative to the location specifed by bOrigin
  74. //   bOrigin - Specifies the origin of the seek. 
  75. //     Can have the following values:
  76. //   * TF_SEEK_SET - seek is relative to the file's beginning.
  77. //   * TF_SEEK_CUR - seek is relative to the current position
  78. //   * TF_SEEK_END - seek is relative to the file's end.
  79. // Return type : TRUE on success. FALSE on failure, or requested position isn't within the file
  80. // Description : The function checks is the requested position already exist in the buffer.
  81. //   If not, it fills the buffer from that point. In both cases, it updates
  82. //   the internal pointer pcCurrentBufferPosition to the requested position
  83. /////////////////////////////////////////////////////////////////////////////////////////////
  84. BOOL textFileSeek(textFilePtr tfpFile, long dwOffset, BYTE bOrigin)
  85. {
  86. DWORD dwRequestedPos;
  87. if ( NULL == tfpFile) {
  88. tr_printf(("textFileSeek - NULL pointer was suppliedn"));
  89. return FALSE;
  90. }
  91. // determine the requested offest in the file.
  92. switch (bOrigin)
  93. {
  94. case TF_SEEK_SET:
  95. dwRequestedPos = dwOffset;
  96. break;
  97. case TF_SEEK_CUR:
  98. if ( NULL != tfpFile->pcCurrentBufferPosition )
  99. dwRequestedPos = tfpFile->dwCurrentDiscOffset + ( tfpFile->pcCurrentBufferPosition - tfpFile->caBuffer ) + dwOffset;
  100. else {
  101. // either we were on EOF, or the buffer was empty. In both cases, it means
  102. // the current position is the byte after the end of the buffer.
  103. dwRequestedPos = tfpFile->dwCurrentDiscOffset + tfpFile->wCurrentBufferSize + dwOffset;
  104. }
  105. break;
  106. case TF_SEEK_END:
  107. // the end is considered to be the last byte of the file.
  108. dwRequestedPos=tfpFile->dwFileSize-1+dwOffset;
  109. break;
  110. default:
  111. tr_printf(("textFileSeek - unknown bOrigin valuen"));
  112. return FALSE;
  113. }
  114. if (dwRequestedPos < 0 || dwRequestedPos >=tfpFile->dwFileSize) {
  115. tr_printf(("textFileSeek - Requested postion outside of filen"));
  116. return FALSE;
  117. }
  118. // check if the requested position is in the buffer
  119. if ( 0 != tfpFile->wCurrentBufferSize && dwRequestedPos>=tfpFile->dwCurrentDiscOffset &&
  120. dwRequestedPos - tfpFile->dwCurrentDiscOffset < tfpFile->wCurrentBufferSize )
  121. {
  122. // the requested position is in the buffer
  123. tfpFile->pcCurrentBufferPosition = tfpFile->caBuffer+dwRequestedPos - tfpFile->dwCurrentDiscOffset;
  124. return TRUE;
  125. }
  126. else {
  127. // it isn't, so fill the buffer fron its beginning, starting from the requested position
  128. return textFileFillBuffer(tfpFile,dwRequestedPos,0);
  129. }
  130. }
  131. /////////////////////////////////////////////////////////////////////////////////////////////
  132. // Function name : textFileEOF
  133. // Purpose : Check if end of file was reached
  134. // Input Parameters : tfpFile - Handle to the file
  135. // Return type : TRUE if end of file was reached, FALSE otherwise
  136. // Description : Check if pcCurrentBufferPosition is NULL, and dwCurrentDiscOffset + 
  137. //   wCurrentBufferSize points outside of the file
  138. /////////////////////////////////////////////////////////////////////////////////////////////
  139. BOOL textFileEOF(textFilePtr tfpFile)
  140. {
  141. return (tfpFile->dwCurrentDiscOffset + tfpFile->wCurrentBufferSize == tfpFile->dwFileSize
  142. && NULL == tfpFile->pcCurrentBufferPosition);
  143. }
  144. /////////////////////////////////////////////////////////////////////////////////////////////
  145. // Function name : textFileReadChar
  146. // Purpose : Reads a character (single byte) from the file.
  147. // Input Parameters : tfpFile - Handle to the file
  148. //   wReserveLast - If rewinding is expected after this operation,
  149. //  wReserveLast is the number of bytes for the possible rewind
  150. //  (for buffering purposes only)
  151. // Output Parameters: c - The character that was read
  152. // Return type : TRUE if successful, FALSE if failed, or already on end of file
  153. // Description : Fills the buffer if necessary, and reads a character.
  154. /////////////////////////////////////////////////////////////////////////////////////////////
  155. BOOL textFileReadChar(textFilePtr tfpFile,WORD wReserveLast, char *c )
  156. {
  157. if (textFileEOF(tfpFile))
  158. return FALSE;
  159. // check if the buffer is "empty" - doesn't contain the data of the next char
  160. if ( NULL == tfpFile->pcCurrentBufferPosition ) {
  161. // fill the buffer and reserve 1 byte, in case someone wants to rewind
  162. if (!textFileFillBuffer(tfpFile, tfpFile->dwCurrentDiscOffset + tfpFile->wCurrentBufferSize, wReserveLast))
  163. {
  164. tr_printf(("textFileReadChar - textFileFillBuffer failedn"));
  165. return FALSE;
  166. }
  167. }
  168. *c=*(tfpFile->pcCurrentBufferPosition);
  169. // if 0x00 in the middle of the file, deal with it as space
  170.     if (*c == 0x00)
  171.         *c = 0x20;
  172. tfpFile->pcCurrentBufferPosition++;
  173. // check if the buffer becomes "empty"
  174. if ( tfpFile->pcCurrentBufferPosition - tfpFile->caBuffer  >= tfpFile->wCurrentBufferSize )
  175. tfpFile->pcCurrentBufferPosition=NULL;
  176. return TRUE;
  177. }
  178. /////////////////////////////////////////////////////////////////////////////////////////////
  179. // Function name : textFileGetPosition
  180. // Purpose : Get the current poision in the file.
  181. // Input Parameters : tfpFile - Handle to the file
  182. // Return type : DWORD specifying the position. This value can be used in textFileSeek
  183. //   together with TF_SEEK_SET to reach this position again.
  184. // Description : calculates the offset on disc of the current character in the buffer.
  185. /////////////////////////////////////////////////////////////////////////////////////////////
  186. DWORD textFileGetPosition(textFilePtr tfpFile)
  187. {
  188. if ( NULL == tfpFile->pcCurrentBufferPosition )
  189. return tfpFile->dwCurrentDiscOffset + tfpFile->wCurrentBufferSize;
  190. else
  191. return tfpFile->dwCurrentDiscOffset + ( tfpFile->pcCurrentBufferPosition - tfpFile->caBuffer );
  192. }
  193. /////////////////////////////////////////////////////////////////////////////////////////////
  194. // Function name : textFileFindString
  195. // Purpose : Searches for the specified string from het current position, in the
  196. //   specified number of bytes.
  197. // Input Parameters : tfpFile - Handle to the file
  198. //   szStr - String (null terminated, single byte) to look for.
  199. //   dwRegionSize - a limit to the number of bytes in the file the search 
  200. // will cover. Specify 0 for search until end of file.
  201. // Return type : TRUE is string was found, else otherwise.
  202. //   The current position in the file will be the first character in the string
  203. // Description : 
  204. /////////////////////////////////////////////////////////////////////////////////////////////
  205. BOOL textFileFindString(textFilePtr tfpFile, const char *szStr, DWORD dwRegionSize)
  206. {
  207. int len,i,j;
  208. char *cpWindow,*cpTmp;
  209. BOOL bSuccess=FALSE;
  210. len=strlen(szStr);
  211. i=0;
  212. cpWindow=(char *)malloc(len);
  213. if ( NULL == cpWindow) {
  214. tr_printf(("textFileFindString - error allocating memoryn"));
  215. return FALSE;
  216. }
  217. while ( !textFileEOF(tfpFile) && (i<dwRegionSize || dwRegionSize==0) ) {
  218. // shift the window, to make room for a new char in the end
  219. for (j=0,cpTmp=cpWindow; j<len-1 ; j++, cpTmp++)
  220. *cpTmp=*(cpTmp+1);
  221. // read char into the window's end
  222. if (FALSE == textFileReadChar(tfpFile,len,cpTmp)) {
  223. tr_printf(("textFileFindString - textFileReadChar failedn"));
  224. break;
  225. }
  226. // if the window is full, compare the window and the string
  227. if (i>=len-1) {
  228. if ( 0 == strnicmp(szStr, cpWindow, len)) {
  229. bSuccess=TRUE;
  230. free(cpWindow);
  231. return bSuccess;
  232. }
  233. }
  234. i++;
  235. }
  236. free(cpWindow);
  237. return bSuccess;
  238. }
  239. /////////////////////////////////////////////////////////////////////////////////////////////
  240. // Function name : textFileFindNumber
  241. // Purpose : Finds the next digit in the file, if exists in the next specified number of bytes.
  242. // Input Parameters : tfpFile - Handle to the file
  243. //   dwRegionSize - a limit to the number of bytes in the file the search 
  244. // will cover. Specify 0 for search until end of file.
  245. // Return type : TRUE is a digit was found within the region, else otherwise.
  246. //   The current position in the file will be the digit.
  247. // Description : The function looks of the next digit, starting from the current position
  248. //   for dwRegionSize bytes. If there was already a digit in the current position,
  249. //   it does nothing.
  250. /////////////////////////////////////////////////////////////////////////////////////////////
  251. BOOL textFileFindNumber(textFilePtr tfpFile,DWORD dwRegionSize)
  252. {
  253. int i=0;
  254. BOOL bSuccess=FALSE;
  255. char c;
  256. while ( !textFileEOF(tfpFile) && ( i<dwRegionSize || dwRegionSize == 0 )) {
  257. // read char into the window's end
  258. if (FALSE == textFileReadChar(tfpFile,1,&c)) {
  259. tr_printf(("textFileFindNumber - textFileReadChar failedn"));
  260. return FALSE;
  261. }
  262. if ( c >= '0' && c <= '9' ) {
  263. if (FALSE == textFileSeek(tfpFile,-1,TF_SEEK_CUR)) {
  264. tr_printf(("textFileFindNumber - error seeking after digit foundn"));
  265. return FALSE;
  266. }
  267. bSuccess=TRUE;
  268.          break;
  269. }
  270. i++;
  271. }
  272. return bSuccess;
  273. }
  274. /////////////////////////////////////////////////////////////////////////////////////////////
  275. // Function name : textFileReadNumber
  276. // Purpose : Reads a number from the current position in the file.
  277. // Input Parameters : tfpFile - Handle to the file
  278. // Output Parameters: uiNumber - The number that was read
  279. // Return type : TRUE if successful. FALSE if the was no number in the current position,
  280. //   if already on EOF, or on error.
  281. // Description : The function checks if there's a digit in the current position. If there
  282. //   is, it reads until (not including) the 1st non digit character and 
  283. //   converts the digit sequence to a number.
  284. /////////////////////////////////////////////////////////////////////////////////////////////
  285. BOOL textFileReadNumber(textFilePtr tfpFile, DWORD *uiNumber)
  286. {
  287. char c;
  288. *uiNumber=0;
  289. if (TRUE == textFileEOF(tfpFile))
  290. return FALSE;
  291. if (FALSE == textFileReadChar(tfpFile,1,&c)) {
  292. tr_printf(("textFileReadNumber - textFileReadChar failedn"));
  293. return FALSE;
  294. }
  295. // Robin_0328_2005, deal with the writing mistake
  296. if (c == 'O' || c == 'o')
  297. {
  298. c = '0';
  299. }
  300. if (!( c >= '0' && c <= '9' )) {
  301. if (FALSE == textFileSeek(tfpFile,-1,TF_SEEK_CUR))
  302. tr_printf(("textFileFindNumber - error seeking after digit not foundn"));
  303. return FALSE;
  304. }
  305. do {
  306. // add the previously read digit to the number
  307. *uiNumber= 10 * (*uiNumber) + (c - '0');
  308. // read the next digit
  309. if (FALSE == textFileReadChar(tfpFile,1,&c)) {
  310. tr_printf(("textFileReadNumber - textFileReadChar failedn"));
  311. return FALSE;
  312. }
  313. } while (( c >= '0' && c <= '9' ) && (FALSE == textFileEOF(tfpFile)));
  314.    if (FALSE == textFileSeek(tfpFile,-1,TF_SEEK_CUR)) {
  315. tr_printf(("textFileFindNumber - error seeking after digit not foundn"));
  316.          return FALSE;
  317.    }
  318. return TRUE;
  319. }
  320. /////////////////////////////////////////////////////////////////////////////////////////////
  321. // Function name : textFileSkipLine
  322. // Purpose : Find the beginning of the next line
  323. // Input Parameters : tfpFile - Handle to the file
  324. // Return type : TRUE if successful. FALSE if EOF encountered before 'n',
  325. //   or on error.
  326. // Description : The function searches for the next 'n'  and sets the current position
  327. //   right after it.
  328. /////////////////////////////////////////////////////////////////////////////////////////////
  329. BOOL textFileSkipLine(textFilePtr tfpFile)
  330. {
  331. char c=0;
  332. while ( !textFileEOF(tfpFile) && 'n' != c )  {
  333. if (FALSE == textFileReadChar(tfpFile,1,&c)) {
  334. tr_printf(("textFileSkipLine - textFileReadChar failedn"));
  335. return FALSE;
  336. }
  337. }
  338. // return false if EOF was reached before 'n' was found
  339. return ( 'n' == c );
  340. }
  341. // ******************************************************************************************
  342. // Private functions
  343. // ******************************************************************************************
  344. /////////////////////////////////////////////////////////////////////////////////////////////
  345. // Function name : textFileFillBuffer
  346. // Purpose : Fills the buffer
  347. // Input Parameters : tfpFile      - Handle to the file
  348. //   dwOffset     - Position in the file, from which the data would be read.
  349. //   wReserveLast - Number of bytes to keep from the end of the previous buffer.
  350. //  used when it's likely that a file seek will want to access
  351. //  these bytes. If the buffer was empty - ignore this value
  352. // Return type : TRUE if successful. FALSE on error.
  353. // Description : The function searches for the next 'n'  and sets the current position
  354. //   right after it.
  355. /////////////////////////////////////////////////////////////////////////////////////////////
  356. BOOL textFileFillBuffer(textFilePtr tfpFile,DWORD dwOffset,WORD wReserveLast)
  357. {
  358. WORD wNewBufferSize;
  359.    BYTE bReadExtraBytes=0;
  360. #ifdef DEBUG_AUX_SUBTITLES
  361. static DWORD dwTotal=0;
  362.    DWORD dwStart;
  363.    DWORD dwEnd;
  364. #endif
  365. // check if requested offset is valid
  366. if (dwOffset >= tfpFile->dwFileSize || dwOffset < 0) {
  367. tr_printf(("textFileFillBuffer - requested read position outside of filen"));
  368. return FALSE;
  369. }
  370.    /*
  371. // if the buffer was empty - ignore wReserveLast
  372. if (0 == tfpFile->wCurrentBufferSize)
  373. wReserveLast=0;
  374.    // make sure that the size for reading is even
  375. if ( wReserveLast & 1)
  376.     wReserveLast++;
  377. // check if number of reserved bytes is valid
  378. if (wReserveLast >= TF_BUFFER_SIZE) {
  379. tr_printf(("textFileFillBuffer - number of reserved bytes >= buffer sizen"));
  380. return FALSE;
  381. }
  382. // if specified, copy reserved bytes to the beginning of buffer
  383. if ( 0 != wReserveLast ) {
  384. //if (wReserveLast<=TF_BUFFER_SIZE_HALF) {
  385. // the source and destination regions don't overlap - use memcpy
  386. memcpy(tfpFile->caBuffer , tfpFile->caBuffer + tfpFile->wCurrentBufferSize - wReserveLast, wReserveLast);
  387. }
  388. }
  389.    */
  390. // calculate new buffer size
  391. if ( tfpFile->dwFileSize - dwOffset < TF_BUFFER_SIZE )
  392. wNewBufferSize = tfpFile->dwFileSize - dwOffset;
  393. else
  394. wNewBufferSize = TF_BUFFER_SIZE;
  395.    // the new buffer size can be odd only if it's the end of file. The extra
  396.    // byte will still fall inside the buffer.
  397.    if (wNewBufferSize & 1)
  398.     bReadExtraBytes=1;
  399. #ifdef DEBUG_AUX_SUBTITLES
  400. dwStart = gen_timer();
  401.    if (dwOffset == 0 )
  402.     dwTotal = 0;
  403. #endif
  404. // Reading - fill only the non reserved part
  405. // Robin_0117_2005, support AVI internal text subtitle
  406. if (!AuxCache_GetBytes(tfpFile->dwStartAddress, dwOffset + g_dwSubtitleExtraOffset, wNewBufferSize /* - wReserveLast*/ + bReadExtraBytes, tfpFile->caBuffer /*+ wReserveLast*/))
  407. {
  408. tr_printf(("textFileFillBuffer - failed reading from discn"));
  409. return FALSE;
  410. }
  411. #ifdef DEBUG_AUX_SUBTITLES
  412. dwEnd = gen_timer();
  413.    dwTotal += ((dwEnd > dwStart ) ? dwEnd - dwStart : 0xffffffffL - dwStart + dwEnd) ;
  414. if ( wNewBufferSize != TF_BUFFER_SIZE )
  415.     dbg_printf(("Total time for AuxCache_GetBytes calls - %lun",dwTotal));
  416. #endif
  417. tfpFile->dwCurrentDiscOffset = dwOffset/*-wReserveLast*/;
  418. tfpFile->wCurrentBufferSize = wNewBufferSize;
  419. tfpFile->pcCurrentBufferPosition = tfpFile->caBuffer /*+ wReserveLast */;
  420. return TRUE;
  421. }
  422. /////////////////////////////////////////////////////////////////////////////////////////////
  423. // Function name : textFileIsCurrentChar
  424. // Purpose : Asserts that the current character in the file is the specified char
  425. // Input Parameters : tfpFile - Handle to the file
  426. //   c - character to be tested.
  427. // Return type : TRUE if character is correct. FALSE otherwise, and on error
  428. // Description : The function reads a character from the file and compares it to the
  429. //   specified character. This function should be used to check correctness
  430. //   of file format.
  431. /////////////////////////////////////////////////////////////////////////////////////////////
  432. BOOL textFileIsCurrentChar(textFilePtr tfpFile,char c)
  433. {
  434. char b;
  435. if (FALSE == textFileReadChar(tfpFile,0,&b)) {
  436. //tr_printf(("textFileIsCurrentChar - can't read charn"));
  437. return FALSE;
  438. }
  439. c = ((c <= 'z' ) && (c >= 'a')) ? (c-32) : c;
  440. b = ((b <= 'z' ) && (b >= 'a')) ? (b-32) : b;
  441. return (b == c);
  442. }
  443. // Robin_0604_2004_C
  444. BOOL textFileIsCurrentChar2(textFilePtr tfpFile,char c)
  445. {
  446. char b;
  447. if (FALSE == textFileReadChar(tfpFile,0,&b)) {
  448. //tr_printf(("textFileIsCurrentChar - can't read charn"));
  449. return FALSE;
  450. }
  451. c = ((c <= 'z' ) && (c >= 'a')) ? (c-32) : c;
  452. b = ((b <= 'z' ) && (b >= 'a')) ? (b-32) : b;
  453. if (b == c)
  454. {
  455. return TRUE;
  456. }
  457. else
  458. {
  459. if (NULL == tfpFile->pcCurrentBufferPosition)
  460. tfpFile->pcCurrentBufferPosition = tfpFile->caBuffer + tfpFile->wCurrentBufferSize - 1;
  461. else
  462. tfpFile->pcCurrentBufferPosition--;
  463. return FALSE;
  464. }
  465. }
  466. #endif // USE_AUX_SUBTITLES