home *** CD-ROM | disk | FTP | other *** search
-
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
-
- #include "NString.h"
- #include "NString_Misc.h"
-
- unsigned long int NString::BufferSizeStep = 100;
- float NString::DeallocationTrigger = 0.2;
- unsigned long int NString::DeallocationMargin = 20;
-
- #ifndef USE_EXCEPTIONS
-
- void (*NString::panic)(const unsigned long int, const char *, const char *, const char *) = &NString::NString_Error;
-
- void NString::Out_of_Memory (unsigned int line, const char *file, const char *function)
- {
- NString::panic(line, file, function, "Out of memory");
- exit(1);
- }
-
-
- void NString::NString_Error (const unsigned long int line, const char *file,
- const char *function, const char *message)
- {
- fprintf(stderr, "*** NString runtime error: %s at line %d in source file \"%s\" (function \"%s\").\n",
- message, line, file, function);
- exit(1);
- }
-
- #else
-
- NString::Exception::Exception (const unsigned long int line, const char *file, const char *function, const char *message)
- : ErrorLine(line)
- {
- strncpy(ErrorFile, file, MAX_MSG_LENGTH);
- ErrorFile[MAX_MSG_LENGTH] = '\0';
- strncpy(ErrorMessage, message, MAX_MSG_LENGTH);
- ErrorMessage[MAX_MSG_LENGTH] = '\0';
- strncpy(ErrorFunction, function, MAX_MSG_LENGTH);
- ErrorFunction[MAX_MSG_LENGTH] = '\0';
- }
-
-
- virtual void NString::Exception::PrintError (ostream& theStream)
- {
- theStream << ErrorMessage << " at line " << ErrorLine << " in source file \""
- << ErrorFile << "\" (function \"" << ErrorFunction << "\").\n";
- }
-
- #endif
-
- //_________________________________________________________________________________
-
- int NString::DuplicateSB (void)
- {
- strbody *old_sb = sb;
-
- if ((sb = new strbody) == NULL)
- {
- sb = old_sb; // undo modifications
- return 0;
- }
-
- if (! AllocStrBuf(old_sb->len))
- {
- delete sb;
- sb = old_sb; // undo modifications
- return 0;
- }
-
- strcpy(sb->str, old_sb->str);
- old_sb->refs--; // disconnect from old string body
- return 1;
- }
-
- //_________________________________________________________________________________
-
- int NString::GetNewSB (unsigned long int new_length)
- {
- strbody *old_sb = sb;
-
- if ((sb = new strbody) == NULL)
- {
- sb = old_sb; // undo modifications
- return 0;
- }
-
- if (! AllocStrBuf(new_length))
- {
- delete sb;
- sb = old_sb; // undo modifications
- return 0;
- }
-
- sb->str[new_length] = '\0'; // terminate string
- old_sb->refs--; // disconnect from old string body
- return 1;
- }
-
- //_________________________________________________________________________________
-
- NString::NString (const unsigned long int l)
- {
- const char *fname = "NString (const unsigned long int)";
-
- if ((sb = new strbody) == NULL)
- OUT_OF_MEM(fname);
- if (! AllocStrBuf(l))
- {
- delete sb;
- sb = NULL;
- OUT_OF_MEM(fname);
- }
- sb->str[l] = '\0';
-
- #if (NSTRING_DEBUG & 2) != 0
- printf("Construction of uninitialized NString of length %ld.\n", l);
- #endif
- }
-
- //_________________________________________________________________________________
-
- char *NString::AllocStrBuf (unsigned long int size)
- {
- unsigned long int string_size = size;
-
- size++; // size now denotes the wanted buffer-size
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("-- AllocStrBuf: %ld bytes requested, ", size);
- #endif
-
- if (BufferSizeStep != 1)
- {
- unsigned long int modulo = size % BufferSizeStep;
-
- if (modulo != 0)
- size = (size - modulo) + BufferSizeStep; // adjust size to be a multiple of "BufferSizeStep"
- }
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("allocating %ld bytes.\n", size);
- #endif
-
- char *buffer = (char *)malloc(size); // attempt the allocation
-
- if (buffer != NULL)
- {
- sb->len = string_size; // inscribe string length
- sb->bufsize = size; // inscribe buffer size
- sb->str = buffer; // inscribe buffer address
- }
-
- return (buffer);
- }
-
- //_________________________________________________________________________________
-
- char *NString::ReallocStrBuf (unsigned long int size)
- {
- unsigned long int new_bufsize = size + 1; // the wanted buffer-size
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("-- ReallocStrBuf: wanted -> %ld bytes / buffer -> %ld bytes, ", new_bufsize, sb->bufsize);
- #endif
-
- if (BufferSizeStep != 1)
- {
- unsigned long int modulo, old_bufsize;
-
- modulo = new_bufsize % BufferSizeStep;
- if (modulo != 0) // adjust size to be a multiple of "BufferSizeStep"
- new_bufsize = (new_bufsize - modulo) + BufferSizeStep;
-
- modulo = sb->bufsize % BufferSizeStep;
- if (modulo != 0) // align old buffer size if necessary
- old_bufsize = (sb->bufsize - modulo) + BufferSizeStep;
- else
- old_bufsize = sb->bufsize;
-
- if ((new_bufsize + BufferSizeStep == old_bufsize) // deallocation of BufferSizeStep bytes asked ...
- && (size >= (new_bufsize - DeallocationMargin))) // ... but wanted size is too near new_bufsize
- {
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("deallocation margin not reached.\n");
- #endif
-
- return (sb->str);
- }
- }
-
- if (new_bufsize == sb->bufsize) // Is a buffer size change needed ?
- {
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("no change.\n");
- #endif
-
- return (sb->str);
- }
-
- #if (NSTRING_DEBUG & 4) != 0
- printf("reallocating %ld bytes.\n", new_bufsize);
- #endif
-
- char *buffer = (char *)realloc(sb->str, new_bufsize); // attempt reallocation
-
- if (buffer != NULL)
- {
- sb->bufsize = new_bufsize; // inscribe new buffer size
- sb->str = buffer; // inscribe new buffer address
- }
-
- return (buffer);
- }
-