Logo Search packages:      
Sourcecode: ncmpcpp version File versions

strbuffer.h

/***************************************************************************
 *   Copyright (C) 2008-2009 by Andrzej Rybczak                            *
 *   electricityispower@gmail.com                                          *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.              *
 ***************************************************************************/

#ifndef _STRBUFFER_H
#define _STRBUFFER_H

#include "window.h"

#include <sstream>
#include <list>

namespace NCurses
{
      template <typename C> class basic_buffer
      {
            struct FormatPos
            {
                  size_t Position;
                  short Value;
                  
                  bool operator<(const FormatPos &f)
                  {
                        return Position < f.Position;
                  }
            };
            
            std::basic_ostringstream<C> itsString;
            std::list<FormatPos> itsFormat;
            std::basic_string<C> *itsTempString;
            
            public:
                  basic_buffer() : itsTempString(0) { }
                  basic_buffer(const basic_buffer &b);
                  
                  std::basic_string<C> Str() const;
                  void SetFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each = 1);
                  void SetTemp(std::basic_string<C> *);
                  void Clear();
                  
                  template <typename T> basic_buffer<C> &operator<<(const T &t)
                  {
                        itsString << t;
                        return *this;
                  }
                  
                  basic_buffer<C> &operator<<(std::ostream &(*os)(std::ostream &));
                  basic_buffer<C> &operator<<(const Color &color);
                  basic_buffer<C> &operator<<(const Format &f);
                  basic_buffer<C> &operator<<(const basic_buffer<C> &buf);
                  
                  friend Window &operator<< <>(Window &, const basic_buffer<C> &);
      };
      
      typedef basic_buffer<char> Buffer;
      typedef basic_buffer<wchar_t> WBuffer;
}

template <typename C> NCurses::basic_buffer<C>::basic_buffer(const basic_buffer &b) : itsFormat(b.itsFormat),
                                                            itsTempString(b.itsTempString)
{
      itsString << b.itsString.str();
}

template <typename C> std::basic_string<C> NCurses::basic_buffer<C>::Str() const
{
      return itsString.str();
}

template <typename C> void NCurses::basic_buffer<C>::SetFormatting(short vb, const std::basic_string<C> &s, short ve, bool for_each)
{
      std::basic_string<C> base = itsString.str();
      FormatPos fp;
      
      for (size_t i = base.find(s); i != std::basic_string<C>::npos; i = base.find(s))
      {
            base[i] = 0;
            fp.Value = vb;
            fp.Position = i;
            itsFormat.push_back(fp);
            fp.Value = ve;
            fp.Position = i+s.length();
            itsFormat.push_back(fp);
            if (!for_each)
                  break;
      }
}

template <typename C> void NCurses::basic_buffer<C>::SetTemp(std::basic_string<C> *tmp)
{
      itsTempString = tmp;
}

template <typename C> void NCurses::basic_buffer<C>::Clear()
{
      itsString.str(std::basic_string<C>());
      itsFormat.clear();
}

template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(std::ostream &(*os)(std::ostream&))
{
      itsString << os;
      return *this;
}

template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(const Color &color)
{
      FormatPos f;
      f.Position = itsString.str().length();
      f.Value = color;
      itsFormat.push_back(f);
      return *this;
}

template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(const Format &f)
{
      return operator<<(Color(f));
}

template <typename C> NCurses::basic_buffer<C> &NCurses::basic_buffer<C>::operator<<(const NCurses::basic_buffer<C> &buf)
{
      size_t len = itsString.str().length();
      itsString << buf.itsString.str();
      std::list<FormatPos> tmp = buf.itsFormat;
      if (len)
            for (typename std::list<typename NCurses::basic_buffer<C>::FormatPos>::iterator it = tmp.begin(); it != tmp.end(); it++)
                  it->Position += len;
      itsFormat.merge(tmp);
      return *this;
}

template <typename C> NCurses::Window &operator<<(NCurses::Window &w, const NCurses::basic_buffer<C> &buf)
{
      const std::basic_string<C> &s = buf.itsTempString ? *buf.itsTempString : buf.itsString.str();
      if (buf.itsFormat.empty())
      {
            w << s;
      }
      else
      {
            std::basic_string<C> tmp;
            typename std::list<typename NCurses::basic_buffer<C>::FormatPos>::const_iterator b = buf.itsFormat.begin();
            typename std::list<typename NCurses::basic_buffer<C>::FormatPos>::const_iterator e = buf.itsFormat.end();
            for (size_t i = 0; i < s.length() || b != e; i++)
            {
                  while (b != e && i == b->Position)
                  {
                        if (!tmp.empty())
                        {
                              w << tmp;
                              tmp.clear();
                        }
                        if (b->Value < NCurses::fmtNone)
                              w << NCurses::Color(b->Value);
                        else
                              w << NCurses::Format(b->Value);
                        b++;
                  }
                  if (i < s.length())
                        tmp += s[i];
            }
            if (!tmp.empty())
                  w << tmp;
      }
      return w;
}

#endif


Generated by  Doxygen 1.6.0   Back to index