WvStreams
wvwordwrap.cc
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * A very simple word wrapping encoder.
00006  */
00007 #include "wvwordwrap.h"
00008 
00009 WvWordWrapEncoder::WvWordWrapEncoder(int _maxwidth) :
00010     maxwidth(_maxwidth)
00011 {
00012     line = new char[maxwidth];
00013     _reset();
00014 }
00015 
00016 
00017 WvWordWrapEncoder::~WvWordWrapEncoder()
00018 {
00019     deletev line;
00020 }
00021 
00022 
00023 bool WvWordWrapEncoder::_reset()
00024 {
00025     width = 0;
00026     curindex = wordindex = 0;
00027     inword = false;
00028     return true;
00029 }
00030 
00031 
00032 bool WvWordWrapEncoder::_encode(WvBuf &inbuf, WvBuf &outbuf,
00033     bool flush)
00034 {
00035     while (inbuf.used() != 0)
00036     {
00037         int ch = inbuf.getch();
00038         switch (ch)
00039         {
00040             case '\n':
00041                 if (! inword)
00042                     curindex = 0;
00043                 flushline(outbuf);
00044                 width = 0;
00045                 outbuf.putch('\n');
00046                 break;
00047             
00048             case ' ':
00049                 if (inword)
00050                     flushline(outbuf);
00051                 width += 1;
00052                 if (width <= maxwidth)
00053                     line[curindex++] = ch;
00054                 break;
00055             
00056             case '\t':
00057                 if (inword)
00058                     flushline(outbuf);
00059                 width = (width + 8) & ~7;
00060                 if (width <= maxwidth)
00061                     line[curindex++] = ch;
00062                 break;
00063 
00064             default:
00065                 if (width >= maxwidth)
00066                 {
00067                     if (! inword)
00068                     {
00069                         // discard trailing whitespace
00070                         curindex = wordindex = 0;
00071                         width = 0;
00072                     }
00073                     else if (wordindex == 0)
00074                     {
00075                         // insert hard line break
00076                         flushline(outbuf);
00077                         width = 0;
00078                     }
00079                     else
00080                     {
00081                         // insert soft line break
00082                         curindex -= wordindex;
00083                         memmove(line, line + wordindex, curindex);
00084                         wordindex = 0;
00085                         width = curindex;
00086                     }
00087                     outbuf.putch('\n');
00088                 }
00089                 if (! inword)
00090                 {
00091                     inword = true;
00092                     wordindex = curindex;
00093                 }
00094                 width += 1;
00095                 line[curindex++] = ch;
00096                 break;
00097                     
00098         }
00099     }
00100     if (flush)
00101         flushline(outbuf);
00102     return true;
00103 }
00104 
00105 
00106 void WvWordWrapEncoder::flushline(WvBuf &outbuf)
00107 {
00108     outbuf.put(line, curindex);
00109     curindex = wordindex = 0;
00110     inword = false;
00111 }