- Timestamp:
- Sep 1, 2011, 10:29:57 PM (13 years ago)
- Location:
- trunk/src/core
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/core/RpBuffer.cc
r2408 r2458 112 112 113 113 bool 114 Buffer::load (Outcome &status, const char * filePath)114 Buffer::load (Outcome &status, const char *path) 115 115 { 116 116 status.addContext("Rappture::Buffer::load()"); 117 117 118 118 FILE *f; 119 f = fopen( filePath, "rb");119 f = fopen(path, "rb"); 120 120 if (f == NULL) { 121 status.addError("can't open \"%s\": %s", filePath, strerror(errno)); 122 return false; 123 } 121 status.addError("can't open \"%s\": %s", path, strerror(errno)); 122 return false; 123 } 124 124 125 struct stat stat; 125 126 if (fstat(fileno(f), &stat) < 0) { 126 status.addError("can't stat \"%s\": %s", filePath, strerror(errno)); 127 return false; 128 } 129 off_t size; 130 size = stat.st_size; 131 char* memblock; 132 memblock = new char [size]; 133 if (memblock == NULL) { 127 status.addError("can't stat \"%s\": %s", path, strerror(errno)); 128 return false; 129 } 130 131 size_t oldSize, numBytesRead; 132 133 // Save the # of elements in the current buffer. 134 oldSize = count(); 135 136 // Extend the buffer to accomodate the file contents. 137 if (extend(stat.st_size) == 0) { 134 138 status.addError("can't allocate %d bytes for file \"%s\": %s", 135 size, filePath, strerror(errno));139 stat.st_size, path, strerror(errno)); 136 140 fclose(f); 137 141 return false; 138 } 139 140 // FIXME: better yet, create an "extend" method in the buffer and returns 141 // the address of the char buffer so I can read the data directly 142 // into the buffer. This eliminates memory new/copy/delete ops. 143 144 size_t nRead; 145 nRead = fread(memblock, sizeof(char), size, f); 146 fclose(f); // Close the file. 147 148 if (nRead != (size_t)size) { 149 status.addError("can't read %d bytes from \"%s\": %s", size, filePath, 150 strerror(errno)); 151 return false; 152 } 153 154 int nBytes; 155 nBytes = append(memblock, size); 156 delete [] memblock; 157 158 if (nBytes != size) { 159 status.addError("can't append %d bytes from \"%s\" to buffer: %s", 160 size, filePath, strerror(errno)); 161 return false; 162 } 163 return true; 164 } 165 166 167 bool 168 Buffer::dump (Outcome &status, const char* filePath) 142 } 143 // Read the file contents directly onto the end of the old buffer. 144 numBytesRead = fread((char *)bytes() + oldSize, sizeof(char), 145 stat.st_size, f); 146 fclose(f); 147 if (numBytesRead != (size_t)stat.st_size) { 148 status.addError("can't read %ld bytes from \"%s\": %s", stat.st_size, 149 path, strerror(errno)); 150 return false; 151 } 152 // Reset the # of elements in the buffer to the new count. 153 count(stat.st_size + oldSize); 154 return true; 155 } 156 157 158 bool 159 Buffer::dump (Outcome &status, const char* path) 169 160 { 170 161 status.addContext("Rappture::Buffer::dump()"); 171 162 172 163 FILE *f; 173 f = fopen( filePath, "wb");164 f = fopen(path, "wb"); 174 165 if (f == NULL) { 175 status.addError("can't open \"%s\": %s\n", filePath, strerror(errno));166 status.addError("can't open \"%s\": %s\n", path, strerror(errno)); 176 167 return false; 177 168 } … … 182 173 if (nWritten != (ssize_t)size()) { 183 174 status.addError("can't write %d bytes to \"%s\": %s\n", size(), 184 filePath, strerror(errno));175 path, strerror(errno)); 185 176 return false; 186 177 } … … 288 279 { 289 280 int ret=0, flush=0; 290 unsigned have=0;291 281 z_stream strm; 292 282 293 283 char in[CHUNK]; 294 284 char out[CHUNK]; 295 296 int bytesWritten = 0;297 285 298 286 /* allocate deflate state */ … … 330 318 ret = deflate(&strm, flush); /* no bad return value */ 331 319 assert(ret != Z_STREAM_ERROR); /* state not clobbered */ 320 321 int have; 332 322 have = CHUNK - strm.avail_out; 323 333 324 /* write to file and check for error */ 334 bytesWritten = bout.append(out, have); 335 if ( ( (unsigned) bytesWritten != have ) ) { 325 if (bout.append(out, have)) { 336 326 (void)deflateEnd(&strm); 337 327 bout.clear(); -
trunk/src/core/RpSimpleBuffer.h
r1850 r2458 1 1 2 /* 2 3 * ====================================================================== … … 69 70 #include <cstdarg> 70 71 72 /* 73 * Note: I think I would redo this class to deal only with unsigned byte 74 * arrays, instead of arrays of <T>. I would create other classes 75 * that arrays of <T> that used the lower level byte array. 76 * 77 * It would make it cleaner if the class only dealt with bytes 78 * instead of elements (of various sizes). 79 * 80 * Specific implementations of <T> could perform data alignment on 81 * word/double word/quad word boundaries. This is an optimization 82 * that should could done for double arrays. 83 * 84 * Note: The signed int argument on append() should be replaced with a 85 * size_t. This limits the length of strings to appended. It 86 * silently truncates bigger sizes to the lower 32-bits. 87 */ 71 88 namespace Rappture { 72 89 … … 74 91 class SimpleBuffer { 75 92 public: 76 SimpleBuffer(); 93 /** 94 * Construct an empty SimpleBuffer. 95 */ 96 SimpleBuffer() { 97 Initialize(); 98 } 99 /** 100 * Construct a SimpleBuffer loaded with initial data. 101 * 102 * @param bytes pointer to bytes being stored. 103 * @param nbytes number of bytes being stored. 104 */ 105 SimpleBuffer(const T* bytes, int numElems=-1) { 106 Initialize(); 107 append(bytes, numElems); 108 } 77 109 SimpleBuffer(size_t nmemb); 78 SimpleBuffer(const T* bytes, int nmemb=-1); 110 111 /** 112 * Copy constructor 113 * @param SimpleBuffer object to copy 114 */ 79 115 SimpleBuffer(const SimpleBuffer& b); 116 80 117 SimpleBuffer<T>& operator=(const SimpleBuffer<T>& b); 81 118 SimpleBuffer operator+(const SimpleBuffer& b) const; 82 119 SimpleBuffer<T>& operator+=(const SimpleBuffer<T>& b); 83 120 T operator[](size_t offset); 84 virtual ~SimpleBuffer(); 85 86 const T* bytes() const; 87 size_t size() const; 88 size_t nmemb() const; 89 90 SimpleBuffer<T>& clear(); 121 122 /** 123 * Destructor 124 */ 125 virtual ~SimpleBuffer() { 126 Release(); 127 } 128 129 /** 130 * Get the bytes currently stored in the buffer. These bytes can 131 * be stored, and used later to construct another Buffer to 132 * decode the information. 133 * 134 * @return Pointer to the bytes in the buffer. 135 */ 136 const T* bytes() const { 137 return _buf; 138 } 139 /** 140 * Get the number of bytes currently stored in the buffer. 141 * @return Number of the bytes used in the buffer. 142 */ 143 size_t size() const { 144 return _numElemsUsed * sizeof(T); 145 } 146 /** 147 * Get the number of members currently stored in the buffer. 148 * @return Number of the members used in the buffer. 149 */ 150 size_t nmemb() const { 151 return _numElemsUsed; 152 } 153 /** 154 * Get the number of members currently stored in the buffer. 155 * @return Number of the members used in the buffer. 156 */ 157 size_t count() const { 158 return _numElemsUsed; 159 } 160 /** 161 * Set the number of members currently stored in the buffer. 162 * @return Number of the members used in the buffer. 163 */ 164 size_t count(size_t newCount) { 165 _numElemsUsed = newCount; 166 return _numElemsUsed; 167 } 168 /** 169 * Clear the buffer, making it empty. 170 * @return Reference to this buffer. 171 */ 172 SimpleBuffer<T>& clear() { 173 Release(); 174 return *this; 175 } 176 size_t extend(size_t extraElems); 91 177 int append(const T* bytes, int nmemb=-1); 92 178 int appendf(const char *format, ...); … … 98 184 SimpleBuffer<T>& rewind(); 99 185 SimpleBuffer<T>& show(); 100 186 101 187 bool good() const; 102 188 bool bad() const; 103 189 bool eof() const; 104 190 105 191 SimpleBuffer<T>& move(SimpleBuffer<T>& b); 106 192 107 193 protected: 108 109 void bufferInit();110 void bufferFree();111 194 195 void Initialize(); 196 void Release(); 197 112 198 private: 113 199 114 200 /// Pointer to the memory that holds our buffer's data 115 201 T* _buf; 116 202 117 203 /// Position offset within the buffer's memory 118 204 size_t _pos; 119 205 120 206 /// Number of members stored in the buffer 121 size_t _n MembStored;122 207 size_t _numElemsUsed; 208 123 209 /// Total number of members available in the buffer 124 size_t _n MembAvl;125 210 size_t _numElemsAllocated; 211 126 212 /// State of the last file like operation. 127 213 bool _fileState; 128 214 129 215 /// Minimum number of members is set to the number you can fit in 256 bytes 130 const static int _min MembCnt=(256/sizeof(T));131 216 const static int _minNumElems=(256/sizeof(T)); 217 132 218 size_t __guesslen(const T* bytes); 133 219 134 220 }; 135 221 136 222 typedef SimpleBuffer<char> SimpleCharBuffer; 137 223 typedef SimpleBuffer<float> SimpleFloatBuffer; … … 139 225 140 226 /** 141 * Construct an empty SimpleBuffer.142 */143 template<class T>144 SimpleBuffer<T>::SimpleBuffer()145 {146 bufferInit();147 }148 149 150 /**151 227 * Construct an empty SimpleBuffer of specified size. 152 228 */ 153 229 template<class T> 154 SimpleBuffer<T>::SimpleBuffer(size_t n memb)155 { 156 bufferInit();157 158 if (n memb== 0) {230 SimpleBuffer<T>::SimpleBuffer(size_t numElems) 231 { 232 Initialize(); 233 234 if (numElems == 0) { 159 235 // ignore requests for sizes equal to zero 160 236 return; … … 162 238 163 239 // buffer sizes less than min_size are set to min_size 164 if (n memb < (size_t) _minMembCnt) {165 n memb = _minMembCnt;166 } 167 168 if (set(n memb) != nmemb) {240 if (numElems < (size_t) _minNumElems) { 241 numElems = _minNumElems; 242 } 243 244 if (set(numElems) != numElems) { 169 245 return; 170 246 } 171 _nMembStored = nmemb; 172 } 173 174 175 /** 176 * Construct a SimpleBuffer loaded with initial data. 177 * 178 * @param bytes pointer to bytes being stored. 179 * @param nbytes number of bytes being stored. 180 */ 181 template<class T> 182 SimpleBuffer<T>::SimpleBuffer(const T* bytes, int nmemb) 183 { 184 bufferInit(); 185 append(bytes,nmemb); 247 _numElemsUsed = numElems; 186 248 } 187 249 … … 194 256 SimpleBuffer<T>::SimpleBuffer(const SimpleBuffer<T>& b) 195 257 { 196 bufferInit();197 append(b.bytes(), b.nmemb());258 Initialize(); 259 append(b.bytes(), b.nmemb()); 198 260 } 199 261 … … 207 269 SimpleBuffer<T>::operator=(const SimpleBuffer<T>& b) 208 270 { 209 bufferFree(); 210 bufferInit(); 271 Release(); 211 272 append(b.bytes(),b.nmemb()); 212 273 return *this; … … 247 308 template<class T> 248 309 T 249 SimpleBuffer<T>::operator[](size_t idx) 250 { 251 return (_buf+idx); 252 } 253 254 255 /** 256 * Destructor 257 */ 258 template<class T> 259 SimpleBuffer<T>::~SimpleBuffer() 260 { 261 bufferFree(); 262 } 263 264 265 /** 266 * Get the bytes currently stored in the buffer. These bytes can 267 * be stored, and used later to construct another Buffer to 268 * decode the information. 269 * 270 * @return Pointer to the bytes in the buffer. 271 */ 272 template<class T> 273 const T* 274 SimpleBuffer<T>::bytes() const 275 { 276 return _buf; 277 } 278 279 280 /** 281 * Get the number of bytes currently stored in the buffer. 282 * @return Number of the bytes used in the buffer. 283 */ 284 template<class T> 285 size_t 286 SimpleBuffer<T>::size() const 287 { 288 return _nMembStored*sizeof(T); 289 } 290 291 292 /** 293 * Get the number of members currently stored in the buffer. 294 * @return Number of the members used in the buffer. 295 */ 296 template<class T> 297 size_t 298 SimpleBuffer<T>::nmemb() const 299 { 300 return _nMembStored; 301 } 302 303 304 /** 305 * Clear the buffer, making it empty. 306 * @return Reference to this buffer. 307 */ 308 template<class T> 309 SimpleBuffer<T>& 310 SimpleBuffer<T>::clear() 311 { 312 bufferFree(); 313 bufferInit(); 314 315 return *this; 316 } 310 SimpleBuffer<T>::operator[](size_t index) 311 { 312 return (_buf + index); // Rely on pointer arithmetic 313 } 314 315 317 316 318 317 /** … … 327 326 return strlen(bytes); 328 327 } 328 329 /* FIXME: Change the signed int to size_t. Move the -1 copy string 330 * up to the SimpleCharBuffer class. There needs to be both 331 * a heavy duty class that can take a string bigger than 332 * 2^31-1 in length, and a convenient class that doesn't make 333 * you add call strlen(s). 334 * 335 */ 329 336 330 337 /** … … 351 358 { 352 359 size_t newMembCnt = 0; 353 size_t nbytes = 0;354 360 355 361 void* dest = NULL; … … 361 367 return 0; 362 368 } 369 370 #ifdef notdef 371 372 /* This is dead code. The test above catches the condition. */ 363 373 364 374 // FIXME: i think this needs to be division, … … 367 377 // bytes in *bytes. 368 378 379 size_t nbytes = 0; 369 380 if (nmemb == -1) { 370 381 // user signaled null terminated string … … 379 390 return nmemb; 380 391 } 381 382 newMembCnt = (size_t)(_nMembStored + nmemb); 383 384 if (newMembCnt > _nMembAvl) { 392 #endif 393 394 newMembCnt = (size_t)(_numElemsUsed + nmemb); 395 396 if (newMembCnt > _numElemsAllocated) { 385 397 386 398 // buffer sizes less than min_size are set to min_size 387 if (newMembCnt < (size_t) _min MembCnt) {388 newMembCnt = (size_t) _min MembCnt;399 if (newMembCnt < (size_t) _minNumElems) { 400 newMembCnt = (size_t) _minNumElems; 389 401 } 390 402 … … 395 407 */ 396 408 size_t membAvl; 397 membAvl = (_n MembAvl > 0) ? _nMembAvl : _minMembCnt;409 membAvl = (_numElemsAllocated > 0) ? _numElemsAllocated : _minNumElems; 398 410 while (newMembCnt > membAvl) { 399 411 membAvl += membAvl; … … 408 420 } 409 421 410 dest = (void*) (_buf + _n MembStored);422 dest = (void*) (_buf + _numElemsUsed); 411 423 src = (void const*) bytes; 412 424 size = (size_t) (nmemb*sizeof(T)); 413 425 memcpy(dest,src,size); 414 426 415 _n MembStored += nmemb;427 _numElemsUsed += nmemb; 416 428 417 429 return nmemb; 430 } 431 432 /** 433 * Append bytes to the end of this buffer 434 * @param pointer to bytes to be added 435 * @param number of bytes to be added 436 * @return number of bytes appended. 437 */ 438 template<class T> 439 size_t 440 SimpleBuffer<T>::extend(size_t numExtraElems) 441 { 442 size_t newSize; 443 444 newSize = _numElemsUsed + numExtraElems; 445 if (newSize > _numElemsAllocated) { 446 447 /* Enforce a minimum buffer size. */ 448 if (newSize < (size_t) _minNumElems) { 449 newSize = (size_t) _minNumElems; 450 } 451 452 size_t size; 453 size = (_numElemsAllocated > 0) ? _numElemsAllocated : _minNumElems; 454 455 /* Keep doubling the size of the buffer until we have enough space to 456 * hold the extra elements. */ 457 while (newSize > size) { 458 size += size; 459 } 460 /* Reallocate to a larger buffer. */ 461 if (set(size) != size) { 462 return 0; 463 } 464 } 465 return _numElemsAllocated; 418 466 } 419 467 … … 463 511 } 464 512 465 newMembCnt = (size_t)(_n MembStored + nmemb);466 467 if (newMembCnt > _n MembAvl) {513 newMembCnt = (size_t)(_numElemsUsed + nmemb); 514 515 if (newMembCnt > _numElemsAllocated) { 468 516 469 517 // buffer sizes less than min_size are set to min_size 470 if (newMembCnt < (size_t) _min MembCnt) {471 newMembCnt = (size_t) _min MembCnt;518 if (newMembCnt < (size_t) _minNumElems) { 519 newMembCnt = (size_t) _minNumElems; 472 520 } 473 521 … … 478 526 */ 479 527 size_t membAvl; 480 membAvl = (_n MembAvl > 0) ? _nMembAvl : _minMembCnt;528 membAvl = (_numElemsAllocated > 0) ? _numElemsAllocated : _minNumElems; 481 529 while (newMembCnt > membAvl) { 482 530 membAvl += membAvl; … … 491 539 } 492 540 493 dest = (char*) (_buf + _n MembStored);494 size = (_n MembAvl-_nMembStored)*sizeof(T);541 dest = (char*) (_buf + _numElemsUsed); 542 size = (_numElemsAllocated-_numElemsUsed)*sizeof(T); 495 543 496 544 va_start(arg,format); … … 511 559 512 560 // FIXME: round the new size up to the nearest multiple of 256? 513 set(_n MembStored+nmemb);561 set(_numElemsUsed+nmemb); 514 562 515 563 // reset dest because it may have moved during reallocation 516 dest = (char*) (_buf + _n MembStored);564 dest = (char*) (_buf + _numElemsUsed); 517 565 size = bytesAdded; 518 566 … … 528 576 } 529 577 530 _n MembStored += nmemb;578 _numElemsUsed += nmemb; 531 579 532 580 // remove the null character added by vsnprintf() … … 549 597 SimpleBuffer<T>::remove(int nmemb) 550 598 { 551 if ((_n MembStored - nmemb) < 0){552 _n MembStored = 0;599 if ((_numElemsUsed - nmemb) < 0){ 600 _numElemsUsed = 0; 553 601 _pos = 0; 554 602 } else { 555 _n MembStored -= nmemb;556 if (_pos >= _n MembStored) {603 _numElemsUsed -= nmemb; 604 if (_pos >= _numElemsUsed) { 557 605 // move _pos back to the new end of the buffer. 558 _pos = _n MembStored-1;606 _pos = _numElemsUsed-1; 559 607 } 560 608 } … … 563 611 return nmemb; 564 612 } 565 566 613 567 614 template<class T> … … 585 632 } 586 633 _buf = buf; 587 _nMembAvl = nmemb; 588 return _nMembAvl; 589 } 590 634 _numElemsAllocated = nmemb; 635 return _numElemsAllocated; 636 } 591 637 592 638 template<> inline … … 596 642 size_t curMemb = 0; 597 643 598 while (curMemb != _n MembStored) {644 while (curMemb != _numElemsUsed) { 599 645 fprintf(stdout,"_buf[%lu] = :%c:\n", (long unsigned int)curMemb, 600 646 _buf[curMemb]); 601 647 curMemb += 1; 602 648 } 603 fprintf(stdout,"_nMembAvl = :%lu:\n", (long unsigned int)_nMembAvl); 649 fprintf(stdout,"_numElemsAllocated = :%lu:\n", 650 (long unsigned int)_numElemsAllocated); 604 651 605 652 return *this; … … 613 660 size_t curMemb = 0; 614 661 615 while (curMemb != _n MembStored) {662 while (curMemb != _numElemsUsed) { 616 663 fprintf(stdout,"_buf[%lu] = :%#x:\n", (long unsigned int)curMemb, 617 664 (unsigned long)_buf[curMemb]); 618 665 curMemb += 1; 619 666 } 620 fprintf(stdout,"_n MembAvl = :%lu:\n", (long unsigned int)_nMembAvl);667 fprintf(stdout,"_numElemsAllocated = :%lu:\n", (long unsigned int)_numElemsAllocated); 621 668 622 669 return *this; … … 651 698 652 699 // make sure we don't read off the end of our buffer 653 if ( (_pos + nmemb) > _n MembStored ) {654 nMembRead = _n MembStored - _pos;700 if ( (_pos + nmemb) > _numElemsUsed ) { 701 nMembRead = _numElemsUsed - _pos; 655 702 } 656 703 else { … … 694 741 _pos = 0; 695 742 } 696 else if (offset >= (long)_n MembStored) {743 else if (offset >= (long)_numElemsUsed) { 697 744 /* dont go off the end of data */ 698 _pos = _n MembStored - 1;745 _pos = _numElemsUsed - 1; 699 746 } 700 747 else { … … 707 754 _pos = 0; 708 755 } 709 else if ((_pos + offset) >= _n MembStored) {756 else if ((_pos + offset) >= _numElemsUsed) { 710 757 /* dont go off the end of data */ 711 _pos = _n MembStored - 1;758 _pos = _numElemsUsed - 1; 712 759 } 713 760 else { … … 716 763 } 717 764 else if (whence == SEEK_END) { 718 if (offset <= (long)(-1*_n MembStored)) {765 if (offset <= (long)(-1*_numElemsUsed)) { 719 766 /* dont go off the beginning of data */ 720 767 _pos = 0; … … 722 769 else if (offset >= 0) { 723 770 /* dont go off the end of data */ 724 _pos = _n MembStored - 1;771 _pos = _numElemsUsed - 1; 725 772 } 726 773 else { 727 _pos = (size_t)((_n MembStored - 1) + offset);774 _pos = (size_t)((_numElemsUsed - 1) + offset); 728 775 } 729 776 } … … 794 841 SimpleBuffer<T>::eof() const 795 842 { 796 return (_pos >= _n MembStored);843 return (_pos >= _numElemsUsed); 797 844 } 798 845 … … 801 848 * Move the data from this SimpleBuffer to the SimpleBuffer provided by 802 849 * the caller. All data except the _pos is moved and this SimpleBuffer is 803 * re-initialized with bufferInit().850 * re-initialized with Initialize(). 804 851 * @param SimpleBuffer to move the information to 805 852 * @return reference to this SimpleBuffer object. … … 809 856 SimpleBuffer<T>::move(SimpleBuffer<T>& b) 810 857 { 811 bufferFree();858 Release(); 812 859 813 860 _buf = b._buf; 814 861 _pos = b._pos; 815 862 _fileState = b._fileState; 816 _n MembStored = b._nMembStored;817 _n MembAvl = b._nMembAvl;818 819 b. bufferInit();863 _numElemsUsed = b._numElemsUsed; 864 _numElemsAllocated = b._numElemsAllocated; 865 866 b.Initialize(); 820 867 821 868 return *this; … … 825 872 /** 826 873 * Initializes a dynamic buffer, discarding any previous contents 827 * of the buffer. bufferFree() should have been called already874 * of the buffer. Release() should have been called already 828 875 * if the dynamic buffer was previously in use. 829 876 */ 830 877 template<class T> 831 878 void 832 SimpleBuffer<T>:: bufferInit()879 SimpleBuffer<T>::Initialize() 833 880 { 834 881 _buf = NULL; 835 882 _pos = 0; 836 883 _fileState = true; 837 _n MembStored = 0;838 _n MembAvl= 0;884 _numElemsUsed = 0; 885 _numElemsAllocated = 0; 839 886 } 840 887 … … 846 893 template<class T> 847 894 void 848 SimpleBuffer<T>:: bufferFree()895 SimpleBuffer<T>::Release() 849 896 { 850 897 if (_buf != NULL) { … … 852 899 _buf = NULL; 853 900 } 854 bufferInit();901 Initialize(); 855 902 } 856 903 -
trunk/src/core/scew/xhandler.c
r1559 r2458 193 193 } 194 194 if (bytes == NULL) { 195 fprintf(stderr, "can't allocated % dbytes for character data\n",195 fprintf(stderr, "can't allocated %lu bytes for character data\n", 196 196 size); 197 197 return;
Note: See TracChangeset
for help on using the changeset viewer.