home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / word2x0a.zip / source / tblock.cc < prev    next >
C/C++ Source or Header  |  1997-03-21  |  4KB  |  236 lines

  1. /* $Id: tblock.cc,v 1.3 1997/03/21 20:34:11 dps Exp $ */
  2. /* Dynamically growinf text block */
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <iostream.h>
  8. #include "tblock.h"
  9.  
  10. const struct tblock::block tblock::dummy_init={0,0,NULL,NULL};
  11.  
  12. tblock::~tblock(void)
  13. {
  14.     struct block *blk, *nblk;
  15.     blk=dummy_block.next;
  16.     while (blk!=NULL)
  17.     {
  18.     nblk=blk->next;
  19.     free(blk->text);
  20.     free(blk);
  21.     blk=nblk;
  22.     }
  23. }
  24.  
  25. void tblock::zero(void)
  26. {        
  27.     struct block *blk, *nblk;
  28.     blk=dummy_block.next;
  29.     while (blk!=NULL)
  30.     {
  31.     nblk=blk->next;
  32.     free(blk->text);
  33.     free(blk);
  34.     blk=nblk;
  35.     }
  36.     dummy_block=dummy_init;
  37.     head=&dummy_block;
  38. }
  39.  
  40. int tblock::add(char c)
  41. {
  42.     struct block *blk, *nb;
  43.     blk=head;
  44.     if (blk->limit==blk->pos)
  45.     {
  46.     if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
  47.         return 0;
  48.     if ((nb->text=(char *) malloc(block_size))==NULL)
  49.     {
  50.         free(nb);
  51.         return 0;
  52.     }
  53.     nb->limit=1024;
  54.     nb->pos=0;
  55.     nb->next=NULL;
  56.     head->next=nb;
  57.     head=nb;
  58.     }
  59.     head->text[(head->pos)++]=c;
  60.     return 1;
  61. }
  62.  
  63. int tblock::add(const char *s, int len)
  64. {
  65.     struct block *nb;
  66.     const char *t;
  67.     int size;
  68.  
  69.     if (*s=='\0')
  70.     return 1;
  71.  
  72.     t=s;
  73.  
  74.     while (len>0)
  75.     {
  76.     if (head->limit==head->pos)
  77.     {
  78.         if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
  79.         return 0;
  80.         if ((nb->text=(char *) malloc(block_size))==NULL)
  81.         {
  82.         free(nb);
  83.         return 0;
  84.         }
  85.         nb->limit=block_size;
  86.         nb->pos=0;
  87.         nb->next=NULL;
  88.         head->next=nb;
  89.         head=nb;
  90.     }
  91.     size=head->limit-head->pos;
  92.     if (size>len)
  93.         size=len;
  94.     memcpy(head->text+head->pos, t, size);
  95.     head->pos+=size;
  96.     len-=size;
  97.     t+=size;
  98.     }
  99.     return 1;
  100. }
  101.  
  102. const char *tblock::collect(void) const
  103. {
  104.     struct block *blk;
  105.     char *s,*t;
  106.     size_t size;
  107.  
  108.     size=0;
  109.     blk=dummy_block.next;
  110.     while (blk!=NULL)
  111.     {
  112.     size+=blk->pos;
  113.     blk=blk->next;
  114.     }
  115.     
  116.     if ((t=(char *) malloc(size+1))==NULL)
  117.     {
  118.         cerr<<"tblock::collect malloc failure\n";
  119.     return NULL;
  120.     }
  121.  
  122.     s=t; blk=dummy_block.next;
  123.     while (blk!=NULL)
  124.     {
  125.     memcpy(s, blk->text, blk->pos);
  126.     s+=blk->pos;
  127.     blk=blk->next;
  128.     }
  129.     *s='\0';
  130.     return t;
  131. }
  132.  
  133.  
  134. tblock &tblock::operator=(const tblock &arg)
  135. {
  136.     struct block *nb,*blk;
  137.     const char *s;
  138.     
  139.     blk=dummy_block.next;
  140.     while (blk!=NULL)
  141.     {
  142.     nb=blk->next;
  143.     free(blk->text);
  144.     free(blk);
  145.     blk=nb;
  146.     }
  147.  
  148.     if ((s=arg.collect())==NULL)
  149.     {
  150.     cerr<<"tblock:operator= fatal malloc failure\n";
  151.     exit(2);
  152.     }
  153.  
  154.     if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
  155.     {
  156.     cerr<<"tblock:operator= fatal malloc failure\n";
  157.     exit(2);
  158.     }
  159.  
  160.     nb->limit=strlen(s)+1;    // Limit includes '\0'
  161.     nb->pos=strlen(s);        // Do include '\0' in used characters
  162.     nb->text=(char *) s;
  163.     nb->next=NULL;
  164.     dummy_block.next=nb;
  165.     head=nb;
  166.  
  167.     return *this;
  168. }
  169.  
  170. tblock::tblock(const tblock &cpy)
  171. {
  172.     struct block *nb;
  173.     const char *s;
  174.     
  175.     if ((s=cpy.collect())==NULL)
  176.     {
  177.     cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
  178.     exit(2);
  179.     }
  180.  
  181.     if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
  182.     {
  183.     cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
  184.     exit(2);
  185.     }
  186.  
  187.     nb->limit=strlen(s)+1;    // Inlcude '\0' in limit
  188.     nb->pos=strlen(s);        // DO not include '\0' in used
  189.     nb->text=(char *) s;
  190.     nb->next=NULL;
  191.     dummy_block.next=nb;
  192.     dummy_block.pos=0;
  193.     dummy_block.limit=0;
  194.     dummy_block.text=NULL;
  195.     head=nb;
  196. }
  197.  
  198.  
  199. tblock::operator const char *()
  200. {
  201.     struct block *nb;
  202.     const char *s;
  203.     
  204.  
  205.     if (dummy_block.next==head)
  206.     {
  207.     *(head->text+head->pos)='\0';
  208.     return ((const char *) (head->text));
  209.     }
  210.  
  211.     if ((s=this->collect())==NULL)
  212.     {
  213.     cerr<<"tblock::const char * fatal malloc failure\n";
  214.     exit(2);
  215.     }
  216.  
  217.     if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
  218.     {
  219.     cerr<<"tblock::const char * fatal malloc failure\n";
  220.     exit(2);
  221.     }
  222.  
  223.     nb->limit=strlen(s)+1;    // Inlcude '\0' in limit
  224.     nb->pos=strlen(s);        // DO not include '\0' in used
  225.     nb->text=(char *) s;
  226.     nb->next=NULL;
  227.     this->zero();        // Wipe current data
  228.     dummy_block.next=nb;
  229.     dummy_block.pos=0;
  230.     dummy_block.limit=0;
  231.     dummy_block.text=NULL;
  232.     head=nb;
  233.  
  234.     return s;
  235. }
  236.