// ============================================================================
//  $Id: TUtilities.cc,v 1.6 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TUtilities.cc,v $
//  Revision 1.6  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.5  2004/01/29 04:25:07  goiwai
//  いくつかの関数で微妙に仕様変更しました.
//  あとは,substituteをconst sourceのconstをとろうかどうしようか迷ってます.
//
//  Revision 1.4  2003/11/26 23:42:31  goiwai
//  GetBaseName(),GetDirectoryName(),で使ってた std::string::copy にはどう
//  もバグ入りのようですので, strncpy でごまかしました.
//
//  Revision 1.3  2003/10/10 11:50:15  goiwai
//  なんかコンパイルにこけたりするんでバッファ長を短くしました.なんでだろ？
//
//  Revision 1.2  2003/10/10 09:37:22  goiwai
//  バッファサイズを変更しました.
//
//  Revision 1.1  2003/10/06 16:34:36  goiwai
//  データの変換や正規表現等,頻繁に使用される関数群のためのラッパークラス
//  です.あたかもCのライブラリ関数の如く使用できます.
//
// ============================================================================
#include "TUtilities.hh"
#include "TRegularExpression.hh"

static const Tsize_t _buflen = 127;

Tstring TUtilities::ConvertIntegerToString( Tint i, Tint digits )
{
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( i >= 0 ) {
    os << setfill( '0' ) << setiosflags( Tios::right ) << setw( digits );
    os << i << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << i << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

Tstring TUtilities::ConvertLongToString( Tlong l, Tint digits )
{
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( l >= 0 ) {
    os << setfill( '0' ) << setiosflags( Tios::right ) << setw( digits );
    os << l << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << l << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

Tstring TUtilities::ConvertUnsignedLongToString( TUlong ul, Tint digits )
{
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  if ( ul >= 0 ) {
    os << setfill( '0' ) << setiosflags( Tios::right ) << setw( digits );
    os << ul << Tends;
    Tstring s = os.str();
    return s;
  } else {
    os << ul << Tends;
    Tstring s = os.str();
    Tint nzero = digits - s.size();
    if ( nzero > 0 ) {
      s.insert( 1, nzero, '0' );
    }
    return s;
  }
}

Tstring TUtilities::ConvertDoubleToString( Tdouble d, Tint precision )
{
  static Tchar buf[ _buflen + 1 ];
  Tostrstream os( buf, _buflen );

  os << setprecision( precision ) << d << Tends;
  Tstring s = os.str();
  return s;
}

Tstring TUtilities::ConvertFloatToString( Tfloat f, Tint precision )
{
  return ConvertDoubleToString( (Tdouble)f, precision );
}

Tbool TUtilities::FileExist( const Tstring& filename, Tint mode )
{
  if ( access( filename.c_str(), mode ) == 0 ) {
    return Ttrue;
  } else {
    return Tfalse;
  }
}

Tint TUtilities::ConvertStringToInteger( const Tstring& nptr, Tchar** endptr, Tint base )
{
  return (Tint)strtol( nptr.c_str(), endptr, base );
}

Tdouble TUtilities::ConvertStringToDouble( const Tstring& nptr, Tchar** endptr )
{
  return strtod( nptr.c_str(), endptr );
}

Tvoid TUtilities::ShowBitPattern( Tint bit )
{
  Tint nbit = Tsizeof( bit ) * 8;
  for ( Tint i = nbit; i > 0; i -- ) {
    Tcout << ( ( bit >> i - 1 ) & 0x01 );
  }
  Tcout << Tendl;
  return;
}

TstringList TUtilities::Split( const Tstring& source, const Tstring& pattern, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.Split( source, pos );
}

TintList TUtilities::Index( const Tstring& source, const Tstring& pattern, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.Indexes( source, pos );
}

TintList TUtilities::Size( const Tstring& source, const Tstring& pattern, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.Sizes( source, pos );
}

Tstring TUtilities::Substitute( const Tstring& source, const Tstring& pattern, const Tstring& substr, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.Substitute( source, substr, pos );
}

Tstring TUtilities::SubstituteAll( const Tstring& source, const Tstring& pattern, const Tstring& substr, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.SubstituteAll( source, substr, pos );
}

Tbool TUtilities::IsMatch( const Tstring& source, const Tstring& pattern, Tbool igcase, Tint pos )
{
  TRegularExpression regex( pattern );
  if ( igcase == Ttrue ) {
    regex.IgnoreCase();
  }
  return regex.IsMatch( source, pos );
}

// Tstring TUtilities::GetBaseName( const Tstring& path )
// {
//   Tstring copy = path;
//   const Tchar* cpch = copy.c_str();
//   // const Tchar* から Tchar* への変換
//   Tchar* pch = const_cast<Tchar*> (cpch);
//   Tstring base = basename( pch );
//   return base;
// }

Tstring TUtilities::GetBaseName( const Tstring& path )
{
  const Tsize_t len = path.size() + 1;
  Tchar* copy = new Tchar[ len ];
  //path.copy( copy, path.size() ); // std::string::copy has bugs.
  strncpy( copy, path.c_str(), len );
  Tchar* b = basename( copy );
  Tstring base( b );
  delete [] copy;
  return base;
}

// Tstring TUtilities::GetDirectoryName( const Tstring& path )
// {
//   Tstring copy = path;
//   const Tchar* cpch = copy.c_str();
//   // const Tchar* から Tchar* への変換
//   Tchar* pch = const_cast<Tchar*> (cpch);
//   Tstring dir = dirname( pch );
//   return dir;
// }

Tstring TUtilities::GetDirectoryName( const Tstring& path )
{
  const Tsize_t len = path.size() + 1;
  Tchar* copy = new Tchar[ len ];
  //path.copy( copy, path.size() ); // std::string::copy has bugs.
  strncpy( copy, path.c_str(), len );
  Tchar* d = dirname( copy );
  Tstring dir( d );
  delete [] copy;
  return dir;
}

Tstring TUtilities::GetSubMatch( Tint index, const Tstring& source, const Tstring& pattern, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.GetSubMatch( index, source, pos );
}

TstringList TUtilities::GetSubMatch( const Tstring& source, const Tstring& pattern, Tint pos )
{
  TRegularExpression regex( pattern );
  return regex.GetSubMatch( source, pos );
}

#ifdef __CLDAQ_ROOT_DLL
    ClassImp(TUtilities)
#endif
