home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 July / macformat-026.iso / mac / Shareware City / Developers / NString 1.0 beta / Sources / NString_Private.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  5.5 KB  |  219 lines  |  [TEXT/KAHL]

  1.  
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5.  
  6. #include "NString.h"
  7. #include "NString_Misc.h"
  8.  
  9. unsigned long int NString::BufferSizeStep = 100;
  10. float NString::DeallocationTrigger = 0.2;
  11. unsigned long int NString::DeallocationMargin = 20;
  12.  
  13. #ifndef USE_EXCEPTIONS
  14.  
  15. void (*NString::panic)(const unsigned long int, const char *, const char *, const char *) = &NString::NString_Error;
  16.  
  17. void NString::Out_of_Memory (unsigned int line, const char *file, const char *function)
  18. {
  19.     NString::panic(line, file, function, "Out of memory");    
  20.     exit(1);
  21. }
  22.  
  23.  
  24. void NString::NString_Error (const unsigned long int line, const char *file,
  25.                                             const char *function, const char *message)
  26. {
  27.     fprintf(stderr, "*** NString runtime error: %s at line %d in source file \"%s\" (function \"%s\").\n",
  28.                 message, line, file, function);
  29.     exit(1);
  30. }
  31.  
  32. #else
  33.  
  34. NString::Exception::Exception (const unsigned long int line, const char *file, const char *function, const char *message)
  35.     : ErrorLine(line)
  36. {
  37.     strncpy(ErrorFile, file, MAX_MSG_LENGTH);
  38.     ErrorFile[MAX_MSG_LENGTH] = '\0';
  39.     strncpy(ErrorMessage, message, MAX_MSG_LENGTH);
  40.     ErrorMessage[MAX_MSG_LENGTH] = '\0';
  41.     strncpy(ErrorFunction, function, MAX_MSG_LENGTH);
  42.     ErrorFunction[MAX_MSG_LENGTH] = '\0';
  43. }
  44.  
  45.  
  46. virtual void NString::Exception::PrintError (ostream& theStream)
  47. {
  48.     theStream << ErrorMessage << " at line " << ErrorLine << " in source file \""
  49.                     << ErrorFile << "\" (function \"" << ErrorFunction << "\").\n";
  50. }
  51.  
  52. #endif
  53.  
  54. //_________________________________________________________________________________
  55.  
  56. int NString::DuplicateSB (void)
  57. {
  58.     strbody *old_sb = sb;
  59.     
  60.     if ((sb = new strbody) == NULL)
  61.     {
  62.         sb = old_sb;                                                                            // undo modifications
  63.         return 0;
  64.     }
  65.     
  66.     if (! AllocStrBuf(old_sb->len))
  67.     {
  68.         delete sb;
  69.         sb = old_sb;                                                                            // undo modifications
  70.         return 0;
  71.     }
  72.     
  73.     strcpy(sb->str, old_sb->str);
  74.     old_sb->refs--;                                                                            // disconnect from old string body
  75.     return 1;
  76. }
  77.         
  78. //_________________________________________________________________________________
  79.  
  80. int NString::GetNewSB (unsigned long int new_length)
  81. {
  82.     strbody *old_sb = sb;
  83.     
  84.     if ((sb = new strbody) == NULL)
  85.     {
  86.         sb = old_sb;                                                                            // undo modifications
  87.         return 0;
  88.     }
  89.     
  90.     if (! AllocStrBuf(new_length))
  91.     {
  92.         delete sb;
  93.         sb = old_sb;                                                                            // undo modifications
  94.         return 0;
  95.     }
  96.     
  97.     sb->str[new_length] = '\0';                                                            //    terminate string
  98.     old_sb->refs--;                                                                            // disconnect from old string body
  99.     return 1;
  100. }
  101.  
  102. //_________________________________________________________________________________
  103.  
  104. NString::NString (const unsigned long int l)
  105. {
  106.     const char *fname = "NString (const unsigned long int)";
  107.     
  108.     if ((sb = new strbody) == NULL)
  109.         OUT_OF_MEM(fname);
  110.     if (! AllocStrBuf(l))
  111.     {
  112.         delete sb;
  113.         sb = NULL;
  114.         OUT_OF_MEM(fname);
  115.     }
  116.     sb->str[l] = '\0';
  117.  
  118. #if (NSTRING_DEBUG & 2) != 0
  119.     printf("Construction of uninitialized NString of length %ld.\n", l);
  120. #endif
  121. }
  122.  
  123. //_________________________________________________________________________________
  124.  
  125. char *NString::AllocStrBuf (unsigned long int size)
  126. {
  127.     unsigned long int string_size = size;
  128.     
  129.     size++;                                                                        // size now denotes the wanted buffer-size
  130.  
  131. #if (NSTRING_DEBUG & 4) != 0
  132.     printf("-- AllocStrBuf: %ld bytes requested, ", size);
  133. #endif
  134.  
  135.     if (BufferSizeStep != 1)
  136.     {
  137.         unsigned long int modulo = size % BufferSizeStep;
  138.     
  139.         if (modulo != 0)
  140.             size = (size - modulo) + BufferSizeStep;                // adjust size to be a multiple of "BufferSizeStep"
  141.     }
  142.  
  143. #if (NSTRING_DEBUG & 4) != 0
  144.     printf("allocating %ld bytes.\n", size);
  145. #endif
  146.  
  147.     char *buffer = (char *)malloc(size);                            // attempt the allocation
  148.     
  149.     if (buffer != NULL)
  150.     {
  151.         sb->len = string_size;                                                // inscribe string length
  152.         sb->bufsize = size;                                                    // inscribe buffer size
  153.         sb->str = buffer;                                                    // inscribe buffer address
  154.     }
  155.     
  156.     return (buffer);
  157. }
  158.  
  159. //_________________________________________________________________________________
  160.  
  161. char *NString::ReallocStrBuf (unsigned long int size)
  162. {
  163.     unsigned long int new_bufsize = size + 1;                                    // the wanted buffer-size
  164.  
  165. #if (NSTRING_DEBUG & 4) != 0
  166.     printf("-- ReallocStrBuf: wanted -> %ld bytes / buffer -> %ld bytes, ", new_bufsize, sb->bufsize);
  167. #endif
  168.  
  169.     if (BufferSizeStep != 1)
  170.     {
  171.         unsigned long int modulo, old_bufsize;
  172.         
  173.         modulo = new_bufsize % BufferSizeStep;
  174.         if (modulo != 0)                                                                    // adjust size to be a multiple of "BufferSizeStep"
  175.             new_bufsize = (new_bufsize - modulo) + BufferSizeStep;
  176.             
  177.         modulo = sb->bufsize % BufferSizeStep;
  178.         if (modulo != 0)                                                                    // align old buffer size if necessary
  179.             old_bufsize = (sb->bufsize - modulo) + BufferSizeStep;
  180.         else
  181.             old_bufsize = sb->bufsize;
  182.         
  183.         if ((new_bufsize + BufferSizeStep == old_bufsize)                // deallocation of BufferSizeStep bytes asked ...
  184.             && (size >= (new_bufsize - DeallocationMargin)))            // ... but wanted size is too near new_bufsize
  185.         {
  186.         
  187.         #if (NSTRING_DEBUG & 4) != 0
  188.             printf("deallocation margin not reached.\n");
  189.         #endif
  190.         
  191.             return (sb->str);
  192.         }
  193.     }
  194.  
  195.     if (new_bufsize == sb->bufsize)                                                // Is a buffer size change needed ?
  196.     {
  197.     
  198.     #if (NSTRING_DEBUG & 4) != 0
  199.         printf("no change.\n");
  200.     #endif
  201.     
  202.         return (sb->str);
  203.     }
  204.  
  205. #if (NSTRING_DEBUG & 4) != 0
  206.     printf("reallocating %ld bytes.\n", new_bufsize);
  207. #endif
  208.  
  209.     char *buffer = (char *)realloc(sb->str, new_bufsize);                // attempt reallocation
  210.     
  211.     if (buffer != NULL)
  212.     {
  213.         sb->bufsize = new_bufsize;                                                    // inscribe new buffer size
  214.         sb->str = buffer;                                                                // inscribe new buffer address
  215.     }
  216.     
  217.     return (buffer);
  218. }
  219.