home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
word2x0a.zip
/
source
/
tblock.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-21
|
4KB
|
236 lines
/* $Id: tblock.cc,v 1.3 1997/03/21 20:34:11 dps Exp $ */
/* Dynamically growinf text block */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include "tblock.h"
const struct tblock::block tblock::dummy_init={0,0,NULL,NULL};
tblock::~tblock(void)
{
struct block *blk, *nblk;
blk=dummy_block.next;
while (blk!=NULL)
{
nblk=blk->next;
free(blk->text);
free(blk);
blk=nblk;
}
}
void tblock::zero(void)
{
struct block *blk, *nblk;
blk=dummy_block.next;
while (blk!=NULL)
{
nblk=blk->next;
free(blk->text);
free(blk);
blk=nblk;
}
dummy_block=dummy_init;
head=&dummy_block;
}
int tblock::add(char c)
{
struct block *blk, *nb;
blk=head;
if (blk->limit==blk->pos)
{
if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
return 0;
if ((nb->text=(char *) malloc(block_size))==NULL)
{
free(nb);
return 0;
}
nb->limit=1024;
nb->pos=0;
nb->next=NULL;
head->next=nb;
head=nb;
}
head->text[(head->pos)++]=c;
return 1;
}
int tblock::add(const char *s, int len)
{
struct block *nb;
const char *t;
int size;
if (*s=='\0')
return 1;
t=s;
while (len>0)
{
if (head->limit==head->pos)
{
if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
return 0;
if ((nb->text=(char *) malloc(block_size))==NULL)
{
free(nb);
return 0;
}
nb->limit=block_size;
nb->pos=0;
nb->next=NULL;
head->next=nb;
head=nb;
}
size=head->limit-head->pos;
if (size>len)
size=len;
memcpy(head->text+head->pos, t, size);
head->pos+=size;
len-=size;
t+=size;
}
return 1;
}
const char *tblock::collect(void) const
{
struct block *blk;
char *s,*t;
size_t size;
size=0;
blk=dummy_block.next;
while (blk!=NULL)
{
size+=blk->pos;
blk=blk->next;
}
if ((t=(char *) malloc(size+1))==NULL)
{
cerr<<"tblock::collect malloc failure\n";
return NULL;
}
s=t; blk=dummy_block.next;
while (blk!=NULL)
{
memcpy(s, blk->text, blk->pos);
s+=blk->pos;
blk=blk->next;
}
*s='\0';
return t;
}
tblock &tblock::operator=(const tblock &arg)
{
struct block *nb,*blk;
const char *s;
blk=dummy_block.next;
while (blk!=NULL)
{
nb=blk->next;
free(blk->text);
free(blk);
blk=nb;
}
if ((s=arg.collect())==NULL)
{
cerr<<"tblock:operator= fatal malloc failure\n";
exit(2);
}
if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
{
cerr<<"tblock:operator= fatal malloc failure\n";
exit(2);
}
nb->limit=strlen(s)+1; // Limit includes '\0'
nb->pos=strlen(s); // Do include '\0' in used characters
nb->text=(char *) s;
nb->next=NULL;
dummy_block.next=nb;
head=nb;
return *this;
}
tblock::tblock(const tblock &cpy)
{
struct block *nb;
const char *s;
if ((s=cpy.collect())==NULL)
{
cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
exit(2);
}
if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
{
cerr<<"tblock::tblock(const tblock &) fatal malloc failure\n";
exit(2);
}
nb->limit=strlen(s)+1; // Inlcude '\0' in limit
nb->pos=strlen(s); // DO not include '\0' in used
nb->text=(char *) s;
nb->next=NULL;
dummy_block.next=nb;
dummy_block.pos=0;
dummy_block.limit=0;
dummy_block.text=NULL;
head=nb;
}
tblock::operator const char *()
{
struct block *nb;
const char *s;
if (dummy_block.next==head)
{
*(head->text+head->pos)='\0';
return ((const char *) (head->text));
}
if ((s=this->collect())==NULL)
{
cerr<<"tblock::const char * fatal malloc failure\n";
exit(2);
}
if ((nb=(struct block *) malloc(sizeof(struct block)))==NULL)
{
cerr<<"tblock::const char * fatal malloc failure\n";
exit(2);
}
nb->limit=strlen(s)+1; // Inlcude '\0' in limit
nb->pos=strlen(s); // DO not include '\0' in used
nb->text=(char *) s;
nb->next=NULL;
this->zero(); // Wipe current data
dummy_block.next=nb;
dummy_block.pos=0;
dummy_block.limit=0;
dummy_block.text=NULL;
head=nb;
return s;
}