Logo Search packages:      
Sourcecode: vdr-plugin-burn version File versions  Download package

common.c

/*
 * See the files COPYING and README for copyright information and how to reach
 * the author.
 *
 *  $Id: common.c,v 1.28 2006/09/16 18:33:36 lordjaxom Exp $
 */

#include "burn.h"
#include "common.h"
#include "iconvwrapper.h"
#include "setup.h"
#include "proctools/logger.h"
#include "proctools/format.h"
#include "boost/bind.hpp"
#include <sstream>
#include <string>
#include <iterator>
#include <algorithm>
#include <iomanip>
#include <ctime>
#include <vdr/recording.h>
#include <vdr/config.h>
#include <vdr/i18n.h>
#include <sys/types.h>
#include <glob.h>

namespace vdr_burn
{

      using namespace std;
      using proctools::logger;
      using proctools::format;
      using boost::bind;

      // --- disktype -----------------------------------------------------------

      const char* disktype_strings[disktype_count] =
                  { "DVD with menus", "DVD without menus", "Archive disk" };

      // --- storemode ----------------------------------------------------------

      const char* storemode_strings[storemode_count] =
                  { "Create ISO only", "Write to Disc", "Create ISO and write" };

      // --- chaptersmode -------------------------------------------------------

      const char* chaptersmode_strings[chaptersmode_count] =
                  { "No chapters", "Use editing marks", "Every 5 minutes", "Every 10 minutes",
                    "Every 15 minutes", "Every 30 minutes", "Every hour" };

      const int chaptersmode_intervals[chaptersmode_count] =
                  { -1, -1, 5, 10, 15, 30, 60 };

      // --- disksize -----------------------------------------------------------

      const char* disksize_strings[disksize_count] =
                  { "Single Layer", "Double Layer", "CD-R", "Custom" };

      const int disksize_values[disksize_count] =
                  { 4472, 7944, 690, -1 };

      // --- demuxtype ----------------------------------------------------------

      const char* demuxtype_strings[demuxtype_count] =
                  { "VDRSync", "ProjectX" };

      // --- requanttype --------------------------------------------------------

      const char* requanttype_strings[requanttype_count] =
                  { "M2VRequantizer", "Transcode" };

const char *TitleChars = "abcdefghijklmnopqrstuvwxyz"
                                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                     "0123456789"
                                     ":- ";

int ScanPageCount(const std::string& Path)
{
      cString path = AddDirectory(Path.c_str(), "menu-bg-*.png");
      glob_t globbuf;
      int res;

      if ((res = glob(path, 0, NULL, &globbuf)) != 0) {
            const char *error = "Unknown error";

            switch (res) {
                  case GLOB_NOSPACE: error = "Out of memory"; break;
                  case GLOB_ABORTED: error = "I/O error"; break;
                  case GLOB_NOMATCH: error = "File not found"; break;
            }

            esyslog("ERROR[burn]: Error while scanning %s: %s", *path, error);
            return -1;
      }

      res = globbuf.gl_pathc;
      globfree(&globbuf);
      return res;
}

std::string progress_bar(double current, double total, int length)
{
      if (length < 2)
            return "";

      if (current > total)
            current = total;

      int l = static_cast<int>(current * (length - 2) / total);
      ostringstream builder;

      builder << '[';
      fill_n(ostream_iterator<char>(builder), l, '|');
      fill_n(ostream_iterator<char>(builder), length - 2 - l, ' ');
      builder << ']';
      return builder.str();
}

