Changeset 4426
- Timestamp:
- Oct 5, 2000, 9:27:57 AM (25 years ago)
- Location:
- trunk/tools/common
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/tools/common/kFile.cpp ¶
r4402 r4426 1 /* $Id: kFile.cpp,v 1. 6 2000-10-03 05:42:38bird Exp $1 /* $Id: kFile.cpp,v 1.7 2000-10-05 07:27:56 bird Exp $ 2 2 * 3 3 * kFile - Simple (for the time being) file class. … … 84 84 offReal = offVirtual; 85 85 } 86 else 87 rc = NO_ERROR; 86 88 87 89 return TRUE; 88 90 } 91 92 93 /** 94 * Reads data from the file into the buffer from the given file offset. 95 * @returns Success indicator. 96 * @param offFile File offset to read from. 97 * (If readonly and beyond end of file the offset used 98 * may be addjusted.) 99 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 100 */ 101 BOOL kFile::bufferRead(ULONG offFile) throw (int) 102 { 103 ULONG cbRead; 104 105 /* refresh file status (cbFile) */ 106 if (!refreshFileStatus()) 107 return FALSE; 108 109 /* check that the request is valid */ 110 if (offFile > filestatus.cbFile) 111 return FALSE; 112 113 /* commit dirty buffer */ 114 if (fBufferDirty) 115 { 116 if (!bufferCommit()) 117 return TRUE; 118 119 /* refresh file status (cbFile) */ 120 if (!refreshFileStatus()) 121 return FALSE; 122 } 123 124 /* If readonly file optimize end of file */ 125 if (fReadOnly && cbBuffer + offFile > filestatus.cbFile) 126 offFile = filestatus.cbFile > cbBuffer ? filestatus.cbFile - cbBuffer : 0UL; 127 128 /* need to change file ptr? */ 129 if (offFile != offReal) 130 { 131 ULONG ul; 132 rc = DosSetFilePtr(hFile, offFile, FILE_BEGIN, &ul); 133 if (rc != NO_ERROR) 134 { 135 if (fThrowErrors) 136 throw ((int)rc); 137 return FALSE; 138 } 139 offReal = offFile; 140 } 141 142 /* read from the file */ 143 cbRead = min(filestatus.cbFile - offFile, cbBuffer); 144 rc = DosRead(hFile, pachBuffer, cbRead, &cbRead); 145 if (rc == NO_ERROR) 146 { 147 cbBufferValid = cbRead; 148 offBuffer = offFile; 149 offReal = offFile + cbRead; 150 fBufferDirty = FALSE; 151 } 152 else 153 { 154 cbBufferValid = 0; 155 offBuffer = ~0UL; 156 fBufferDirty = FALSE; 157 if (fThrowErrors) 158 throw ((int)rc); 159 return FALSE; 160 } 161 162 return TRUE; 163 } 164 165 166 /** 167 * Commits the data in the buffer. 168 * @returns Success indicator. 169 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 170 */ 171 BOOL kFile::bufferCommit(void) throw (int) 172 { 173 ULONG cbWrote; 174 ULONG ul; 175 176 /* don't commit clean buffers! */ 177 if (!fBufferDirty) 178 return TRUE; 179 180 /* need to change file ptr? */ 181 if (offBuffer != offReal) 182 { 183 rc = DosSetFilePtr(hFile, offBuffer, FILE_BEGIN, &ul); 184 if (rc != NO_ERROR) 185 { 186 if (fThrowErrors) 187 throw ((int)rc); 188 return FALSE; 189 } 190 offReal = offBuffer; 191 } 192 193 /* write to the file */ 194 rc = DosWrite(hFile, pachBuffer, cbBufferValid, &cbWrote); 195 fStatusClean = FALSE; 196 if (rc == NO_ERROR) 197 { 198 fBufferDirty = FALSE; 199 offReal += cbWrote; 200 } 201 else 202 { 203 DosSetFilePtr(hFile, offReal, FILE_BEGIN, &ul); 204 if (fThrowErrors) 205 throw ((int)rc); 206 return FALSE; 207 } 208 209 return TRUE; 210 } 211 89 212 90 213 /** … … 107 230 pszFilename(NULL), 108 231 hFile(hFile), 109 fStdDev(TRUE) 232 fStdDev(TRUE), 233 pachBuffer(NULL), 234 cbBufferValid(0UL), 235 offBuffer(~0UL), 236 fBufferDirty(FALSE) 110 237 { 111 238 if (!refreshFileStatus()) … … 132 259 offReal(0), 133 260 pszFilename(NULL), 134 fStdDev(FALSE) 261 fStdDev(FALSE), 262 pachBuffer(NULL), 263 cbBufferValid(0UL), 264 offBuffer(~0UL), 265 fBufferDirty(FALSE) 135 266 { 136 267 ULONG fulOpenFlags; … … 166 297 if (this->pszFilename == NULL) 167 298 throw (ERROR_NOT_ENOUGH_MEMORY); 299 300 /* Buffering */ 301 cbBuffer = (fReadOnly && filestatus.cbFile < 32768) ? filestatus.cbFile : 8192; 302 pachBuffer = new char[cbBuffer]; 303 if (pachBuffer == NULL) 304 throw (ERROR_NOT_ENOUGH_MEMORY); 305 if (fReadOnly && filestatus.cbFile < 32768) 306 { 307 if (!bufferRead(0)) 308 throw ((int)rc); 309 } 168 310 } 169 311 … … 174 316 kFile::~kFile() 175 317 { 318 if (fBufferDirty) 319 bufferCommit(); 320 if (pachBuffer) 321 delete pachBuffer; 176 322 DosClose(hFile); 177 323 } … … 186 332 BOOL kFile::read(void *pvBuffer, long cbBuffer) 187 333 { 188 if (position()) 189 { 190 ULONG cbRead; 334 ULONG cbRead; 335 336 /* Validate parameters */ 337 if (cbBuffer == 0) 338 return TRUE; 339 if (cbBuffer < 0) 340 { 341 rc = ERROR_INVALID_PARAMETER; 342 if (fThrowErrors) 343 throw ((int)rc); 344 return FALSE; 345 } 346 347 /* refresh file status (cbFile) */ 348 if (!refreshFileStatus()) 349 return FALSE; 350 351 /* check if valid request */ 352 if ( offVirtual > filestatus.cbFile 353 || offVirtual + cbBuffer > filestatus.cbFile 354 ) 355 { /* invalid request */ 356 rc = ERROR_NO_DATA; 357 } 358 else if (this->cbBufferValid == filestatus.cbFile && offBuffer == 0) 359 { 360 /* 361 * The entire file is buffered 362 * Complete the request. 363 */ 364 memcpy(pvBuffer, &pachBuffer[offVirtual], (size_t)cbBuffer); 365 offVirtual += cbBuffer; 366 rc = NO_ERROR; 367 } 368 else if (pachBuffer && cbBuffer <= this->cbBuffer) 369 { /* 370 * Buffered read. (request not bigger than the buffer!) 371 * Update status (filesize). 372 * Check if the request is with the bounds of the file. 373 * Not in buffer? 374 * Then read more data into buffer. 375 * In buffer? 376 * Then complete the request. 377 * 378 */ 379 while (cbBuffer > 0) 380 { 381 /* Part or all in buffer? */ 382 if (pachBuffer != NULL && 383 offVirtual >= offBuffer && 384 offVirtual < offBuffer + cbBufferValid 385 ) 386 { /* copy data from buffer */ 387 cbRead = cbBufferValid - offVirtual + offBuffer; 388 cbRead = min(cbRead, cbBuffer); 389 memcpy(pvBuffer, &pachBuffer[offVirtual - offBuffer], (size_t)cbRead); 390 offVirtual += cbRead; 391 pvBuffer = (char*)pvBuffer + cbRead; 392 cbBuffer -= cbRead; 393 } 394 else 395 { 396 /* read into buffer */ 397 if (!bufferRead(offVirtual)) 398 return FALSE; 399 } 400 } 401 402 rc = NO_ERROR; 403 } 404 else if (position()) 405 { /* 406 * unbuffered read. 407 */ 191 408 rc = DosRead(hFile, pvBuffer, cbBuffer, &cbRead); 192 409 if (rc == NO_ERROR) 193 {194 410 offVirtual = offReal += cbRead; 195 return TRUE; 196 } 197 } 198 199 if (fThrowErrors) 200 throw ((int)rc); 201 return FALSE; 411 } 412 413 /* check for error and return accordingly */ 414 if (rc) 415 { 416 if (fThrowErrors) 417 throw ((int)rc); 418 return FALSE; 419 } 420 return TRUE; 202 421 } 203 422 … … 255 474 * @status partially implemented. 256 475 * @author knut st. osmundsen (knut.stange.osmundsen@mynd.no) 257 * @remark Should implemented buffered read ASAP!258 476 */ 259 477 BOOL kFile::readln(char *pszBuffer, long cchBuffer) throw (int) 260 478 { 261 char *psz; 262 long cbRead = min(max((long)filestatus.cbFile - (long)offVirtual, 0), cchBuffer-1); 479 long cbRead; 480 481 /* refresh file status (cbFile) */ 482 if (!refreshFileStatus()) 483 return FALSE; 263 484 264 485 /* 265 * Read full buffer length or remining part of file into the buffer.266 * Look for line end.267 * Found lineend: cut buffer there and rewind file back to that point (but skipping the newline).486 * Buffered read. 487 * Calc max read size. 488 * Loop buffer by buffer looking for a newline. 268 489 */ 269 if (cbRead == 0 || !read(pszBuffer, cbRead) ) 490 cbRead = min(max((long)filestatus.cbFile - (long)offVirtual, 0), cchBuffer-1); 491 if (cbRead == 0) 270 492 return FALSE; 271 493 272 pszBuffer[cbRead] = '\0'; 273 274 psz = strpbrk(pszBuffer, "\r\n"); 275 if (psz != NULL) 276 { 277 cbRead -= psz - pszBuffer; 278 if (*psz == '\r') 494 while (cbRead > 0) 495 { 496 char *pszNewLine; 497 char *pszReturn; 498 char *pszEnd; 499 unsigned long cch; 500 501 /* read more buffer ? */ 502 if (offVirtual >= offBuffer + cbBufferValid || offVirtual < offBuffer) 503 if (!bufferRead(offVirtual)) 504 return FALSE; 505 506 /* Scan buffer for new line */ 507 pszNewLine = (char*)memchr(&pachBuffer[offVirtual - offBuffer], '\r', (size_t)(cbBufferValid - offVirtual + offBuffer)); 508 pszReturn = (char*)memchr(&pachBuffer[offVirtual - offBuffer], '\n', (size_t)(cbBufferValid - offVirtual + offBuffer)); 509 if (pszNewLine != NULL || pszReturn != NULL) 279 510 { 280 if (psz[1] == '\n') 281 cbRead -= 2; 511 pszEnd = pszReturn != NULL && (pszNewLine == NULL || pszReturn < pszNewLine) ? 512 pszReturn : pszNewLine; 513 cch = pszEnd - &pachBuffer[offVirtual - offBuffer]; 514 } 515 else 516 { 517 pszEnd = NULL; 518 cch = cbBufferValid - offVirtual + offBuffer; 519 } 520 521 /* copy into result buffer */ 522 memcpy(pszBuffer, &pachBuffer[offVirtual - offBuffer], (size_t)cch); 523 cbRead -= cch; 524 offVirtual += cch; 525 pszBuffer += cch; 526 *pszBuffer = '\0'; 527 528 /* check for completion */ 529 if (pszEnd != NULL) 530 { /* skip newline */ 531 if (pszEnd[0] == '\r') 532 { 533 if (cch + 1 > cbBufferValid) 534 { 535 if (bufferRead(offBuffer + cbBufferValid)) 536 pszEnd = pachBuffer; 537 } 538 else 539 pszEnd++; 540 offVirtual += pszEnd != NULL && *pszEnd == '\n' ? 2 : 1; 541 } 282 542 else 283 cbRead--; 284 } 285 else if (*psz == '\n') 286 cbRead--; 287 288 *psz = '\0'; 289 290 return move(-cbRead); 543 offVirtual++; 544 return TRUE; 545 } 291 546 } 292 547 … … 307 562 else 308 563 { 309 if (position()) 310 { 564 ULONG cbWrite; 565 ULONG cbAddPost = 0; 566 567 /* buffered writes? */ 568 if (pachBuffer != NULL) 569 { /* Buffered write! 570 * Init buffer if necessary. 571 * Check if all fits into current buffer. 572 * Update buffer and return. 573 * Check if some fits into the current buffer 574 * Start - update valid part of the buffer. Commit buffer. 575 * End - update buffer. no write 576 * Not - commit buffer. 577 */ 578 if (offBuffer == ~0UL) 579 { /* Empty buffer at current virtual offset */ 580 cbBufferValid = offVirtual; 581 offBuffer = 0; 582 } 583 584 if ( offBuffer <= offVirtual 585 && offBuffer + this->cbBuffer > offVirtual + cbBuffer 586 ) 587 { /* all fits into the buffer */ 588 memcpy(&pachBuffer[offVirtual - offBuffer], pvBuffer, (size_t)cbBuffer); 589 fBufferDirty = TRUE; 590 if (cbBufferValid < offVirtual - offBuffer + cbBuffer) 591 cbBufferValid = offVirtual - offBuffer + cbBuffer; 592 offVirtual += cbBuffer; 593 return TRUE; 594 } 595 else if ( offBuffer <= offVirtual 596 && offBuffer + this->cbBufferValid > offVirtual 597 ) 598 { /* start fits into the valid part of the buffer */ 599 cbWrite = this->cbBuffer - (offVirtual - offBuffer); 600 memcpy(&pachBuffer[offVirtual - offBuffer], pvBuffer, (size_t)cbWrite); 601 fBufferDirty = TRUE; 602 if (cbBufferValid < offVirtual - offBuffer + cbWrite) 603 cbBufferValid = offVirtual - offBuffer + cbWrite; 604 pvBuffer = (char*)pvBuffer + cbWrite; 605 cbBuffer -= cbWrite; 606 offVirtual += cbWrite; 607 if (!bufferCommit()) 608 return FALSE; 609 } 610 else if ( offBuffer < offVirtual + cbBuffer 611 && offBuffer + this->cbBuffer >= offVirtual + cbBuffer 612 ) 613 { /* end fits into the buffer */ 614 cbWrite = offVirtual + cbBuffer - offBuffer; 615 memcpy(pachBuffer, &((char*)pvBuffer)[offBuffer - offVirtual], (size_t)cbWrite); 616 fBufferDirty = TRUE; 617 if (cbBufferValid < cbWrite) 618 cbBufferValid = cbWrite; 619 cbBuffer -= cbWrite; 620 cbAddPost = cbWrite; 621 } 622 else if ( offVirtual + cbBuffer <= offBuffer 623 || offVirtual >= offBuffer + this->cbBufferValid 624 ) 625 { /* don't fit into the buffer at all */ 626 if (!bufferCommit()) 627 return FALSE; 628 } 629 630 /* Set filepointer. */ 631 if (!position()) 632 return FALSE; 633 634 /* Write. */ 635 rc = DosWrite(hFile, pvBuffer, cbBuffer, &cbWrite); 636 if (rc == NO_ERROR) 637 { 638 offVirtual = offReal += cbWrite; 639 if (cbAddPost == 0) 640 { /* no post add; start empty buffer at current virtual offset .*/ 641 offBuffer = offVirtual; 642 cbBufferValid = 0; 643 fBufferDirty = FALSE; 644 } 645 else 646 offVirtual += cbAddPost; 647 return TRUE; 648 } 649 } 650 else if (position()) 651 { /* non-buffered write! */ 311 652 ULONG cbWrote; 312 653 … … 314 655 if (rc == NO_ERROR) 315 656 { 316 fStatusClean = FALSE;317 657 offVirtual = offReal += cbWrote; 318 658 return TRUE; … … 358 698 /* !QUICK AND DIRTY! */ 359 699 char * psz, * pszEnd; 360 char * pszBuffer = (char*)malloc(1024*64); //64KB should normally be enough...700 static char szBuffer[1024*64]; //64KB should normally be enough for anyone... 361 701 362 702 va_start(arg, pszFormat); 363 pszEnd = vsprintf( pszBuffer, pszFormat, arg) + pszBuffer;703 pszEnd = vsprintf(szBuffer, pszFormat, arg) + szBuffer; 364 704 va_end(arg); 365 705 366 706 psz = pszEnd; 367 while (psz > pszBuffer)707 while (psz > szBuffer) 368 708 { 369 709 if (*psz-- == '\n' && *psz != '\r') … … 375 715 } 376 716 377 write(pszBuffer, pszEnd - pszBuffer); 378 free(pszBuffer); 717 write(szBuffer, pszEnd - szBuffer); 379 718 380 719 return (int)(getPos() - offStart); … … 401 740 402 741 403 404 742 /** 405 743 * Appends the AppendFile to this file. … … 437 775 return *this; 438 776 } 439 440 777 441 778 … … 501 838 if (!refreshFileStatus()) 502 839 return FALSE; 503 offVirtual = filestatus.cbFile; //?? or +1 840 841 if (!fReadOnly && pachBuffer && offBuffer != ~0UL && offBuffer + cbBufferValid > filestatus.cbFile) 842 /* a writable file with buffer might have uncommited data in the buffer. */ 843 offVirtual = offBuffer + cbBufferValid; 844 else 845 offVirtual = filestatus.cbFile; 846 504 847 rc = NO_ERROR; 505 848 return TRUE; -
TabularUnified trunk/tools/common/kFile.h ¶
r4402 r4426 1 /* $Id: kFile.h,v 1. 6 2000-10-03 05:42:38bird Exp $1 /* $Id: kFile.h,v 1.7 2000-10-05 07:27:57 bird Exp $ 2 2 * 3 3 * kFile - Simple (for the time being) file class. … … 38 38 39 39 /** @cat Buffering datamembers */ 40 char * pachBuffer; /* Pointer to the buffer. NULL if not buffering. */ 41 unsigned long cbBuffer; /* Count of allocated bytes. */ 42 unsigned long offBuffer; /* Virtual file offset where the buffer starts. */ 43 unsigned long cbBufferValid; /* Count of valid bytes in the buffer. */ 44 BOOL fBufferDirty; /* Dirty flag. Set when the buffer needs to be committed. */ 45 46 /** @cat internal buffer methods */ 47 BOOL bufferRead(ULONG offFile) throw (int); 48 BOOL bufferCommit(void) throw (int); 40 49 41 50 /** @cat internal methods for maintaing internal structures. */ -
TabularUnified trunk/tools/common/kFileDef.cpp ¶
r4424 r4426 114 114 if (pFile->start()) 115 115 { 116 this->read(pFile); 116 try 117 { 118 this->read(pFile); 119 } 120 catch (int err) 121 { 122 throw (err); 123 } 117 124 } 118 125 else -
TabularUnified trunk/tools/common/makefile.icc ¶
r4402 r4426 1 # $Id: makefile.icc,v 1.1 2 2000-10-03 05:42:40bird Exp $1 # $Id: makefile.icc,v 1.13 2000-10-05 07:27:57 bird Exp $ 2 2 3 3 # … … 54 54 $(OBJDIR)\commonicc.lib: $(OBJS) 55 55 $(RM) $@ 56 $(ILIB) /nobackup $@ $(OBJS: = +), NUL;56 $(ILIB)/quiet /nobackup $@ $(OBJS: = +), NUL; 57 57 58 58 # kDump
Note:
See TracChangeset
for help on using the changeset viewer.