1 /*---------------------------------------------------------------------------* 2 * pstream.c * 3 * * 4 * Copyright 2007, 2008 Nuance Communciations, Inc. * 5 * * 6 * Licensed under the Apache License, Version 2.0 (the 'License'); * 7 * you may not use this file except in compliance with the License. * 8 * * 9 * You may obtain a copy of the License at * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, software * 13 * distributed under the License is distributed on an 'AS IS' BASIS, * 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * 15 * See the License for the specific language governing permissions and * 16 * limitations under the License. * 17 * * 18 *---------------------------------------------------------------------------*/ 19 20 #include <stdarg.h> 21 #include <stdlib.h> 22 #include <stdio.h> 23 24 #include <string.h> 25 #include "passert.h" 26 #include "pstdio.h" 27 #include "pmemory.h" 28 #include "plog.h" 29 30 #ifdef __cplusplus 31 extern "C" 32 { 33 #endif 34 35 #ifdef PFILE_VIRTUAL_SUPPORT 36 37 #define FILETEXTMODE 0x00 38 #define FILEBINARYMODE 0x01 39 #define FILEREADMODE 0x00 40 #define FILEWRITEMODE 0x02 41 42 /* Open a existed writable file (i.e., the file is not closed yet). 43 At some cases user knows the filename only but does not know the file handle (1), 44 the user could call fopen to open this file again with another file handle (2). 45 He/She could get all the information before the last fflush was called via file handle (1). 46 */ 47 #define FILEREOPENMODE 0x08 48 49 #define ISWRITEMODE(mode) (((mode)&FILEWRITEMODE) == FILEWRITEMODE) 50 51 #define ISBINARYMODE(mode) (((mode)&FILEBINARYMODE) == FILEBINARYMODE) 52 #define ISREOPENMODE(mode) (((mode)&FILEREOPENMODE) == FILEREOPENMODE) 53 54 /* 55 use a double link list to store the data of the writable file. 56 Each entry has 4k space (FILEBUFFERSIZE). 57 */ 58 #define FILEBUFFERSIZE 4096 /* 4k for each file buffer entry */ 59 60 typedef struct FileBufferFrame 61 { 62 unsigned char *buffer; /* do not use pointer here and set it the first */ 63 size_t size; 64 size_t index; /* nth buffer, from 0, 1, ... */ 65 struct FileBufferFrame *prev; 66 struct FileBufferFrame *next; 67 BOOL bMalloc; /* flag, if the buffer malloced here ? */ 68 } 69 FileBufferFrame; 70 71 FileRecord pWritableFileRecTable[] = 72 { 73 {"", 0, 0, 0, 3}, 74 {"", 0, 0, 0, 3}, 75 {"", 0, 0, 0, 3}, 76 {"", 0, 0, 0, 3}, 77 {"", 0, 0, 0, 3}, 78 {"", 0, 0, 0, 3}, 79 {"", 0, 0, 0, 3} 80 }; 81 const nWritableFiles = sizeof(pWritableFileRecTable) / sizeof(pWritableFileRecTable[0]); 82 83 #ifdef WIN32 84 extern const FileRecord pFileRecTable[]; 85 extern const unsigned char pFileStart0[]; 86 #endif 87 88 const FileRecord *pReadOnlyFileRecTable = NULL; 89 const unsigned char *g_pFirstFile = NULL; 90 91 void SetFileTable(VirtualFileTable *table) 92 { 93 #ifdef WIN32 94 pReadOnlyFileRecTable = pFileRecTable; 95 g_pFirstFile = pFileStart0; 96 #else 97 if (table) 98 { 99 pReadOnlyFileRecTable = table->pFileTable; 100 g_pFirstFile = table->pFirstFile; 101 } 102 #endif 103 } 104 105 /* 106 size: size of buffer. 107 buffer: is NULL, allocate here and set bMalloc as TRUE; otherwise use the external buffer 108 */ 109 FileBufferFrame* CreateFileBufferFrame(size_t size, unsigned char *buffer) 110 { 111 FileBufferFrame *fb = NULL; 112 113 /* create FileBufferFrame */ 114 fb = (FileBufferFrame *)MALLOC(sizeof(FileBufferFrame), "FileBufferFrame"); 115 if (fb) 116 { 117 fb->next = NULL; 118 fb->prev = NULL; 119 fb->index = 0; 120 fb->size = size; 121 fb->bMalloc = FALSE; 122 123 if (buffer) 124 fb->buffer = buffer; 125 else 126 { 127 /* create one buffer frame */ 128 if ((fb->buffer = (unsigned char *)MALLOC(size, "FileBufferFrame Buffer")) == NULL) 129 { 130 FREE(fb); 131 return NULL; 132 } 133 fb->bMalloc = TRUE; 134 } 135 } 136 return fb; 137 } 138 139 /* free FileBufferFrames 140 header should be the header of the FileBufferFrame link list 141 */ 142 void DeleteFileBuffers(FileBufferFrame *header) 143 { 144 FileBufferFrame *next, *curr; 145 146 passert(header && header->prev == NULL); /* delete from the beginning */ 147 148 curr = header; 149 do 150 { 151 next = curr->next; 152 if (curr->bMalloc) 153 FREE(curr->buffer); 154 FREE(curr); 155 curr = next; 156 } 157 while (next != NULL); 158 } 159 160 void PortFileInit(void) 161 { 162 /* No gPortStdin, gPortStdout, and gPortStderr to initialize. */ 163 #ifdef WIN32 164 pReadOnlyFileRecTable = pFileRecTable; 165 g_pFirstFile = pFileStart0; 166 #endif 167 } 168 169 /* Assume that all files have at least one byte in them, that is length is > 0. */ 170 PORT_FILE PortFopen(const char *filename, const char *mode) 171 { 172 char *pfn; 173 const unsigned char *start; 174 int size; 175 int text_mode; 176 int access_mode; 177 int m = 0; 178 PORT_FILE PortFile; 179 FileBufferFrame *curFrame; 180 size_t end; 181 182 passert(filename); 183 passert(mode); 184 185 if (pReadOnlyFileRecTable == NULL) 186 { 187 passert("File Table is not initialized!" == NULL); 188 return NULL; 189 } 190 191 /* support read and write. */ 192 if (mode[0] == 'r' || mode[0] == 'w' || mode[0] == 'R') /* w means w+, attaching text */ 193 { 194 char fname[80]; 195 FileRecord *pCurRec; 196 197 access_mode = (mode[0] == 'r') ? FILEREADMODE : FILEWRITEMODE; 198 199 /* access mode: b/t */ 200 if (mode[1] == '+') 201 text_mode = (mode[2] == 'b') ? FILEBINARYMODE : FILETEXTMODE; 202 else 203 text_mode = (mode[1] == 'b') ? FILEBINARYMODE : FILETEXTMODE; 204 205 /* Remove the directory path from the filename. */ 206 if ((pfn = strrchr(filename, '/')) != NULL || (pfn = strrchr(filename, '\\')) != NULL) 207 strcpy(fname, pfn + 1); 208 else 209 strcpy(fname, filename); 210 211 212 /* Locate the start of the file, by looking through the file record table. */ 213 if (access_mode == FILEREADMODE) 214 { 215 pCurRec = (FileRecord *)pReadOnlyFileRecTable; 216 start = g_pFirstFile; 217 } 218 else 219 { 220 pCurRec = (FileRecord *)pWritableFileRecTable; 221 } 222 223 while (pCurRec->size > 0 && strcmp(pCurRec->name, fname) != 0) 224 { 225 /* have to count the read-only file address in order to be best portable */ 226 start += pCurRec->size; 227 pCurRec++; 228 #ifndef NDEBUG 229 /* just for our internal test for read-only files. 230 if (pCurRec->start != NULL) 231 passert(start == pCurRec->start); 232 */ 233 #endif 234 } 235 236 m = access_mode | text_mode; 237 /* Do not support reopen the writable file now. */ 238 if (access_mode == FILEREADMODE) 239 { 240 if (pCurRec->size == 0) 241 { 242 return NULL; 243 } 244 245 /* Found the file, record it's starting offset and length. */ 246 end = pCurRec->end; 247 size = pCurRec->size; 248 } 249 /* writable file, open it the first time; could be text or binary */ 250 else if (ISWRITEMODE(access_mode)) 251 { 252 /* set the name and mode */ 253 strcpy(pCurRec->name, fname); 254 pCurRec->mode = m; 255 256 start = pCurRec->start; 257 passert(start == NULL); 258 end = size = FILEBUFFERSIZE; 259 } 260 else 261 { 262 /* File doesn't exist. */ 263 return NULL; 264 } 265 pfn = pCurRec->name; 266 } 267 else 268 { 269 /* Unknown mode */ 270 return NULL; 271 } 272 273 /* Open file */ 274 /* Create new file handle */ 275 PortFile = (PORT_FILE)MALLOC(sizeof(PORT_FILE_HANDLE), "PortFile"); 276 if (PortFile == NULL) 277 { 278 return NULL; 279 } 280 281 /* this mode is not tested yet */ 282 if (ISREOPENMODE(m)) 283 { 284 PortFile->startFrame = (FileBufferFrame *)start; 285 } 286 else 287 { 288 PortFile->startFrame = CreateFileBufferFrame(size, (unsigned char *)start); 289 if (ISWRITEMODE(m)) 290 { 291 start = (const unsigned char *)PortFile->startFrame; 292 } 293 } 294 295 if (PortFile->startFrame == NULL) 296 { 297 FREE(PortFile); 298 return NULL; 299 } 300 301 PortFile->endFrame = PortFile->curFrame = PortFile->startFrame; 302 303 /* Mark that this file handle is for flash memory */ 304 PortFile->filename = pfn; 305 PortFile->curPos = PortFile->curFrame->buffer; 306 PortFile->endPos = PortFile->curPos + end; 307 308 /* set the PortFile->endPos */ 309 curFrame = PortFile->curFrame; 310 while (end > 0) 311 { 312 if (end > curFrame->size) 313 { 314 curFrame = curFrame->next; 315 passert(end > curFrame->size); 316 end -= curFrame->size; 317 passert(curFrame); 318 } 319 else 320 { 321 /* only reopen the writable file comes here */ 322 PortFile->endPos = curFrame->buffer + end; 323 break; 324 } 325 } 326 327 PortFile->eof = 0; /* File must have at least one byte in it. */ 328 PortFile->size = size; 329 PortFile->mode = m; 330 331 return PortFile; 332 } 333 334 int PortFclose(PORT_FILE PortFile) 335 { 336 passert(PortFile); 337 338 /* for reopen mode, do not delete the FileBufferFrame. Delete it by who created it */ 339 if (ISWRITEMODE(PortFile->mode) && !ISREOPENMODE(PortFile->mode)) /* writable file */ 340 { 341 int i = 0; 342 FileRecord *pCurRec = (FileRecord *)pWritableFileRecTable; 343 344 /* find the file record in memory */ 345 for (i = 0; i < nWritableFiles; i++) 346 { 347 if (PortFile->size > 0 && 348 PortFile->filename[0] != '\0' && 349 strcmp(pCurRec->name, PortFile->filename) == 0 350 ) 351 { 352 /* The parameter SREC.Recognizer.osi_log_level in par file control the output 353 # BIT 0 -> BASIC logging 354 # BIT 1 -> AUDIO waveform logging 355 # BIT 2 -> ADD WORD logging 356 # e.g. value is 3 = BASIC+AUDIO logging, no ADDWORD 357 SREC.Recognizer.osi_log_level = 7; 358 359 Do not control here 360 */ 361 /* 362 SaveFileToDisk(PortFile); 363 */ 364 365 pCurRec->name[0] = '\0'; 366 pCurRec->start = NULL; 367 pCurRec->end = 0; 368 pCurRec->size = 0; 369 370 break; 371 } 372 pCurRec++; 373 } 374 } 375 376 DeleteFileBuffers(PortFile->startFrame); 377 FREE(PortFile); 378 return 0; 379 } 380 381 /* 382 * Returns the number of items read 383 */ 384 size_t PortFread(void *buffer, size_t size, size_t count, PORT_FILE PortFile) 385 { 386 unsigned char *bufferPtr = (unsigned char *)buffer; 387 int cbRemain = size * count; 388 int cbAvail, minSize; 389 FileBufferFrame *curFrame = PortFile->curFrame; 390 391 passert(buffer); 392 passert(PortFile); 393 394 if (PortFile->eof == 1) 395 { 396 return 0; 397 } 398 399 while (cbRemain > 0) 400 { 401 if (PortFile->endPos == PortFile->curPos) /* end of file */ 402 break; 403 404 if (PortFile->curPos == curFrame->buffer + curFrame->size) /* end of this frame */ 405 { 406 /* go to next frame */ 407 curFrame = PortFile->curFrame = curFrame->next; 408 PortFile->curPos = curFrame->buffer; 409 } 410 411 if (curFrame == PortFile->endFrame) /* last frame */ 412 cbAvail = PortFile->endPos - PortFile->curPos; 413 else 414 cbAvail = curFrame->size - (PortFile->curPos - curFrame->buffer); 415 416 minSize = cbRemain < cbAvail ? cbRemain : cbAvail; 417 passert(minSize >= 0); 418 419 cbRemain -= minSize; 420 while (minSize-- > 0) 421 *bufferPtr++ = *PortFile->curPos++; 422 } 423 424 if (PortFile->curPos == PortFile->endPos) 425 { 426 PortFile->eof = 1; 427 } 428 /* 429 #ifdef __BIG_ENDIAN 430 if (!bNativeEnding) 431 { 432 swap_byte_order((char *)buffer, count, size); 433 } 434 #endif 435 */ 436 return count - cbRemain / size; 437 } 438 439 /* 440 * Returns the number of items written 441 */ 442 size_t PortFwrite(const void *data, size_t size, size_t count, PORT_FILE PortFile) 443 { 444 int cbWrite = size * count; 445 int cbAvail, minSize; 446 unsigned char *buffer = (unsigned char *)data; 447 FileBufferFrame *curFrame; 448 449 if (PortFile == NULL) 450 return 0; 451 452 curFrame = PortFile->curFrame; 453 454 /* write data until the end of the internal buffer */ 455 if (PortFile->eof == 1) 456 { 457 /* TODO: should return 0, but it will cause infinite loop */ 458 return 0; 459 } 460 461 /* why sub 1 ? */ 462 while (cbWrite > 0) 463 { 464 if (PortFile->curPos == curFrame->buffer + curFrame->size) /* end of this frame */ 465 { 466 if (curFrame->next == NULL) 467 { 468 /* assign a new space */ 469 FileBufferFrame *nextFrame = CreateFileBufferFrame(FILEBUFFERSIZE, NULL); 470 if (nextFrame) 471 { 472 curFrame->next = nextFrame; 473 nextFrame->prev = curFrame; 474 nextFrame->index = curFrame->index + 1; 475 476 curFrame = PortFile->curFrame = nextFrame; 477 PortFile->endFrame = nextFrame; 478 PortFile->curPos = PortFile->endPos = nextFrame->buffer; 479 480 PortFile->size += FILEBUFFERSIZE; 481 } 482 else 483 { 484 return count -cbWrite / size; 485 } 486 } 487 else 488 curFrame = curFrame->next; 489 } 490 491 /* available space in current frame */ 492 cbAvail = curFrame->size - (PortFile->curPos - curFrame->buffer); 493 minSize = cbWrite < cbAvail ? cbWrite : cbAvail; 494 495 memcpy((char *)PortFile->curPos, buffer, minSize); 496 buffer += minSize; 497 PortFile->curPos += minSize; 498 /* in case the write is not adding to the end */ 499 if (curFrame == PortFile->endFrame && PortFile->endPos < PortFile->curPos) 500 PortFile->endPos = PortFile->curPos; 501 cbWrite -= minSize; 502 } 503 504 return count; 505 } 506 507 /* 508 * Returns 0 on success, non-zero on failure 509 */ 510 int PortFseek(PORT_FILE PortFile, long offset, int origin) 511 { 512 int retval = 0; 513 int cbAvail, minSize; 514 FileBufferFrame *curFrame; 515 516 passert(PortFile); 517 518 /* Clear eof flag */ 519 PortFile->eof = 0; 520 521 switch (origin) 522 { 523 case SEEK_CUR: 524 break; 525 case SEEK_END: 526 PortFile->curFrame = PortFile->endFrame; 527 PortFile->curPos = PortFile->endPos; 528 break; 529 case SEEK_SET: 530 PortFile->curFrame = PortFile->startFrame; 531 PortFile->curPos = PortFile->startFrame->buffer; 532 break; 533 default: 534 retval = 0; /* Error, unknown origin type */ 535 break; 536 } 537 538 curFrame = PortFile->curFrame; 539 540 while (offset != 0) 541 { 542 if (offset > 0) 543 { 544 if (PortFile->endPos <= PortFile->curPos) /* end of file */ 545 break; 546 547 if (PortFile->curPos == curFrame->buffer + curFrame->size) /* end of this frame */ 548 { 549 /* go to next frame */ 550 curFrame = curFrame->next; 551 if (curFrame == NULL) 552 break; 553 PortFile->curFrame = curFrame->next; 554 PortFile->curPos = curFrame->buffer; 555 } 556 if (curFrame == PortFile->endFrame) /* last frame */ 557 cbAvail = PortFile->endPos - PortFile->curPos; 558 else 559 cbAvail = curFrame->size - (PortFile->curPos - curFrame->buffer); 560 561 minSize = offset < cbAvail ? offset : cbAvail; 562 563 PortFile->curPos += minSize; 564 offset -= minSize; 565 } 566 else 567 { 568 if (PortFile->startFrame->buffer == PortFile->curPos) /* start of file */ 569 break; 570 571 if (PortFile->curPos <= curFrame->buffer) /* start of this frame */ 572 { 573 /* go to next frame */ 574 curFrame = curFrame->next; 575 if (curFrame == NULL) 576 break; 577 PortFile->curFrame = curFrame; 578 PortFile->curPos = curFrame->buffer + curFrame->size; 579 } 580 cbAvail = PortFile->curPos - curFrame->buffer; 581 582 minSize = -offset < cbAvail ? -offset : cbAvail; 583 584 PortFile->curPos -= minSize; 585 offset += minSize; 586 } 587 } 588 return retval; 589 } 590 591 /* 592 * Returns current file position 593 */ 594 long PortFtell(PORT_FILE PortFile) 595 { 596 int size; 597 FileBufferFrame *curFrame = PortFile->curFrame; 598 599 passert(PortFile); 600 601 /* current Frame size */ 602 size = PortFile->curPos - curFrame->buffer; 603 604 /* previous frame size */ 605 while (curFrame = curFrame->prev) 606 size += curFrame->size; 607 608 return size; 609 } 610 611 int PortVfprintf(PORT_FILE PortFile, const char *format, va_list argptr) 612 { 613 char message[2*2048] = ""; 614 615 /* Print formatted message to buffer */ 616 vsprintf(message, format, argptr); 617 618 if (PortFile == NULL) 619 { 620 /* TODO: HECK to screen */ 621 #ifndef NDEBUG 622 printf(message); 623 #endif 624 return 0; 625 } 626 627 passert(strlen(message) < 2*2048); 628 /* TO DO, seems at case fprintf(pf, "whatever"), message is empty! */ 629 if (strlen(message) == 0) 630 return 0; 631 else 632 return PortFwrite(message, sizeof(char), strlen(message), PortFile); 633 } 634 635 /* 636 * Returns current file position 637 */ 638 int PortFprintf(PORT_FILE PortFile, const char* format, ...) 639 { 640 va_list log_va_list; 641 int ret = 0; 642 643 /* Start variable argument list */ 644 va_start(log_va_list, format); 645 646 /* Print formatted message to buffer */ 647 ret = PortVfprintf(PortFile, format, log_va_list); 648 649 /* End variable argument list */ 650 va_end(log_va_list); 651 652 return ret; 653 } 654 655 /* 656 * Returns string or NULL if error 657 */ 658 char *PortFgets(char *string, int n, PORT_FILE PortFile) 659 { 660 int cbToRead = n - 1; 661 BOOL done = FALSE; 662 char *retString = NULL; 663 int i; 664 665 passert(string); 666 passert(n); 667 passert(PortFile); 668 669 670 if (PortFile->eof == 1) 671 { 672 return NULL; 673 } 674 675 676 /* Search for \n only! */ 677 for (i = 0; i < cbToRead && !done; i++) 678 { 679 if (PortFile->curPos >= PortFile->endPos) 680 { 681 PortFile->eof = 1; 682 done = TRUE; 683 break; 684 } 685 else if (*PortFile->curPos == '\n') 686 { 687 if (retString == NULL) 688 { 689 retString = string; 690 } 691 retString[i] = '\n'; 692 PortFile->curPos++; 693 done = TRUE; 694 } 695 else 696 { 697 if (retString == NULL) 698 { 699 retString = string; 700 } 701 retString[i] = *PortFile->curPos++; 702 } 703 } 704 if (retString != NULL) 705 { 706 retString[i] = '\0'; 707 } 708 return retString; 709 } 710 711 /* 712 * Returns string or NULL if error 713 */ 714 int PortFflush(PORT_FILE PortFile) 715 { 716 if (PortFile == NULL) 717 { 718 return -1; 719 } 720 721 722 /* call fflush before reopen a writable file */ 723 if (ISWRITEMODE(PortFile->mode)) /* writable file */ 724 { 725 FileRecord *pCurRec = (FileRecord *)pWritableFileRecTable; 726 727 /* find the file record in memory */ 728 do 729 { 730 if (strcmp(pCurRec->name, PortFile->filename) == 0) 731 { 732 /* assgin it as startFrame, so others could get information when reopen it */ 733 pCurRec->start = (unsigned char *)PortFile->startFrame; 734 pCurRec->end = PortFile->size - PortFile->endFrame->size + 735 (PortFile->endPos - PortFile->endFrame->buffer); 736 pCurRec->size = PortFile->size; 737 pCurRec->mode = PortFile->mode; 738 739 break; 740 } 741 pCurRec++; 742 } 743 while (pCurRec->size > 0); 744 } 745 return 0; 746 } 747 748 749 int PortFeof(PORT_FILE PortFile) 750 { 751 passert(PortFile); 752 753 return PortFile->eof; 754 } 755 756 /* 757 * Returns character or EOF 758 */ 759 int PortFgetc(PORT_FILE PortFile) 760 { 761 int c; 762 763 passert(PortFile); 764 765 if (PortFile->eof == 1) 766 { 767 return EOF; 768 } 769 else 770 { 771 c = (int) * PortFile->curPos++; 772 773 if (PortFile->curPos >= PortFile->endPos) 774 { 775 PortFile->eof = 1; 776 } 777 } 778 return c; 779 } 780 781 /* 782 * Returns 0 if no error 783 */ 784 int PortFerror(PORT_FILE PortFile) 785 { 786 passert(PortFile); 787 788 return 0; 789 } 790 791 void PortClearerr(PORT_FILE PortFile) 792 { 793 PortFile->eof = 0; 794 } 795 796 /* 797 * Returns current file position 798 */ 799 int PortFscanf(PORT_FILE PortFile, const char* format, ...) 800 { 801 passert(PortFile); 802 803 (void)format; 804 805 /* Not supported. */ 806 passert(FALSE); 807 return 0; 808 } 809 810 void PortRewind(PORT_FILE PortFile) 811 { 812 passert(PortFile); 813 814 PortFile->curFrame = PortFile->startFrame; 815 PortFile->curPos = PortFile->startFrame->buffer; 816 817 PortFile->eof = 0; 818 } 819 820 /* 821 * NULL if it fails, otherwise a valid file pointer 822 */ 823 PORT_FILE PortFreopen(const char *path, const char *mode, PORT_FILE PortFile) 824 { 825 /* does not support reopen writable file */ 826 if (PortFclose(PortFile) == 0) 827 { 828 PortFile = PortFopen(path, mode); 829 return PortFile; 830 } 831 return NULL; 832 } 833 834 char* PortGetcwd(char *buffer, int maxlen) 835 { 836 if (maxlen >= 1) 837 buffer[0] = '\0'; 838 else 839 return NULL; 840 841 return buffer; 842 } 843 844 int PortMkdir(const char *dirname) 845 { 846 return 0; 847 } 848 849 #ifdef XANAVI_PROJECT 850 851 int PortSaveFileToDisk(PORT_FILE PortFile, const char *path, const char *fname) 852 { 853 /* ### start mod */ 854 855 FILE *fp = NULL; /* real file handle */ 856 char fullfname[256], data[256]; 857 char mode[3]; 858 const char *file; 859 int size; 860 861 if (fname == NULL) 862 file = PortFile->filename; 863 else 864 file = fname; 865 866 if (path == NULL) 867 { 868 PLogMessage("trying to save file %s...\n", file); 869 sprintf(fullfname, "%s", file); 870 } 871 else 872 { 873 PLogMessage("trying to save file %s to %s...\n", file, path); 874 sprintf(fullfname, "%s/%s", path, file); 875 } 876 877 if (ISBINARYMODE(PortFile->mode)) /* binary file, the wav file */ 878 { 879 sprintf(mode, "wb"); 880 } 881 else 882 { 883 sprintf(mode, "w"); 884 } 885 886 if ((fp = fopen(fullfname, mode)) != NULL) 887 { 888 PortRewind(PortFile); 889 890 while ((size = PortFread(data, 1, 256, PortFile)) > 0) 891 { 892 fwrite(data, 1, size, fp); 893 } 894 fclose(fp); 895 } 896 else 897 { 898 PLogError(L("Error to fopen %s with mode %s\n\n"), fullfname, mode); 899 return -1; 900 } 901 return 0; 902 } 903 904 int PortLoadFileFromDisk(PORT_FILE PortFile, const char *filename, const char *mode) 905 { 906 FILE *fp; 907 int size; 908 char data[256]; 909 910 passert(PortFile); 911 912 if (filename == NULL) 913 filename = PortFile->filename; 914 915 if (mode == NULL) 916 { 917 data[0] = 'r'; 918 if (ISBINARYMODE(PortFile->mode)) 919 data[1] = 'b'; 920 else 921 data[1] = '\0'; 922 data[2] = '\0'; 923 mode = data; 924 } 925 926 fp = fopen(filename, mode); 927 928 if (fp == NULL) /* do not have the file, it is fine */ 929 return 0; 930 931 while ((size = fread(data, 1, 256, fp)) > 0) 932 PortFwrite(data, 1, size, PortFile); 933 934 fclose(fp); 935 /* go to the beginning of the file */ 936 PortFseek(PortFile, 0, SEEK_SET); 937 938 return 0; 939 } 940 941 int XanaviSaveFileToDisk(PORT_FILE PortFile) 942 { 943 const char *tail; 944 int lenny; 945 946 passert(PortFile); 947 948 /* UG has to be 8.3 format! */ 949 lenny = strlen(PortFile->filename); 950 if (lenny > 10) 951 tail = PortFile->filename + (lenny - 11); 952 else 953 tail = PortFile->filename; 954 /* printf( "8.3 filename is %s.\n", tail ); */ 955 956 /* the 8.3 format has truncated the path in PortFile->filename, 957 should get the direcotry from par file 958 cmdline.DataCaptureDirectory = /CFC 959 TODO: here use /CFC directly to save time 960 */ 961 return PortSaveFileToDisk(PortFile, "/CFC", tail); 962 } 963 964 int XanaviLoadFileFromDisk(PORT_FILE PortFile) 965 { 966 char fname[256]; 967 char mode[3]; 968 969 passert(PortFile); 970 971 sprintf(fname, "/CFC/%s", PortFile->filename); 972 973 mode[0] = 'r'; 974 if (ISBINARYMODE(PortFile->mode)) 975 mode[1] = 'b'; 976 else 977 mode[1] = '\0'; 978 979 mode[2] = '\0'; 980 981 return PortLoadFileFromDisk(PortFile, fname, mode); 982 } 983 984 #endif 985 #endif /* STATIC_FILE_SYSTME */ 986 987 #ifdef __cplusplus 988 } 989 #endif 990 991