      void trim_left( std::string& text_, const char* characters_ )
      {
            std::string::size_type pos = 0;
            do {
                  while ( strchr( characters_, text_[ pos ] ) != NULL )
                        text_.erase( 0, 1 );
                  if ( ( pos = text_.find( '~' ) ) != std::string::npos )
                        ++pos;
            } while ( pos != std::string::npos );
      }

string get_recording_datetime(const cRecording* recording_, char delimiter)
{
      string title = recording_->Title('\t', false, -1
#ifdef LIEMIKUUTIO // hatred... HATRED!!!
                                                       , true
#endif
                                                      );

      string::iterator it = title.begin();
      for (int i = 0; i < 2 && it != title.end(); ++i)
            it = find(it + 1, title.end(), '\t');

      title.erase(it, title.end());
      if (title[title.length() - 1] == ' ')
            title.erase(title.length() - 1);
      if (delimiter != '\t')
            replace(title.begin(), title.end(), '\t', delimiter);
      return title;
}

string get_recording_title(const cRecording* recording_, int level)
{
      stringstream result;
      string name( recording_->Name() );

      if (level == recording_->HierarchyLevels()) {
            string::size_type pos;
            for ( int l = 0; l < level && ((pos = name.find('~')) != string::npos); ++l )
                  name.erase(0, pos + 1);

            result << get_recording_datetime(recording_);

            ostringstream archivePath;
            archivePath << recording_->FileName() << "/dvd.vdr";
            if (access(archivePath.str().c_str(), F_OK) == 0)
                  result << 'A';
            else
                  result << ' ';

            result << (recording_->IsNew() ? '*' : ' ') << '\t' << name;
            return result.str();
      }

      string::size_type lastOffset = 0;
      string::size_type offset;
      while ((offset = name.find('~', lastOffset)) != string::npos) {
            if (level-- == 0)
                  break;
            lastOffset = offset + 1;
      }
      result << "\t\t" << name.substr(lastOffset, offset - lastOffset);
      return result.str();
}

std::string get_recording_description(const cRecording* recording_)
{
#if VDRVERSNUM < 10300
      if (recording_->Summary() != 0)
            return recording_->Summary();
#else
      if (recording_->Info()->Description() != 0)
            return recording_->Info()->Description();
      else if (recording_->Info()->ShortText() != 0)
            return recording_->Info()->ShortText();
#endif

      return "";
}

string string_replace( const string& text, char from, char to )
{
      string result( text );
      replace( result.begin(), result.end(), from, to );
      return result;
}

bool elapsed_since(time_t& timestamp, time_t difference)
{
      time_t now = time(NULL);
      if (timestamp + difference <= now) {
            timestamp = now;
            return true;
      }
      return false;
}

string int_to_string(int value, int base, bool prefix)
{
      stringstream conv;
      if (prefix) {
            switch (base) {
            case 2: conv << "0b"; break;
            case 8: conv << "0"; break;
            case 16: conv << "0x"; break;
            }
      }
      conv << setbase(base) << value;

      string result;
      conv >> result;
      return result;
}

string get_recording_name(const cRecording* recording)
{
      string title( recording->Title() );
      string::size_type pos( title.rfind('~') );
      if (pos != string::npos)
            title.erase( pos );
      return title;
}

      inline char clean_path_character( char ch )
      {
            //! Table with clean characters for path names.
            static const char cleanPathCharacters[] =
            {
            //      0 ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,  A ,  B ,  C ,  D ,  E ,  F ,
                   '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_',    //00
                   '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_',    //10
                   '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', '_', 0x2D,0x2E,0x2F,   //20
                   0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,'_', '_', '_', '_', '_', '_',    //30
                   '_', 0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,   //40
                   0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,'_', '_', '_', '_', '_',    //50
                   '_', 0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,   //60
                   0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,'_', '_', '_', '_', '_'     //70
                   // everything above 127 (for signed char, below zero) is replaced with '_'
            };

            if ( static_cast<signed char>( ch ) <= 0 ) // since not all implementations consider char _arrays_ to be signed, make sure
                  return '_';
            return cleanPathCharacters[ int( ch ) ];
      }

      ///////////////////////////////////////////////////////////////////////////////
      //! Clean path name, so it just contains save characters.
      /*! Use this function to ensure functionality in various charset environments.
       All "bad" characters are replaced with '_'.
       CAUTION: for UTF16, we need to adjust the table or add a upper limit.
       \param text Path name to be cleaned up
       \return Cleaned path named
      */
      string clean_path_name( const string& text )
      {
            string result;
            result.resize( text.length() );
            // I like the functional approach ;)
            transform( text.begin(), text.end(), result.begin(), clean_path_character );
            return result;
      }

      string convert_to_utf8( const string& text )
      {
            if ( plugin::get_character_encoding() == "utf-8" )
                  return text;

            iconvwrapper::iconv iso_to_utf( plugin::get_character_encoding(), "utf-8" );
            string result = iso_to_utf( text );
            if ( !iso_to_utf ) {
                  logger::error( "couldn't convert characters from iso-8859-15 to utf-8" );
                  throw user_exception( tr("Couldn't convert character sets!") );
            }
            return result;
      }

}

Generated by  Doxygen 1.6.0   Back to index