diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ebb6ee3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +##### C++ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 5aa223a..d8ec3b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,7 +23,7 @@ - fixed combined H.264 streams read from Elementary Stream - BD Bitrate control improved a little bit -## tsMuxeR 2.6.4(b) +## tsMuxeR 2.6.4 - Add secondary video support - fixed mp4 files with MPEG-DASH - fixed SEI again @@ -31,19 +31,19 @@ - fixed font renderer (a little bit wrong text position) - several minor improvments and bug fixes -## tsMuxeR 2.5.7(b) +## tsMuxeR 2.5.7 - fixed bug with SEI messages for some movie - fixed problem with some movies where problem occured during processing several last video frames - several minor bug fixes -## tsMuxeR 2.5.5(b) +## tsMuxeR 2.5.5 - add HEVC video codec support - UI improvment: Save settings for General tab, Subtitles tab and last output folder - Fixed file duration detection for ssif and some m2ts files - Fixed bug if mux playlist and several sup files (it is a very olg bug, but it became much more often since 2.4.x) - Several minor bug fixes -## tsMuxeR 2.4.0(b) +## tsMuxeR 2.4.0 - Add secondary audio support for bluray muxing. Due to standart It is allowed only for DTS-Express and DD+ codecs. - Filter out H.264 filler packets - UI improvment: option for MPLS offset can be entered either as time or as 45Khz clock value @@ -55,7 +55,7 @@ - UI fix: if open MPLS, then close, track list is not cleared. It is broken in previous build only. - Subtitles renderer fixed (broken in previous build only after in/out effects) -## tsMuxeR 2.3.2(b) +## tsMuxeR 2.3.2 - Support PG subtitles inside MKV - Support MKV tracks with zlib compression - Support 3D MP4 and MOV files (combined AVC+MVC stream) @@ -66,7 +66,7 @@ - bug fixed: tsMuxeR can't create output directory for UNC path (for instance \\.\Volume{E5FB13D8-5096-11E3-B9C4-005056C00008}\folder1\test.ts) - bug fixed: message "file already exist" appeared if open several files from a folder with '(' in the name -## tsMuxeR 2.2.3(b) +## tsMuxeR 2.2.3 - Add support for DTS-HD elementary stream with extra DTSHD headers - Add support for mkv with 'Header Stripping' compression - Add 3D MKV support @@ -77,21 +77,21 @@ - Fixed file splitting option (it was disabled since v.1.11.x because of was not implemented for ISO and 3D-blurays) - Several minor bug fixes -## tsMuxeR 2.1.8(b) +## tsMuxeR 2.1.8 - Fixed join files problem with True-HD track - introduce MAC build -## tsMuxeR 2.1.6(b) +## tsMuxeR 2.1.6 - Add support for combined AVC+MVC streams - Output file size slightly reduced - Fixed bug if mux AVC+MVC tracks to m2ts file. Some 3d m2ts movies did not play on Samsung Smart TV - Fixed minor bug in a SSIF interleaving for some movies - introduce Linux build -## tsMuxeR 2.1.4(b) +## tsMuxeR 2.1.4 - Same problem fixed again. Sometimes tsMuxeR get access to file with wrong name during mpls processing. -## tsMuxeR 2.1.3(b) +## tsMuxeR 2.1.3 - Previous version introduce a new bug. Sometime tsMuxeR showed error message "file not found". Fixed. ## tsMuxeR 2.1.2(b); diff --git a/README.md b/README.md index 8796fb7..fc8fe19 100644 --- a/README.md +++ b/README.md @@ -43,16 +43,26 @@ or are worried that the code isn't being followed, please contact the owner of t ## Language -tsMuxer is written is C++. Specifically it was written for Windows on Visual C++ 2008. It can also be compiled for Linux and Mac. +tsMuxer is written in C++. It can be compiled for Windows, Linux and Mac. ## History -This project was created by Roman Vasilenko, with the last public release 20th January 2014. It was open sourced on 15th July 2019, to aid the future development. +This project was created by Roman Vasilenko, with the last public release 20th January 2014. It was open sourced on 23rd July 2019, to aid the future development. ## Installation All executable are created to be portable, so you can just save and extract the compressed package for your platform. +## Todo + +The following is a list of changes that will need to be made to the original source code and project in general: + +* swapping custom includes from libmediation to their standard library equivalents +* the code uses my_htonl, my_ntohll, etc - these can be swapped for the standard library versions +* the program currently only compiles 32-bit executables, even on 64-bit systems, a multi-architecture approach is needed +* consider making static executables for Linux, to make the program more portable +* create a multi-platform build pipeline, maybe using dockcross + ## Contributing We’re really happy to accept contributions from the community, that’s the main reason why we open-sourced it! There are many ways to contribute, even if you’re not a technical person. @@ -76,13 +86,56 @@ You can report issues directly on Github, that would be a really useful contribu ### Building -To build the project you will need a machine for your chosen platform. Then for Linux or Mac run: +To build the project you will need a machine for your chosen platform. In this example we will use Linux, specifically Ubuntu 19 64-bit. + +First we have to install the pre-requisites. On Ubuntu you can run the following to install all required packages: ``` +sudo apt-get install libfreetype6-dev \ +build-essential \ +flex \ +libelf-dev \ +libc6-dev \ +binutils-dev \ +libdwarf-dev \ +libc6-dev-i386 \ +g++-multilib \ +upx \ +qt4-qmake \ +libqt4-dev +``` + +Unfortunately on Ubuntu this isn't enough. We need to install libfreetype and it's dependencies as 32-bit libraries. You can download a compressed archive of these files [here](https://dropapk.com/6308nkz3zpej). + +Once you download the package you have to install it, the easiest thing is to extract the tar directly into the correct folder as root (I know, this needs to be improved!). Assuming you downloaded the tar to /home/me/Downloads: + +``` +cd /lib32 +sudo tar --strip-components=1 -xvf /home/me/Downloads/ubuntu-libfreetype-lib32.tar.gz lib32 +``` + +With all the dependencies set up we can now actually compile the code. + +Open the folder where the git repo is stored in a terminal and run the following: + +``` +# compile tsMuxer to ../bin +cd tsMuxer make -``` -On Windows you need to Build the Visual C++ project. +# generate the tsMuxerGUI makefile +cd .. +cd tsMuxerGUI +qmake + +# compile tsMuxerGUI to ../bin +make + +# UPX compress the executables, then create a release package as tsMuxeR.tar.gz from the install folder +cd .. +cd tsMuxer +make install +``` ## Financing diff --git a/libmediation/Makefile b/libmediation/Makefile new file mode 100644 index 0000000..b0af4d2 --- /dev/null +++ b/libmediation/Makefile @@ -0,0 +1,42 @@ +BUILD= + +ifeq ($(MAKECMDGOALS),debug) + BUILD= +endif +ifeq ($(MAKECMDGOALS),release) + BUILD=-Os +endif +#ifeq (!$(findstring $(BUILD),debug release)) +# $(error BUILD=$(BUILD) is unknown, must be BUILD=release or BUILD=debug) +#endif + +CC=gcc +DEFINES = -DLINUX -DLIBMEDIATION_API= -DDISABLE_LOG_SUPPORT -DDEBUG_NEW12=new -DNO_SYSTEM_EXCEPT +CFLAGS = -c -m32 +INCPATH = -I./ +LFLAGS = -m32 +LIBS = -lpthread +LDFLAGS = +TARGET = libmediationl.a + +SOURCES= fs/directory.cpp fs/osdep/file_unix.cpp system/osdep/condvar_linux.cpp system/osdep/mutex_linux.cpp \ +system/osdep/terminatablethread_linux.cpp types/types.cpp time/time.cpp + +OBJECTS=$(SOURCES:.cpp=.o) + +all: $(SOURCES) $(TARGET) +.PHONY : debug release +debug: all +release: all + +$(TARGET): $(OBJECTS) + ar cr $@ $(OBJECTS) + +.cpp.o: + $(CC) $(DEFINES) $(BUILD) $(LFLAGS) $(CFLAGS) $(INCPATH) $? $(LDFLAGS) -o $@ + +clean: + rm -f $(OBJECTS) + rm -f ./libmediation.so + rm -f ./libmediationl.a + \ No newline at end of file diff --git a/libmediation/Makefile.mac b/libmediation/Makefile.mac new file mode 100644 index 0000000..e800d9d --- /dev/null +++ b/libmediation/Makefile.mac @@ -0,0 +1,41 @@ +BUILD= + +ifeq ($(MAKECMDGOALS),debug) + BUILD= +endif +ifeq ($(MAKECMDGOALS),release) + BUILD=-Os +endif +#ifeq (!$(findstring $(BUILD),debug release)) +# $(error BUILD=$(BUILD) is unknown, must be BUILD=release or BUILD=debug) +#endif + +CC=gcc +DEFINES = -DMAC -DLIBMEDIATION_API= -DDISABLE_LOG_SUPPORT -DDEBUG_NEW12=new -DNO_SYSTEM_EXCEPT +CFLAGS = -c +INCPATH = -I./ +LFLAGS = +LIBS = -lpthread +LDFLAGS = +TARGET = libmediationl.a + +SOURCES= fs/directory.cpp fs/osdep/file_unix.cpp system/osdep/condvar_linux.cpp system/osdep/mutex_linux.cpp \ +system/osdep/terminatablethread_linux.cpp types/types.cpp time/time.cpp + +OBJECTS=$(SOURCES:.cpp=.o) + +all: $(SOURCES) $(TARGET) +.PHONY : debug release +debug: all +release: all + +$(TARGET): $(OBJECTS) + ar cr $@ $(OBJECTS) + +.cpp.o: + $(CC) $(DEFINES) $(BUILD) $(LFLAGS) $(CFLAGS) $(INCPATH) $? $(LDFLAGS) -o $@ + +clean: + rm -f $(OBJECTS) + rm -f ./libmediation.so + rm -f ./libmediationl.a diff --git a/libmediation/containers/safequeue.h b/libmediation/containers/safequeue.h new file mode 100644 index 0000000..0859357 --- /dev/null +++ b/libmediation/containers/safequeue.h @@ -0,0 +1,146 @@ + +#ifndef _SAFE_QUEUE_H +#define _SAFE_QUEUE_H + +#include + +#include +#include + + +template< typename T > +class SafeQueue +{ +public: + typedef typename std::queue::size_type size_type; + + SafeQueue( const size_type& maxSize ) + : + m_maxSize( maxSize ) + { + }; + + virtual ~SafeQueue() + { + }; + + bool empty() const + { + Mutex::ScopedLock lk(&m_mtx); + + return m_queue.empty(); + }; + + size_type size() const + { + Mutex::ScopedLock lk(&m_mtx); + + return m_queue.size(); + }; + + bool push(const T& val) + { + Mutex::ScopedLock lk(&m_mtx); + + if ( m_queue.size()>=m_maxSize ) + return false; + + m_queue.push(val); + return true; + } + + T pop() + { + Mutex::ScopedLock lk(&m_mtx); + + T val = m_queue.front(); + m_queue.pop(); + + return val; + } + +private: + mutable Mutex m_mtx; + std::queue m_queue; + const size_type m_maxSize; + + SafeQueue( const SafeQueue& ); + SafeQueue& operator= ( const SafeQueue& ); +}; + + +template< typename T > + +class SafeQueueWithNotification : public SafeQueue +{ +public: + SafeQueueWithNotification( + const uint32_t maxSize, + Mutex* const mtx, + ConditionVariable* const cond ) + : + SafeQueue( maxSize ), + m_mtx( mtx ), + m_cond( cond ) + { + }; + + bool push( const T& val ) + { + Mutex::ScopedLock lk( m_mtx ); + + if( !SafeQueue::push( val ) ) + return false; + + m_cond->notify_one(); + + return true; + } + +private: + Mutex* const m_mtx; + ConditionVariable* const m_cond; + + SafeQueueWithNotification( const SafeQueueWithNotification& ); + SafeQueueWithNotification& operator= ( const SafeQueueWithNotification& ); +}; + + +template< typename T > +class WaitableSafeQueue : public SafeQueueWithNotification +{ +public: + WaitableSafeQueue( const uint32_t maxSize ) + : + SafeQueueWithNotification( + maxSize, + &m_mtx, + &m_cond ) + { + }; + + virtual ~WaitableSafeQueue() {}; + + T pop() + { + Mutex::ScopedLock lk( &m_mtx ); + + while( SafeQueue::empty() ) + { + m_cond.wait(&lk); + } + + T val = SafeQueue::pop(); + + return val; + } + +private: + Mutex m_mtx; + ConditionVariable m_cond; + + WaitableSafeQueue( const WaitableSafeQueue& ); + WaitableSafeQueue& operator= ( const WaitableSafeQueue& ); +}; + +#endif //_SAFE_QUEUE_H diff --git a/libmediation/fs/directory.cpp b/libmediation/fs/directory.cpp new file mode 100644 index 0000000..aedab27 --- /dev/null +++ b/libmediation/fs/directory.cpp @@ -0,0 +1,293 @@ + +#include "directory.h" +#include +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include +#include +#include +#endif + + +using namespace std; + +#ifdef SOLARIS +typedef struct mydirent +{ + ino_t d_ino; /* "inode number" of entry */ + off_t d_off; /* offset of disk directory entry */ + unsigned short d_reclen; /* length of this record */ + char d_name[PATH_MAX]; /* name of file */ +} mydirent_t; +#endif + +char getDirSeparator() +{ +#ifdef WIN32 + return '\\'; +#else + return '/'; +#endif +} + +string extractFileDir( const string& fileName ) +{ + size_t index = fileName.find_last_of('/'); + if( index != string::npos ) + return fileName.substr( 0, index+1 ); +#ifdef WIN32 + index = fileName.find_last_of('\\'); + if( index != string::npos ) + return fileName.substr( 0, index+1 ); +#endif + + return ""; +} + +bool fileExists( const string& fileName ) +{ + bool fileExists = false; +#ifdef WIN32 + struct _stat64 buf; + fileExists = _stat64( fileName.c_str(), &buf ) == 0; +#else // LINUX + struct stat64 buf; + fileExists = stat64( fileName.c_str(), &buf ) == 0; +#endif + + return fileExists; +} + +uint64_t getFileSize ( const std::string& fileName ) +{ + bool res = false; +#ifdef WIN32 + struct _stat64 fileStat; + res = _stat64( fileName.c_str(), &fileStat ) == 0; +#else // LINUX + struct stat64 fileStat; + res = stat64( fileName.c_str(), &fileStat ) == 0; +#endif + + return res ? ( uint64_t )fileStat.st_size : 0; +} + +bool createDir( + const std::string& dirName, + bool createParentDirs ) +{ + if( dirName.empty() ) + return false; + + if( createParentDirs ) + { + for( string::size_type + separatorPos = dirName.find_first_not_of( getDirSeparator() ), dirEnd = string::npos; + separatorPos != string::npos; + dirEnd = separatorPos, separatorPos = dirName.find_first_not_of( getDirSeparator(), separatorPos ) ) + { + separatorPos = dirName.find( getDirSeparator(), separatorPos ); + if( dirEnd != string::npos ) + { + string parentDir = dirName.substr( 0, dirEnd ); +#if defined(LINUX) || defined(SOLARIS) || defined(MAC) + if( mkdir( parentDir.c_str(), S_IREAD | S_IWRITE | S_IEXEC ) == -1 ) + { + if( errno != EEXIST ) + return false; + } +#elif defined(WIN32) + if (parentDir.size() == 0 || parentDir[parentDir.size()-1] == ':' || + parentDir == string("\\\\.") || parentDir == string("\\\\.\\") || // UNC patch prefix + (strStartWith(parentDir, "\\\\.\\") && parentDir[parentDir.size()-1] == '}')) // UNC patch prefix + continue; + if( CreateDirectory( parentDir.c_str(), 0 ) == 0 ) + { + if( GetLastError() != ERROR_ALREADY_EXISTS ) + return false; + } +#endif + } + } + } + +#if defined(LINUX) || defined(SOLARIS) || defined(MAC) + return mkdir( dirName.c_str(), S_IREAD | S_IWRITE | S_IEXEC ) == 0; +#elif defined(WIN32) + return CreateDirectory( dirName.c_str(), 0 ) != 0; +#endif +} + +bool deleteFile( const string& fileName ) +{ +#if defined(LINUX) || defined(SOLARIS) || defined(MAC) + return unlink( fileName.c_str() ) == 0; +#else + if( DeleteFile(fileName.c_str()) ) + { + return true; + } + else + { + DWORD err = GetLastError(); + return false; + } + + return DeleteFile( fileName.c_str() ) != 0; +#endif +} + + +//----------------------------------------------------------------------------- +#if defined(WIN32) +/** windows implementation */ +//----------------------------------------------------------------------------- +#include + +bool findFiles( + const string& path, + const string& fileMask, + vector< string>* fileList, + bool savePaths ) +{ + WIN32_FIND_DATA fileData; // Data structure describes the file found + HANDLE hSearch; // Search handle returned by FindFirstFile + + hSearch = FindFirstFile( TEXT( string( path + '/' + fileMask ).c_str() ), &fileData); + if( hSearch == INVALID_HANDLE_VALUE ) + return false; + + do + { + if( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) + { + string fileName( fileData.cFileName ); + + fileList->push_back( savePaths ? (path + '/' + fileName) : fileName ); + } + } + while ( FindNextFile (hSearch, &fileData) ); + + FindClose( hSearch ); + + return true; +} + +bool findDirs( + const string& path, + vector< string>* dirsList ) +{ + WIN32_FIND_DATA fileData; // Data structure describes the file found + HANDLE hSearch; // Search handle returned by FindFirstFile + + hSearch = FindFirstFile( TEXT( string( path + "*" ).c_str() ), &fileData); + if( hSearch == INVALID_HANDLE_VALUE ) return false; + + do { + if( !(fileData.dwFileAttributes ^ FILE_ATTRIBUTE_DIRECTORY ) ) { + string dirName( fileData.cFileName ); + + if( "." != dirName && ".." != dirName ) + dirsList->push_back( path + dirName + "/" ); + } + + } while ( FindNextFile (hSearch, &fileData) ); + + FindClose( hSearch ); + + return true; +} +#elif defined(LINUX) || defined(MAC) +#include + +bool findFiles( + const string& path, + const string& fileMask, + vector< string>* fileList, + bool savePaths ) +{ + dirent **namelist; + + int n = scandir( path.c_str(), &namelist, 0, 0 ); //alphasort); + + if( n < 0 ) + { + return false; + } + else + { + while( n-- ) + { + if( namelist[ n ]->d_type == DT_REG ) + { + string fileName( namelist[ n ]->d_name ); + + if( 0 == fnmatch( fileMask.c_str(), fileName.c_str(), 0 ) ) + fileList->push_back( savePaths ? path + fileName : fileName ); + + } + free(namelist[n]); + } + free(namelist); + } + + return true; +} + +bool findDirs( + const string& path, + vector< string>* dirsList ) +{ + dirent **namelist; + + int n = scandir( path.c_str(), &namelist, 0, 0 ); //alphasort); + + if( n < 0 ) + { + return false; + } + else + { + while( n-- ) + { + if( namelist[ n ]->d_type == DT_DIR ) + { + string dirName( namelist[ n ]->d_name ); + + //сохраняем только нормальные + if( "." != dirName && ".." != dirName ) + dirsList->push_back( path + dirName + "/" ); + + } + free(namelist[n]); + } + free(namelist); + } + + return true; +} +#endif +//----------------------------------------------------------------------------- + + +bool findFilesRecursive(const string& path, const string& mask, vector* const fileList ) +{ + //finding files + findFiles( path, mask, fileList, true ); + + vector dirList; + findDirs( path, &dirList ); + + for( unsigned int d_idx = 0; d_idx != dirList.size(); d_idx++ ) + findFilesRecursive( dirList[ d_idx ], mask, fileList ); + + return true; +} diff --git a/libmediation/fs/directory.h b/libmediation/fs/directory.h new file mode 100644 index 0000000..78de9fa --- /dev/null +++ b/libmediation/fs/directory.h @@ -0,0 +1,25 @@ +#ifndef directory_h +#define directory_h + +#include +#include "types/types.h" + +bool createDir( + const std::string& dirName, + bool createParentDirs = false ); + +std::string extractFileDir(const std::string& fileName); + +char getDirSeparator(); + +bool fileExists( const std::string& fileName ); + +uint64_t getFileSize ( const std::string& fileName ); + +/** remove file. cerr contains error code */ +bool deleteFile( const std::string& fileName ); + +bool findFilesRecursive(const std::string& path, const std::string& mask, std::vector< std::string >* const fileList); + + +#endif //directory_h diff --git a/libmediation/fs/file.h b/libmediation/fs/file.h new file mode 100644 index 0000000..57084cf --- /dev/null +++ b/libmediation/fs/file.h @@ -0,0 +1,159 @@ +#ifndef LIBMEDIATION_FILE_H +#define LIBMEDIATION_FILE_H + +#include +#include +#include "../types/types.h" + +#ifdef WIN32 +#pragma warning( disable : 4290 ) +#endif + +class AbstractStream +{ +public: + AbstractStream() {} + virtual ~AbstractStream() {} + + static const unsigned int ofRead = 1; + static const unsigned int ofWrite = 2; + static const unsigned int ofAppend = 4; // file can be exist + static const unsigned int ofOpenExisting = 8; // do not create file if absent + static const unsigned int ofCreateNew = 16; // create new file. Return error If file exist + static const unsigned int ofNoTruncate = 32; // keep file data while opening + + virtual bool open(const char* fName, unsigned int oflag, unsigned int systemDependentFlags = 0 ) = 0; + virtual bool close() = 0; + virtual int64_t size() const = 0; +}; + +class AbstractOutputStream: public AbstractStream +{ +public: + AbstractOutputStream(): AbstractStream() {} + virtual int write( const void* buffer, uint32_t count ) = 0; + virtual void sync() = 0; +}; + + +//! , +class File: public AbstractOutputStream +{ +public: + enum SeekMethod + { + smBegin, + smCurrent, + smEnd + }; + + File(); + //! + /*! + . , . + \param fName + \param oflag + \param systemDependentFlags - . + win32 dwFlagsAndAttributes CreateFile, + unix - (oflag) open. + */ + File( + const char* fName, + unsigned int oflag, + unsigned int systemDependentFlags = 0 ) throw ( std::runtime_error ); + virtual ~File(); + + //! + /*! + , + \param fName + \param oflag + \param systemDependentFlags - . + win32 dwFlagsAndAttributes CreateFile, + unix - (oflag) open. + \return true, , false + */ + virtual bool open( + const char* fName, + unsigned int oflag, + unsigned int systemDependentFlags = 0 ) override; + //! + /*! + \return true, , false + */ + virtual bool close() override; + + //! + /*! + count . . + \return , 0 , -1 . + */ + int read( void* buffer, uint32_t count ) const; + //! + /*! + \return , . -1 (, ). + */ + virtual int write( const void* buffer, uint32_t count ) override; + //! + /*! + + */ + virtual void sync() override; + + //! , + /*! + \return true, , false . + */ + bool isOpen() const; + + //! + /*! + \return + */ + bool size( uint64_t* const fileSize ) const; + + virtual int64_t size() const override { + uint64_t result; + if (size(&result)) + return (int64_t) result; + else + return -1; + } + + //! + /*! + \param offset + \param whence + \return , uint64_t(-1) . + */ + uint64_t seek( int64_t offset, SeekMethod whence = smBegin); + + //! + /*! + . + \param newFileSize . , . + */ + bool truncate( uint64_t newFileSize); + + std::string getName() { return m_name; } + + uint64_t pos() const { return m_pos; } + +private: + void* m_impl; + + friend class MemoryMappedFile; + + std::string m_name; + mutable uint64_t m_pos; +}; + +class FileFactory +{ +public: + virtual ~FileFactory() {} + virtual AbstractOutputStream* createFile() = 0; + virtual bool isVirtualFS() const = 0; +}; + +#endif //LIBMEDIATION_FILE_H diff --git a/libmediation/fs/logstream.h b/libmediation/fs/logstream.h new file mode 100644 index 0000000..2efd612 --- /dev/null +++ b/libmediation/fs/logstream.h @@ -0,0 +1,156 @@ +/* +$Log: logstream.h,v $ +Revision 1.7 2006/08/30 03:50:05 mike + . int uint32_t + +Revision 1.6 2006/08/18 16:16:25 andreyk + netflow collector v4 Netflow v9. + +Revision 1.5 2006/07/20 16:26:18 andreyk + VoipSession VoipProcessor . VoipSession , . + +Revision 1.4 2006/05/29 13:24:23 andreyk + libmediation + +Revision 1.3 2006/05/02 10:49:00 andreyk +*** empty log message *** + +Revision 1.2 2006/04/28 13:46:18 andreyk +*** empty log message *** + +Revision 1.1 2006/04/19 17:00:00 mike +*** empty log message *** + +Revision 1.23 2006/03/24 13:28:29 andreyk + + +Revision 1.22 2006/02/20 13:40:11 andreyk + include + +Revision 1.21 2006/01/27 10:56:19 andreyk + + +Revision 1.20 2006/01/18 11:10:10 mike +*** empty log message *** + +Revision 1.19 2005/12/27 11:52:01 mike + + +Revision 1.18 2005/12/23 15:40:38 mike +*** empty log message *** + +Revision 1.17 2005/09/21 18:22:36 mike +*** empty log message *** + +*/ +#ifndef LOGSTREAM_H +#define LOGSTREAM_H + +#include +#include +#include +#include + +#include "system/mutex.h" + +#include "alternativefilestream.h" + +class LogStream; + +//------------------------------------------------------------------------------------ +// loglevel manipulator class declaration +//------------------------------------------------------------------------------------ +class LIBMEDIATION_API loglevel +{ +public: + loglevel(uint32_t); + LogStream& operator() ( LogStream& ) const; + + uint32_t m_logLevel; + +}; // loglevel + +//------------------------------------------------------------------------------------ +// LogStream class declaration +//------------------------------------------------------------------------------------ +// thread-safe +class LIBMEDIATION_API LogStream +: + public AlternativeFileStream +{ +public: + static const uint32_t MessageLevel = 0x01; + static const uint32_t MessageDate = 0x02; + static const uint32_t MessageTime = 0x04; + static const uint32_t MessageThreadID = 0x08; + + LogStream( + uint32_t logLevel, + const std::string& fileName, + const std::string& oldFilesDir, + const uint32_t secRotationPeriod, + const uint32_t maxFileSizeBytes = 128*1024*1024, + const bool rotateAtInitialization = true, + AlternativeFileStream::DestDirectoryDetalization + dirDetalization = AlternativeFileStream::None, + uint32_t systemMessages = MessageLevel | MessageDate | MessageTime | MessageThreadID, + const std::string& fileNamePrefix = "" ); + virtual ~LogStream(); + + virtual void forceMoveCurrentFile(); + void setLogLevel( uint32_t newLogLevel ); + uint32_t getLogLevel(); + + virtual void write( + const char *str, + uint32_t count ); + virtual void endmsg(); + + virtual AlternativeFileStream& operator<<( const char* ); + virtual AlternativeFileStream& operator<<( const std::string& ); + virtual AlternativeFileStream& operator<<( const LightString& ); + virtual AlternativeFileStream& operator<<( void* ); + virtual AlternativeFileStream& operator<<( const char& ); + virtual AlternativeFileStream& operator<<( const double& ); + virtual AlternativeFileStream& operator<<( const bool ); + virtual AlternativeFileStream& operator<<( const uint16_t ); + virtual AlternativeFileStream& operator<<( const uint32_t ); + virtual AlternativeFileStream& operator<<( const uint64_t ); + virtual AlternativeFileStream& operator<<( const int16_t ); + virtual AlternativeFileStream& operator<<( const int32_t ); + virtual AlternativeFileStream& operator<<( const int64_t ); + virtual AlternativeFileStream& operator<<( const mtime::Time& ); + virtual AlternativeFileStream& operator<<( const mtime::TimeInterval& ); + virtual AlternativeFileStream& operator<<( const mtime::DayTime& ); + virtual AlternativeFileStream& operator<<( const mtime::DayTimeInterval& ); + virtual AlternativeFileStream& operator<<( const IPAddress& ); + virtual AlternativeFileStream& operator<<( const IPNet& ); + + virtual AlternativeFileStream& operator<<( AlternativeFileStream& (*_Pfn)(AlternativeFileStream&) ); + + virtual void width( size_t ); + virtual void fill( char ); + virtual void hex(); + virtual void dec(); + +private: + Mutex m_mutex; + uint32_t m_logLevel; + uint32_t m_currentLogLevel; + uint32_t m_systemMessages; + + void setCurrentLogLevel( uint32_t newCurrentLogLevel ); + + friend class loglevel; + +}; // LogStream +//------------------------------------------------------------------------------------ +void LIBMEDIATION_API bufToLogStream( + const char* const buf, + const uint32_t& length, + LogStream* const stream, + bool printLength = true ); + +LIBMEDIATION_API AlternativeFileStream& operator<<( AlternativeFileStream&, const loglevel& manip ); + +#endif diff --git a/libmediation/fs/osdep/file_unix.cpp b/libmediation/fs/osdep/file_unix.cpp new file mode 100644 index 0000000..45dc276 --- /dev/null +++ b/libmediation/fs/osdep/file_unix.cpp @@ -0,0 +1,182 @@ +/*********************************************************************** +* File: file.cpp +* Author: Andrey Kolesnikov +* Date: 13 oct 2006 +***********************************************************************/ + +#include "../file.h" +#include "../directory.h" + +#include +#include +#include +#include +#include +#include + +#ifdef MAC +#define O_LARGEFILE 0 +#endif + + +void makeUnixOpenFlags( + unsigned int oflag, + int* const unixOflag ) +{ + int sysFlags = 0; + if( oflag & File::ofRead ) + sysFlags = O_RDONLY; + if( oflag & File::ofWrite ) + { + if( oflag & File::ofRead) + sysFlags = O_RDWR | O_TRUNC; + else + sysFlags = O_WRONLY | O_TRUNC; + if( !(oflag & File::ofOpenExisting) ) + sysFlags |= O_CREAT; + if( oflag & File::ofNoTruncate) + { + sysFlags &= ~O_TRUNC; + } + if( oflag & File::ofAppend ) + { + sysFlags |= O_APPEND; + sysFlags &= ~O_TRUNC; + } + + } + if( oflag & File::ofCreateNew ) + sysFlags |= O_CREAT | O_EXCL; + *unixOflag = sysFlags; +} + +File::File(): + m_impl( (void*)0xffffffff ), + m_name ( "" ), + m_pos(0) +{ +} + +File::File ( const char* fName, unsigned int oflag, unsigned int systemDependentFlags ) throw ( std::runtime_error ): + m_name ( fName ), + m_pos(0) +{ + int sysFlags = 0; + makeUnixOpenFlags( oflag, &sysFlags ); + m_impl = (void*)::open( fName, sysFlags | O_LARGEFILE | systemDependentFlags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP ); + if( (long)m_impl == -1 ) + { + std::ostringstream ss; + ss<<"Error opening file "< +#include +#include + + +void throwFileError() +{ + char msgBuf[32*1024]; + memset( msgBuf, 0, sizeof(msgBuf) ); + DWORD dw = GetLastError(); + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &msgBuf, + sizeof(msgBuf), + NULL ); + throw std::runtime_error( msgBuf ); +} + +void makeWin32OpenFlags( + unsigned int oflag, + DWORD* const dwDesiredAccess, + DWORD* const dwCreationDisposition, + DWORD* const dwShareMode ) +{ + *dwDesiredAccess = 0; + *dwCreationDisposition = CREATE_ALWAYS; + if( oflag & File::ofRead ) + { + *dwDesiredAccess = GENERIC_READ & ~SYNCHRONIZE; + *dwCreationDisposition = OPEN_EXISTING; + *dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + } + if( oflag & File::ofWrite ) + { + *dwDesiredAccess |= GENERIC_WRITE & ~SYNCHRONIZE; + *dwCreationDisposition = CREATE_ALWAYS; + *dwShareMode = FILE_SHARE_READ; + } + if( oflag & File::ofAppend ) + *dwCreationDisposition = OPEN_ALWAYS; + if( oflag & File::ofNoTruncate) + *dwCreationDisposition = OPEN_ALWAYS; + if( oflag & File::ofOpenExisting ) + *dwCreationDisposition = OPEN_EXISTING; + if( oflag & File::ofCreateNew ) + *dwCreationDisposition = CREATE_NEW; +} + +File::File(): + AbstractOutputStream(), + m_impl( INVALID_HANDLE_VALUE ), + m_name ( "" ), + m_pos(0) +{ +} + +File::File( const char* fName, unsigned int oflag, unsigned int systemDependentFlags ) throw ( std::runtime_error ): + AbstractOutputStream(), + m_impl( INVALID_HANDLE_VALUE ), + m_name ( fName ), + m_pos(0) +{ + DWORD dwDesiredAccess = 0; + DWORD dwCreationDisposition = CREATE_ALWAYS; + DWORD dwShareMode = 0; + makeWin32OpenFlags( oflag, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode ); + if( !systemDependentFlags ) + { + if( (oflag & ofRead) && !(oflag & ofWrite) ) + systemDependentFlags = FILE_FLAG_SEQUENTIAL_SCAN; + else + systemDependentFlags = FILE_FLAG_RANDOM_ACCESS; + } + m_impl = CreateFile( + fName, + dwDesiredAccess, + dwShareMode, + NULL, + dwCreationDisposition, + systemDependentFlags, + NULL ); + if( m_impl == INVALID_HANDLE_VALUE ) + { + throwFileError(); + } + else + { + if( oflag & File::ofAppend ) { + long hiword = 0; + DWORD newPointerLow = SetFilePointer( m_impl, 0, &hiword, FILE_END ); + if( newPointerLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ) + throwFileError(); + } + } +} + +File::~File() +{ + if( isOpen() ) + close(); +} + +bool File::open( const char* fName, unsigned int oflag, unsigned int systemDependentFlags ) +{ + m_name = fName; + m_pos = 0; + + DWORD dwDesiredAccess = 0; + DWORD dwCreationDisposition = CREATE_ALWAYS; + DWORD dwShareMode = 0; + makeWin32OpenFlags( oflag, &dwDesiredAccess, &dwCreationDisposition, &dwShareMode ); + if( !systemDependentFlags ) + { + if( (oflag & ofRead) && !(oflag & ofWrite) ) + systemDependentFlags = FILE_FLAG_SEQUENTIAL_SCAN; + else + systemDependentFlags = FILE_FLAG_RANDOM_ACCESS; + } + + createDir ( extractFileDir ( fName ), true ); + + m_impl = CreateFile( + fName, + dwDesiredAccess, + dwShareMode, + NULL, + dwCreationDisposition, + systemDependentFlags, + NULL ); + if( m_impl == INVALID_HANDLE_VALUE ) + { + return false; + } + else + { + if( oflag & File::ofAppend ) { + long hiword = 0; + DWORD newPointerLow = SetFilePointer( m_impl, 0, &hiword, FILE_END ); + if( newPointerLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ) + throwFileError(); + } + } + + return true; +} + +bool File::close() +{ + //sync(); + BOOL res = CloseHandle( m_impl ); + m_impl = INVALID_HANDLE_VALUE; + return res != 0; +} + +int File::read( void* buffer, uint32_t count ) const +{ + if( !isOpen() ) + return -1; + + DWORD bytesRead = 0; + BOOL res = ReadFile( m_impl, buffer, count, &bytesRead, NULL ); + if( !res ) + return -1; + + m_pos += bytesRead; + + return (int)bytesRead; +} + +int File::write( const void* buffer, uint32_t count ) +{ + if( !isOpen() ) + return -1; + + DWORD bytesWritten = 0; + BOOL res = WriteFile( m_impl, buffer, count, &bytesWritten, NULL ); + if( !res ) + { + throwFileError(); + } + if( !res ) + return -1; + + m_pos += bytesWritten; + + return (int)bytesWritten; +} + +void File::sync() +{ + FlushFileBuffers( m_impl ); +} + +bool File::isOpen() const +{ + return m_impl != INVALID_HANDLE_VALUE; +} + +bool File::size( uint64_t* const fileSize ) const +{ + DWORD highDw; + DWORD lowDw = GetFileSize( m_impl, &highDw ); + if( (lowDw == INVALID_FILE_SIZE) && (GetLastError() != NO_ERROR) ) + return false; + *fileSize = highDw; + *fileSize <<= 32; + *fileSize |= lowDw; + return true; +} + +uint64_t File::seek( int64_t offset, SeekMethod whence ) +{ + if( !isOpen() ) + return (uint64_t)-1; + + DWORD moveMethod = 0; + switch( whence ) + { + case smBegin: + moveMethod = FILE_BEGIN; + break; + case smCurrent: + moveMethod = FILE_CURRENT; + break; + case smEnd: + moveMethod = FILE_END; + break; + } + + LONG distanceToMoveLow = (uint32_t)(offset & 0xffffffff); + LONG distanceToMoveHigh = (uint32_t)((offset & 0xffffffff00000000ull) >> 32); + + DWORD newPointerLow = SetFilePointer( m_impl, distanceToMoveLow, &distanceToMoveHigh, moveMethod ); + if( newPointerLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ) + return (uint64_t)-1; + + m_pos = newPointerLow | ((uint64_t)distanceToMoveHigh << 32); + + return m_pos; +} + +bool File::truncate( uint64_t newFileSize) +{ + LONG distanceToMoveLow = (uint32_t)(newFileSize & 0xffffffff); + LONG distanceToMoveHigh = (uint32_t)((newFileSize & 0xffffffff00000000ull) >> 32); + DWORD newPointerLow = SetFilePointer( + m_impl, + distanceToMoveLow, + &distanceToMoveHigh, + FILE_BEGIN ); + int errCode = GetLastError(); + if( (newPointerLow == INVALID_SET_FILE_POINTER) && (errCode != NO_ERROR) ) + //return false; + throwFileError(); + + return SetEndOfFile( m_impl ) > 0; +} diff --git a/libmediation/fs/systemlog.h b/libmediation/fs/systemlog.h new file mode 100644 index 0000000..e875b99 --- /dev/null +++ b/libmediation/fs/systemlog.h @@ -0,0 +1,13 @@ +#ifndef SYSTEMLOG_H +#define SYSTEMLOG_H + +const static unsigned LT_FATAL_ERROR = 0; +const static unsigned LT_ERROR = 1; +const static unsigned LT_WARN = 2; +const static unsigned LT_INFO = 3; +const static unsigned LT_DEBUG = 4; +const static unsigned LT_DEBUG2 = 5; +const static unsigned LT_DEBUG6 = 5; +const static unsigned LT_DEBUG7 = 7; + +#endif diff --git a/libmediation/fs/textfile.h b/libmediation/fs/textfile.h new file mode 100644 index 0000000..7d7ead9 --- /dev/null +++ b/libmediation/fs/textfile.h @@ -0,0 +1,43 @@ +#ifndef LIBMEDIATION_TEXTFILE_H +#define LIBMEDIATION_TEXTFILE_H + +#include "file.h" + +class TextFile: public File { +public: + TextFile(): File() {} + TextFile( + const char* fName, + unsigned int oflag, + unsigned int systemDependentFlags = 0 ): File(fName, oflag, systemDependentFlags) {} + + bool readLine(std::string& line) + { + line = ""; + char ch; + int readCnt = 0; + do { + readCnt = read( &ch, 1); + } while (readCnt == 1 && (ch == '\n' || ch == '\r')); + if (readCnt != 1) + return false; + if (ch != '\n' && ch != '\r') + line += ch; + while(1) { + readCnt = read( &ch, 1); + if (readCnt == 1 && ch != '\n' && ch != '\r') + line += ch; + else + break; + }; + return readCnt == 1 || !line.empty(); + } + bool writeLine(const std::string& line) + { + if (write(line.c_str(),line.size()) != line.size()) + return false; + return write("\r\n", 2) == 2; + } +}; + +#endif diff --git a/libmediation/libmediationlight.vcproj b/libmediation/libmediationlight.vcproj new file mode 100644 index 0000000..9e348ff --- /dev/null +++ b/libmediation/libmediationlight.vcproj @@ -0,0 +1,281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libmediation/system/condvar.h b/libmediation/system/condvar.h new file mode 100644 index 0000000..5fde197 --- /dev/null +++ b/libmediation/system/condvar.h @@ -0,0 +1,26 @@ +#ifndef IPSOFT_COND_VAR_H +#define IPSOFT_COND_VAR_H + +#include "system/mutex.h" +#include "time/time.h" + + +class ConditionVariable +{ +public: + ConditionVariable(); + ~ConditionVariable(); + + void notify_one(); + void notify_all(); + + void wait( Mutex::ScopedLock* const lock ); +private: + void* const m_impl; + + ConditionVariable( const ConditionVariable& ); + ConditionVariable& operator=( const ConditionVariable& ); + +}; + +#endif// IPSOFT_COND_VAR_H diff --git a/libmediation/system/mutex.h b/libmediation/system/mutex.h new file mode 100644 index 0000000..5a37663 --- /dev/null +++ b/libmediation/system/mutex.h @@ -0,0 +1,40 @@ +#ifndef IPSOFT_MUTEX_H +#define IPSOFT_MUTEX_H + +class Mutex +{ + friend class ScopedLock; +public: + //! + class ScopedLock + { + friend class ConditionVariable; + public: + ScopedLock( Mutex* const ); + ~ScopedLock(); + + private: + friend class ConditionVariableImpl; + + ScopedLock( const ScopedLock& ); + ScopedLock& operator=( const ScopedLock& ); + + Mutex* const m_mtx; + }; + + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + +private: + friend class ConditionVariableImpl; + + Mutex( const Mutex& ); + Mutex& operator=( const Mutex& ); + + void* m_mtxImpl; +}; + +#endif// IPSOFT_MUTEX_H diff --git a/libmediation/system/osdep/common_win32.cpp b/libmediation/system/osdep/common_win32.cpp new file mode 100644 index 0000000..77c5d45 --- /dev/null +++ b/libmediation/system/osdep/common_win32.cpp @@ -0,0 +1,53 @@ +/*********************************************************************** +* File: system/osdep/common_win32.cpp +* Author: Andrey Kolesnikov +* Date: 26 jun 2007 +***********************************************************************/ + +#include "common_win32.h" + + +void initializeAllAccessSecurityDescriptor( SECURITY_DESCRIPTOR* const sd ) +{ + if( !InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION) ) + { + char msgBuf[32*1024]; + memset( msgBuf, 0, sizeof(msgBuf) ); + DWORD dw = GetLastError(); + char* msgBufPos = msgBuf; + strcpy( msgBufPos, "Cannot initialize SECURITY_DESCRIPTOR structure: " ); + msgBufPos += strlen( msgBufPos ); + + DWORD bufSize = sizeof(msgBuf) - (msgBufPos - msgBuf); + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)msgBufPos, + bufSize, + NULL ); + throw std::runtime_error( msgBuf ); + } + + if( !SetSecurityDescriptorDacl(sd, TRUE, NULL, FALSE) ) + { + char msgBuf[32*1024]; + memset( msgBuf, 0, sizeof(msgBuf) ); + DWORD dw = GetLastError(); + char* msgBufPos = msgBuf; + strcpy( msgBufPos, "Cannot set NULL DACL to security descriptor: " ); + msgBufPos += strlen( msgBufPos ); + + DWORD bufSize = sizeof(msgBuf) - (msgBufPos - msgBuf); + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dw, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)msgBufPos, + bufSize, + NULL ); + throw std::runtime_error( msgBuf ); + } +} diff --git a/libmediation/system/osdep/common_win32.h b/libmediation/system/osdep/common_win32.h new file mode 100644 index 0000000..7ad44f0 --- /dev/null +++ b/libmediation/system/osdep/common_win32.h @@ -0,0 +1,17 @@ +/*********************************************************************** +* File: system/osdep/common_win32.h +* Author: Andrey Kolesnikov +* Date: 26 jun 2007 +***********************************************************************/ + +#ifndef COMMON_WIN32_H +#define COMMON_WIN32_H + +#include + +#include + + +void initializeAllAccessSecurityDescriptor( SECURITY_DESCRIPTOR* const sa ) throw ( std::runtime_error ); + +#endif //COMMON_WIN32_H diff --git a/libmediation/system/osdep/condvar_linux.cpp b/libmediation/system/osdep/condvar_linux.cpp new file mode 100644 index 0000000..0609ac4 --- /dev/null +++ b/libmediation/system/osdep/condvar_linux.cpp @@ -0,0 +1,106 @@ +/*********************************************************************** +* File: system/condvar_linux.cpp +* Author: Andrey Kolesnikov +* Date: 28 dec 2005 +***********************************************************************/ + +/* +$Log: condvar_linux.cpp,v $ +Revision 1.4 2007/03/07 10:07:36 andreyk + +Fixed GCC compile errors + +Revision 1.3 2007/03/07 09:16:30 andreyk + timed_wait + +Revision 1.2 2007/02/02 16:39:23 andreyk +*** empty log message *** + +Revision 1.1 2006/04/19 17:00:03 mike +*** empty log message *** + +Revision 1.4 2006/03/03 17:19:34 andreyk + private , . + +Revision 1.3 2006/02/15 12:11:47 andreyk + , warning + +Revision 1.2 2006/02/06 08:40:28 andreyk + . + +Revision 1.1 2005/12/28 14:34:34 andreyk + +Building project under Linux + +*/ + +#include "../condvar.h" + +#include +#include + + +class ConditionVariableImpl +{ + +public: + ConditionVariableImpl() + { + pthread_cond_init( &m_cond, NULL ); + } + + ~ConditionVariableImpl() + { + pthread_cond_destroy( &m_cond ); + } + + void notify_one() + { + pthread_cond_signal( &m_cond ); + } + + void notify_all() + { + pthread_cond_broadcast( &m_cond ); + } + + void wait( Mutex::ScopedLock* const lock ) + { + pthread_cond_wait( + &m_cond, + reinterpret_cast( lock->m_mtx->m_mtxImpl ) ); + } + + +private: + pthread_cond_t m_cond; + +}; + + +ConditionVariable::ConditionVariable() +: + m_impl( new ConditionVariableImpl() ) +{ +} + +ConditionVariable::~ConditionVariable() +{ + delete reinterpret_cast(m_impl); +} + +void ConditionVariable::notify_one() +{ + reinterpret_cast(m_impl)->notify_one(); +} + +void ConditionVariable::notify_all() +{ + reinterpret_cast(m_impl)->notify_all(); +} + +void ConditionVariable::wait( Mutex::ScopedLock* const lock ) +{ + reinterpret_cast(m_impl)->wait( lock ); +} + diff --git a/libmediation/system/osdep/condvar_win32.cpp b/libmediation/system/osdep/condvar_win32.cpp new file mode 100644 index 0000000..fc4fcf8 --- /dev/null +++ b/libmediation/system/osdep/condvar_win32.cpp @@ -0,0 +1,109 @@ +#include "system/condvar.h" + +#include + + +enum +{ + SIGNAL = 0, + BROADCAST = 1, + MAX_EVENTS = 2 +}; + +class ConditionVariableImpl +{ +public: + ConditionVariableImpl() + : + m_waitersCount( 0 ) + { + m_events[SIGNAL] = CreateEvent( + NULL, // no security + FALSE, // auto-reset event + FALSE, // non-signaled initially + NULL ); // unnamed + + m_events[BROADCAST] = CreateEvent( + NULL, // no security + TRUE, // manual-reset + FALSE, // non-signaled initially + NULL ); // unnamed + } + + ~ConditionVariableImpl() + { + CloseHandle( m_events[SIGNAL] ); + CloseHandle( m_events[BROADCAST] ); + } + + void notify_one() + { + Mutex::ScopedLock sl( &m_waitersCountLock ); + + if( m_waitersCount > 0 ) + SetEvent( m_events[SIGNAL] ); + } + + void notify_all() + { + Mutex::ScopedLock sl( &m_waitersCountLock ); + + if( m_waitersCount > 0 ) + SetEvent( m_events[BROADCAST] ); + } + + void do_wait( Mutex* const mtx ) + { + { + Mutex::ScopedLock sl( &m_waitersCountLock ); + m_waitersCount++; + } + + mtx->unlock(); + + int result = WaitForMultipleObjects( 2, m_events, FALSE, INFINITE ); + + { + Mutex::ScopedLock sl( &m_waitersCountLock ); + + m_waitersCount--; + if( (result == WAIT_OBJECT_0 + BROADCAST) && (m_waitersCount == 0) ) + ResetEvent( m_events[BROADCAST] ); + } + + mtx->lock(); + } + + +private: + HANDLE m_events[MAX_EVENTS]; + unsigned int m_waitersCount; + Mutex m_waitersCountLock; +}; + +ConditionVariable::ConditionVariable() +: + m_impl( new ConditionVariableImpl() ) +{ +} + +ConditionVariable::~ConditionVariable() +{ + delete ((ConditionVariableImpl*)m_impl); +} + +void ConditionVariable::notify_all() +{ + ((ConditionVariableImpl*)m_impl)->notify_all(); +} + +void ConditionVariable::notify_one() +{ + ((ConditionVariableImpl*)m_impl)->notify_one(); +} + +void ConditionVariable::wait( Mutex::ScopedLock* const lock ) +{ + ((ConditionVariableImpl*)m_impl)->do_wait( lock->m_mtx ); +} + diff --git a/libmediation/system/osdep/mutex_linux.cpp b/libmediation/system/osdep/mutex_linux.cpp new file mode 100644 index 0000000..9e3f36c --- /dev/null +++ b/libmediation/system/osdep/mutex_linux.cpp @@ -0,0 +1,78 @@ +/*********************************************************************** +* File: system/mutex_linux.cpp +* Author: Andrey Kolesnikov +* Date: 28 dec 2005 +***********************************************************************/ + +/* +$Log: mutex_linux.cpp,v $ +Revision 1.4 2007/06/22 14:20:19 andreyk +*** empty log message *** + +Revision 1.3 2007/02/25 13:35:27 andreyk + . + +Revision 1.2 2006/09/21 10:56:10 andreyk + Mutex::ScopedLock: unlock, ScopedLock::~ScopedLock , . + +Revision 1.1 2006/04/19 17:00:03 mike +*** empty log message *** + +Revision 1.3 2006/02/06 08:38:39 andreyk + Mutex . + +Revision 1.2 2006/02/02 11:22:11 andreyk + +Building mediation under linux + +Revision 1.1 2005/12/28 14:34:34 andreyk + +Building project under Linux + +*/ + +#include "../mutex.h" + +#include + + +Mutex::ScopedLock::ScopedLock( Mutex* mtx ) +: + m_mtx( mtx ) +{ + m_mtx->lock(); +} + +Mutex::ScopedLock::~ScopedLock() +{ + m_mtx->unlock(); +} + + +Mutex::Mutex() +: + m_mtxImpl( new pthread_mutex_t ) +{ + pthread_mutex_init( reinterpret_cast(m_mtxImpl), NULL ); +} + +Mutex::~Mutex() +{ + pthread_mutex_destroy( reinterpret_cast(m_mtxImpl) ); + delete reinterpret_cast(m_mtxImpl); + m_mtxImpl = 0; +} + +void Mutex::lock() +{ + if( m_mtxImpl ) + pthread_mutex_lock( reinterpret_cast(m_mtxImpl) ); +} + + +void Mutex::unlock() +{ + if( m_mtxImpl ) + pthread_mutex_unlock( reinterpret_cast(m_mtxImpl) ); +} + diff --git a/libmediation/system/osdep/mutex_win32.cpp b/libmediation/system/osdep/mutex_win32.cpp new file mode 100644 index 0000000..05ecb81 --- /dev/null +++ b/libmediation/system/osdep/mutex_win32.cpp @@ -0,0 +1,50 @@ + +#include "../mutex.h" + +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x400 +#endif + +#include + +Mutex::Mutex() +: + m_mtxImpl( new CRITICAL_SECTION() ) +{ + InitializeCriticalSection( (CRITICAL_SECTION*)m_mtxImpl ); +} + +Mutex::~Mutex() +{ + DeleteCriticalSection( (CRITICAL_SECTION*)m_mtxImpl ); + delete (LPCRITICAL_SECTION)m_mtxImpl; + m_mtxImpl = 0; +} + +void Mutex::lock() +{ + if( !m_mtxImpl ) + return; + EnterCriticalSection( (CRITICAL_SECTION*)m_mtxImpl ); +} + +void Mutex::unlock() +{ + if( !m_mtxImpl ) + return; + LeaveCriticalSection( (CRITICAL_SECTION*)m_mtxImpl ); +} + +//#endif + +Mutex::ScopedLock::ScopedLock( Mutex* const mtx ) +: + m_mtx( mtx ) +{ + m_mtx->lock(); +} + +Mutex::ScopedLock::~ScopedLock() +{ + m_mtx->unlock(); +} diff --git a/libmediation/system/osdep/terminatablethread_linux.cpp b/libmediation/system/osdep/terminatablethread_linux.cpp new file mode 100644 index 0000000..32a7459 --- /dev/null +++ b/libmediation/system/osdep/terminatablethread_linux.cpp @@ -0,0 +1,165 @@ +/*********************************************************************** +* File: system/terminatablethread_linux.cpp +* Author: Andrey Kolesnikov +* Date: 28 dec 2005 +***********************************************************************/ + +/* +$Log: terminatablethread_linux.cpp,v $ +Revision 1.5 2006/09/14 19:11:21 andreyk + +Corrected daemon-startup sequence. + +Revision 1.4 2006/08/31 19:22:51 andreyk +*** empty log message *** + +Revision 1.3 2006/08/30 13:00:09 andreyk +*** empty log message *** + +Revision 1.2 2006/06/15 17:04:26 andreyk + voip-. + +Revision 1.1 2006/04/19 17:00:03 mike +*** empty log message *** + +Revision 1.2 2006/02/02 16:14:40 andreyk + +Build project under linux + +Revision 1.1 2005/12/28 14:34:34 andreyk + +Building project under Linux + +*/ + +#include "../terminatablethread.h" + +extern "C" { +#include +} + +#include +#include +#include "errno.h" + +using namespace std; + +const static int PRIORITIES [ 6 ] = { 19, 10, 0, 10, -19, -20 }; + +class ThreadImpl +{ +public: + ThreadImpl() + : + m_threadHandle( 0 ) + { + } + + ~ThreadImpl() + { + if( m_threadHandle ) + { + pthread_detach(m_threadHandle); + pthread_cancel( m_threadHandle ); + m_threadHandle = 0; + } + } + + void join() + { + if( m_threadHandle ) + pthread_join( m_threadHandle, NULL ); + } + +#ifndef MAC + bool setPriority ( int nPriority ) + { + return pthread_setschedprio ( m_threadHandle, PRIORITIES [ nPriority ] ) == 0; + } +#endif + + pthread_t m_threadHandle; +}; + + +void threadProc( TerminatableThread* const ptr ) +{ + ptr->thread_main(); + //pthread_t handle = reinterpret_cast(ptr->m_impl)->m_threadHandle; + //reinterpret_cast(ptr->m_impl)->m_threadHandle = 0; + //pthread_detach(handle); + pthread_exit ( NULL ); +} +void* thread_proc( void* param ) +{ + threadProc( reinterpret_cast(param) ); + return NULL; +} + +TerminatableThread::TerminatableThread() +: + m_impl( new ThreadImpl() ) +{ +} + +TerminatableThread::~TerminatableThread() +{ + delete reinterpret_cast(m_impl); +} + +void TerminatableThread::run( TerminatableThread* const thread ) +{ + int err = 0; + size_t stackSize = 0; + + pthread_attr_t attr; + + if ( ( err = pthread_attr_init ( &attr ) ) == 0 ) + { + //LTRACE(LT_DEBUG, 0, "TerminatableThread::run: pthread_attr_init success" ) + //cout << "TerminatableThread::run: pthread_attr_init success" << endl; + + if ( ( err = pthread_attr_getstacksize ( &attr, &stackSize ) ) == 0 ) + { + //LTRACE(LT_DEBUG, 0, "TerminatableThread::run: pthread_attr_getstacksize success, stackSize=" << stackSize ) + //cout << "TerminatableThread::run: pthread_attr_getstacksize success, stackSize=" << stackSize << endl; + + stackSize = 1024 * 1024; + + if ( ( err = pthread_attr_setstacksize ( &attr, stackSize ) ) == 0 ) + { + //cout << "TerminatableThread::run: pthread_attr_setstacksize success" << endl; + + if ( ( err = pthread_create ( &reinterpret_cast < ThreadImpl* >( thread->m_impl )->m_threadHandle, &attr, thread_proc, thread ) ) == 0 ) + { + //cout << "TerminatableThread::run: pthread_create success" << endl; + + } + else { + //cout << "TerminatableThread::run: pthread_create fail, errno=" << err << endl; + } + } + else { + //cout << "TerminatableThread::run: pthread_attr_setstacksize fail, errno=" << err << endl; + } + } + else { + //cout << "TerminatableThread::run: pthread_attr_getstacksize fail, errno=" << err << endl; + } + } + else { + //cout << "TerminatableThread::run: pthread_attr_init fail, errno=" << err << endl; + } +} + +void TerminatableThread::join() +{ + reinterpret_cast(m_impl)->join(); +} + +Terminatable::~Terminatable() +{ +} + + +//--------------------------------------------------------------------------------------- diff --git a/libmediation/system/osdep/terminatablethread_win32.cpp b/libmediation/system/osdep/terminatablethread_win32.cpp new file mode 100644 index 0000000..9c68e14 --- /dev/null +++ b/libmediation/system/osdep/terminatablethread_win32.cpp @@ -0,0 +1,76 @@ +#include "../terminatablethread.h" + +#include + +#include "../mutex.h" + +Terminatable::~Terminatable() +{ +} + + +class ThreadImpl +{ +public: + ThreadImpl() + : + m_threadHandle( 0 ) + { + } + + ~ThreadImpl() + { + if( m_threadHandle ) + { + TerminateThread( m_threadHandle, 0 ); + CloseHandle ( m_threadHandle ); + } + } + + void join() + { + WaitForSingleObject( m_threadHandle, INFINITE ); + } + + HANDLE m_threadHandle; +}; + + +void threadProc( TerminatableThread* const ptr ) +{ + ptr->thread_main(); +} + +DWORD WINAPI thread_proc( LPVOID lpParameter ) +{ + threadProc( static_cast(lpParameter) ); + return 0; +} + +TerminatableThread::TerminatableThread() +: + m_impl( new ThreadImpl() ) +{ +} + +TerminatableThread::~TerminatableThread() +{ + delete static_cast(m_impl); +} + +void TerminatableThread::run( TerminatableThread* const thread ) +{ + static_cast(thread->m_impl)->m_threadHandle = + CreateThread( + NULL, + 0, + thread_proc, + thread, + 0, + 0 ); +} + +void TerminatableThread::join() +{ + static_cast(m_impl)->join(); +} diff --git a/libmediation/system/terminatablethread.h b/libmediation/system/terminatablethread.h new file mode 100644 index 0000000..23164dd --- /dev/null +++ b/libmediation/system/terminatablethread.h @@ -0,0 +1,40 @@ + +#ifndef _TERMINATABLE_THREAD_H +#define _TERMINATABLE_THREAD_H + +class Terminatable +{ +public: + virtual ~Terminatable(); + + virtual void terminate() = 0; +}; + +class TerminatableThread: public Terminatable +{ +public: + //! run(thread) + TerminatableThread(); + //! + virtual ~TerminatableThread(); + + //! . . + static void run( TerminatableThread* const ); + + void join(); + + + +protected: + //! . . + virtual void thread_main() = 0; + +private: + TerminatableThread( const TerminatableThread& ); + TerminatableThread& operator=( const TerminatableThread& ); + + friend void threadProc( TerminatableThread* const ptr ); + void* const m_impl; +}; + +#endif //_TERMINATABLE_THREAD_H diff --git a/libmediation/time/time.cpp b/libmediation/time/time.cpp new file mode 100644 index 0000000..a1fd8f1 --- /dev/null +++ b/libmediation/time/time.cpp @@ -0,0 +1,83 @@ +#include "time.h" + +#include +#include + + +#ifdef WIN32 +#include +#include +#include +#endif + +#ifdef LINUX +#include +#include + +#endif + +#ifdef SOLARIS +//extern time_t timezone; +#include +#endif + +#ifdef MAC +//extern time_t timezone; +#include +#endif + +#include "../system/mutex.h" + + +namespace mtime +{ + +uint32_t clockGetTime() +{ +#ifdef WIN32 + return (uint32_t)GetTickCount(); +#else + // POSIX + struct timeval tv; + gettimeofday(&tv, 0); + return (uint32_t) (tv.tv_sec * 1000ull + tv.tv_usec/1000); +#endif +} + +uint64_t clockGetTimeEx() +{ +#ifdef WIN32 + + static uint32_t prevTics = 0; + static uint64_t cycleCount = 0; + static Mutex timeMutex; + Mutex::ScopedLock lock(&timeMutex); + uint32_t tics = (uint32_t) timeGetTime(); + if (tics < prevTics) + cycleCount+= 0x100000000ull; + prevTics = tics; + return ((uint64_t) tics + cycleCount) * 1000ull; + + + /* + static uint64_t freq = 0; + if( freq == 0 ) + { + LARGE_INTEGER timerFrequency; + QueryPerformanceFrequency( &timerFrequency ); + freq = timerFrequency.QuadPart / 1000000ull; + } + + LARGE_INTEGER t; + QueryPerformanceCounter( &t ); + return (t.QuadPart+500000l) / freq; + */ +#else + // POSIX + struct timeval tv; + gettimeofday(&tv, 0); + return tv.tv_sec * 1000000ull + tv.tv_usec; +#endif +} + +} diff --git a/libmediation/time/time.h b/libmediation/time/time.h new file mode 100644 index 0000000..e2a2c58 --- /dev/null +++ b/libmediation/time/time.h @@ -0,0 +1,26 @@ +#ifndef __T_MTime_H +#define __T_MTime_H + +#include + +#include "types/types.h" + + +namespace mtime +{ + class TimeInterval; + class DayTimeInterval; +}; + +namespace mtime +{ + // , ( Windows) + // Linux. + uint32_t clockGetTime(); + + // , . + uint64_t clockGetTimeEx(); + +}; + +#endif //__T_MTime_H diff --git a/libmediation/types/types.cpp b/libmediation/types/types.cpp new file mode 100644 index 0000000..f1cbe16 --- /dev/null +++ b/libmediation/types/types.cpp @@ -0,0 +1,518 @@ +#include "types.h" + +#include +#include +#include +#include + +#ifndef WIN32 +#include +#include +#include +#include +#endif + +#include "fs/directory.h" + +#include + + +using namespace std; + +uint64_t my_ntohll( const uint64_t& original ) +{ +#ifdef SPARC_V9 // big endian + return original; +#else // little endian + return (((uint64_t)my_ntohl((uint32_t)original))<<32) | ((uint64_t)my_ntohl((uint32_t)(original>>32))); +#endif +} + +uint64_t my_htonll( const uint64_t& original ) +{ +#ifdef SPARC_V9 // big endian + return original; +#else // little endian + return (((uint64_t)my_ntohl((uint32_t)original))<<32) | ((uint64_t)my_ntohl((uint32_t)(original>>32))); +#endif +} + +// Simple types conversion +int64_t strToInt64( const char* const str ) +{ +#ifdef WIN32 + return _atoi64( str ); +#else + return strtoll( str, 0, 10 ); +#endif +} + +uint64_t strToInt64u( const char* const str ) +{ +#ifdef WIN32 + return _atoi64( str ); +#else + return strtoull( str, 0, 10 ); +#endif +} + + +int32_t strToInt32( const char* const str ) +{ + return strtol( str, 0, 10 ); +} + +int32_t strToInt32( const std::string& str) +{ + return strToInt32( str.c_str() ); +} + +int32_t strToInt32( const char* const str, int radix ) +{ + return strtol( str, 0, radix); +} + +int32_t strWToInt32( const wchar_t* const str ) +{ + return wcstol( str, 0, 10 ); +} + +int32_t strWToInt32( const wchar_t* const str, int radix) +{ + return wcstol( str, 0, radix); +} + +uint32_t strWToInt32u( const wchar_t* const str, int radix) +{ + return static_cast(wcstoul( str, 0, radix )); +} + +uint32_t strToInt32u( const char* const str , int radix) +{ + return static_cast(strtoul( str, 0, radix )); +} + + +int16_t strToInt16( const char* const str ) +{ + return (int16_t)strtol( str, 0, 10 ); +} + +uint16_t strToInt16u( const char* const str ) +{ + return (uint16_t)strtol( str, 0, 10 ); +} + +int8_t strToInt8( const char* const str ) +{ + return (int8_t)strtol( str, 0, 10 ); +} + +uint8_t strToInt8u( const char* const str ) +{ + return (uint8_t)strtol( str, 0, 10 ); +} + +double strToDouble( const char* const str ) +{ + return strtod( str, 0 ); +} + +double strWToDouble( const wchar_t* const str ) +{ + return wcstod( str, 0 ); +} + +bool strToBool( const char* const str ) +{ + if( !strcmp(str,"true") ) + return true; + + return false; +} + +string int64ToStr( const int64_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int64uToStr( const uint64_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int32ToStr( const int32_t& x) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int32ToHex( const int32_t& x) +{ + std::ostringstream str; + str << std::hex << x; + return str.str(); +} + +string int32uToStr( const uint32_t& x) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int32uToHex( const uint32_t& x) +{ + std::ostringstream str; + str << std::hex << x; + return str.str(); +} + +string doubleToStr( const double& x, int precision ) +{ + std::ostringstream str; + if (precision > 0) + str << fixed << std::setprecision( precision ); + str << x; + return str.str(); +} + + +string int16ToStr( const int16_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int16uToStr( const uint16_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int8ToStr( const int8_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string int8uToStr( const uint8_t& x ) +{ + std::ostringstream str; + str << x; + return str.str(); +} + +string boolToStr( const bool& x ) +{ + return x ? "true" : "false"; +} + +uint32_t roundDown( const uint32_t& value, const uint32_t& roundVal ) +{ + return roundVal ? (value/roundVal)*roundVal : 0; +} + +uint32_t roundUp( const uint32_t& value, const uint32_t& roundVal ) +{ + return roundVal ? ((value+roundVal-1)/roundVal)*roundVal : 0; +} + +uint64_t roundDown64( const uint64_t& value, const uint64_t& roundVal ) +{ + return roundVal ? (value/roundVal)*roundVal : 0; +} + +uint64_t roundUp64( const uint64_t& value, const uint64_t& roundVal ) +{ + return roundVal ? ((value+roundVal-1)/roundVal)*roundVal : 0; +} + +string strPadLeft(const string& str, size_t newSize, char filler) +{ + int cnt = newSize - str.size(); + string prefix = ""; + for (int i = 0; i < cnt; i++) + prefix += filler; + return prefix + str; +} + +string strPadRight(const string& str, size_t newSize, char filler) +{ + int cnt = newSize - str.size(); + string postfix = ""; + for (int i = 0; i < cnt; i++) + postfix += filler; + return str + postfix; +} + +bool strEndWith(const string& str, const string& substr) +{ + if (str.size() == 0) + return false; + size_t idx = str.size(); + for (int i = substr.size()-1; i >= 0; i--) + if (substr[i] != str[--idx]) + return false; + return true; +} + +bool strStartWith(const string& str, const string& substr) +{ + if (str.size() < substr.size()) + return false; + for (size_t i = 0; i < substr.size(); i++) + if (substr[i] != str[i]) + return false; + return true; +} + +bool strStartWithW(const wstring& str, const wstring& substr) +{ + if (str.size() < substr.size()) + return false; + for (size_t i = 0; i < substr.size(); i++) + if (substr[i] != str[i]) + return false; + return true; +} + +vector splitStr(const char* str, char splitter) +{ + vector rez; + const char* prevPos = str; + const char* buf = str; + for (; *buf; buf++) { + if (*buf == splitter) { + rez.push_back(string(prevPos, buf-prevPos)); + prevPos = buf + 1; + } + } + if (buf > prevPos) + rez.push_back(string(prevPos, buf-prevPos)); + return rez; +} + +vector < string > splitStr ( const string& str, const string& splitter ) +{ + vector < string > res; + + size_t splitterSize = splitter.size(); + size_t posBegin = 0; + size_t posEnd = string::npos; + + if ( splitterSize > 0 && !str.empty() ) + { + while ( ( posEnd = str.find ( splitter, posBegin ) ) != string::npos ) + { + res.push_back ( str.substr ( posBegin, posEnd - posBegin ) ); + posBegin = posEnd + splitterSize; + } + + //if ( res.size() == 0 ) + res.push_back ( str.substr ( posBegin, str.size() ) ); + } + + return res; +} + +void splitStr(vector& rez, const char* str, char splitter) +{ + rez.clear(); + const char* prevPos = str; + const char* buf = str; + for (; *buf; buf++) { + if (*buf == splitter) { + rez.push_back(string(prevPos, buf-prevPos)); + prevPos = buf + 1; + } + } + if (buf > prevPos) + rez.push_back(string(prevPos, buf-prevPos)); +} + +vector splitStrW(const wchar_t* str, wchar_t splitter) +{ + vector rez; + const wchar_t* prevPos = str; + const wchar_t* buf = str; + for (; *buf; buf++) { + if (*buf == splitter) { + rez.push_back(wstring(prevPos, buf-prevPos)); + prevPos = buf + 1; + } + } + if (buf > prevPos) + rez.push_back(wstring(prevPos, buf-prevPos)); + return rez; +} + +string extractFileExt(const string& src) +{ + for (int i = src.size()-1; i >=0; i--) + if (src[i] == '.') { + string rez = src.substr(i+1); + if (rez.size() > 0 && rez[rez.size()-1] == '\"') + return rez.substr(0, rez.size()-1); + else + return rez; + } + return ""; +} + +string extractFileName(const string& src) +{ + int endPos = src.size(); + for (int i = src.size()-1; i >=0; i--) + if (src[i] == '.') { + endPos = i; + } + else if (src[i] == '/' || src[i] == '\\') { + string rez = src.substr(i+1, endPos - i-1); + if (rez.size() > 0 && rez[rez.size()-1] == '\"') + return rez.substr(0, rez.size()-1); + else + return rez; + } + return ""; +} + +string extractFileName2(const string& src, bool withExt ) +{ + string fileName = src; + + size_t extSep = fileName.find_last_of('.'); + size_t dirSep = fileName.find_last_of ('/'); + + if ( dirSep == string::npos ) + dirSep = fileName.find_last_of ('\\'); + + if( extSep != string::npos && !withExt) + fileName = fileName.substr( 0, extSep ); + + if ( dirSep != string::npos ) + fileName = fileName.substr( dirSep + 1, fileName.size() ); + + return fileName; +} + + +string extractFilePath(const string& src) +{ + for (int i = src.size()-1; i >=0; i--) + if (src[i] == '/' || src[i] == '\\') { + string rez = src.substr(0, i); + return rez; + } + return ""; +} + +string closeDirPath(const string& src, char delimiter) +{ + if (delimiter == ' ') + delimiter = getDirSeparator(); + if (src.length() == 0) + return src; + if (src[src.length()-1] == '/' || src[src.length()-1] == '\\') + return src; + return src + delimiter; +} + +string trimStr(const string& value) +{ + const char* bufStart = value.c_str(); + const char* bufEnd = bufStart + value.length()-1; + const char* chBeg = bufStart; + const char* chEnd = bufEnd; + for (; chBeg < bufEnd && (*chBeg == '\n' || *chBeg == '\r' || *chBeg == ' '); chBeg++); + for (; chEnd >= chBeg && (*chEnd == '\n' || *chEnd == '\r' || *chEnd == ' '); chEnd--); + return value.substr(chBeg-bufStart, chEnd - chBeg + 1); +} + +wstring trimStrW(const wstring& value) +{ + int chBeg = 0; + int chEnd = value.length()-1; + for (; chBeg < value.length() && (value[chBeg] == '\n' || value[chBeg] == '\r' || value[chBeg] == ' '); chBeg++); + for (; chEnd >= chBeg && (value[chEnd] == '\n' || value[chEnd] == '\r' || value[chEnd] == ' '); chEnd--); + return value.substr(chBeg, chEnd - chBeg + 1); +} + +vector splitQuotedStr(const char* str, char splitter) +{ + vector rez; + const char* prevPos = str; + const char* buf = str; + bool quoted = false; + for (; *buf; buf++) + { + if (*buf == '"') + quoted = !quoted; + if (*buf == splitter && !quoted) { + rez.push_back(string(prevPos, buf-prevPos)); + prevPos = buf + 1; + } + } + if (buf > prevPos) + rez.push_back(string(prevPos, buf-prevPos)); + return rez; +} + +string strToUpperCase ( const string& src ) +{ + string res = src; + + transform( res.begin(), res.end(), res.begin(), CaseChanger < string > ( ctUpper ) ); + + return res; +} + +string strToLowerCase ( const string& src ) +{ + string res = src; + + transform ( res.begin(), res.end(), res.begin(), CaseChanger < string > ( ctLower ) ); + + return res; +} + +uint32_t my_ntohl( const uint32_t val ) +{ + uint8_t* tmp = (uint8_t*) &val; + return tmp[3] + (tmp[2] << 8) + (tmp[1] << 16) + (tmp[0] << 24); +} + +uint16_t my_ntohs( const uint16_t val ) +{ + uint8_t* tmp = (uint8_t*) &val; + return tmp[1] + (tmp[0] << 8); +} + + char* strnstr(const char *s1, const char *s2, size_t len) +{ + size_t l1 = len, l2; + + l2 = strlen(s2); + if (!l2) + return (char *)s1; + while (l1 >= l2) { + l1--; + if (!memcmp(s1, s2, l2)) + return (char *)s1; + s1++; + } + return NULL; +} + +uint32_t random32() +{ + return ((uint32_t) rand() << 16) + rand(); +} diff --git a/libmediation/types/types.h b/libmediation/types/types.h new file mode 100644 index 0000000..8904f7c --- /dev/null +++ b/libmediation/types/types.h @@ -0,0 +1,144 @@ +#ifndef __T_TYPES_H +#define __T_TYPES_H + +#ifdef WIN32 +#include +#else +#include +#endif + +#include +#include + +//class Serializator; + +#if defined _MSC_VER +typedef unsigned __int8 uint8_t; +typedef unsigned __int16 uint16_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int8 int8_t; +typedef __int16 int16_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +#else +#define override +#endif + + +#ifdef WIN32 +#define strcasecmp stricmp +#endif + char* strnstr(const char *s1, const char *s2, size_t len); + +uint64_t my_ntohll( const uint64_t& original ); +uint64_t my_htonll( const uint64_t& original ); +uint32_t my_ntohl( const uint32_t val ); +uint16_t my_ntohs( const uint16_t val ); +#define my_htonl(val) my_ntohl(val) +#define my_htons(val) my_ntohs(val) + +int64_t strToInt64( const char* const ); +uint64_t strToInt64u( const char* const ); +int32_t strToInt32( const char* const); +int32_t strToInt32( const std::string&); +int32_t strToInt32( const char* const, const int radix); +int32_t strWToInt32( const wchar_t* const str ); +int32_t strWToInt32( const wchar_t* const str , const int radix); +uint32_t strWToInt32u( const wchar_t* const str , const int radix); +uint32_t strToInt32u( const char* const , const int radix = 10); +int16_t strToInt16( const char* const ); +uint16_t strToInt16u( const char* const ); +int8_t strToInt8( const char* const ); +uint8_t strToInt8u( const char* const ); +double strToDouble( const char* const ); // 15 +double strWToDouble( const wchar_t* const ); // 15 +bool strToBool( const char* const ); +bool strEndWith(const std::string& str, const std::string& substr); +bool strStartWith(const std::string& str, const std::string& substr); +bool strStartWithW(const std::wstring& str, const std::wstring& substr); +std::string strPadLeft(const std::string& str, size_t newSize, char filler); +std::string strPadRight(const std::string& str, size_t newSize, char filler); + +std::vector splitStr(const char* str, char splitter); +std::vector splitStr ( const std::string& str, const std::string& splitter ); +void splitStr(std::vector& rez, const char* str, char splitter); + + +std::string trimStr(const std::string& value); +std::wstring trimStrW(const std::wstring& value); + +std::string extractFileExt(const std::string& src); +std::string extractFileName(const std::string& src); +std::string extractFileName2(const std::string& src, bool withExt = true ); +std::string extractFilePath(const std::string& src); +std::string closeDirPath(const std::string& src, char delimiter = ' '); + +std::vector splitStrW(const wchar_t* str, wchar_t splitter); +std::vector splitQuotedStr(const char* str, char splitter); + + +std::string int64ToStr( const int64_t& ); +std::string int64uToStr( const uint64_t& ); +std::string int32ToStr( const int32_t&); +std::string int32uToStr( const uint32_t&); +std::string int32ToHex( const int32_t&); +std::string int32uToHex( const uint32_t&); +//! . +/*! + precision = -1, 4 . +*/ +std::string doubleToStr( const double& x, int precision = -1 ); + +std::string int16ToStr( const int16_t& ); +std::string int16uToStr( const uint16_t& ); +std::string int8ToStr( const int8_t& ); +std::string int8uToStr( const uint8_t& ); +void int8uToStr( const uint8_t&, char* const buf ); + +std::string boolToStr( const bool& ); + +// +std::string strToUpperCase( const std::string& src); +std::string strToLowerCase( const std::string& src); + +enum CaseType { ctLower = 0, ctUpper }; + +template < typename Type > +class CaseChanger +{ +public: + + + CaseChanger ( CaseType caseType = ctLower ): + m_case ( caseType ) + {} + + int operator()( Type& elem ) const + { + return 0; + } + + int operator()( char& elem ) const + { + return m_case == ctLower ? tolower ( elem ) : toupper ( elem ); + } + +private: + CaseType m_case; +}; + +typedef uint16_t ip_port_t; + +uint32_t roundDown( const uint32_t& value, const uint32_t& roundVal ); +uint32_t roundUp( const uint32_t& value, const uint32_t& roundVal ); + +//64-bit versions +uint64_t roundDown64( const uint64_t& value, const uint64_t& roundVal ); +uint64_t roundUp64( const uint64_t& value, const uint64_t& roundVal ); + +uint32_t random32(); + +static uint32_t FOUR_CC(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { return my_ntohl((uint32_t(a) << 24) + (uint32_t(b) << 16) + (uint32_t(c) << 8) + uint32_t(d)); } + +#endif //__T_TYPES_H diff --git a/tsMuxer/Makefile b/tsMuxer/Makefile index 2aa4d83..8ed2565 100644 --- a/tsMuxer/Makefile +++ b/tsMuxer/Makefile @@ -7,13 +7,14 @@ ifeq ($(MAKECMDGOALS),release) BUILD=-Os endif +DIRS=../bin ../install CC=g++ DEFINES = -DLINUX -DLIBMEDIATION_API= -DDISABLE_LOG_SUPPORT CFLAGS = -c -fpic -fexceptions -m32 INCPATH = -I../libmediation -I/usr/include/freetype2 STATIC_LIBS = ../libmediation/libmediationl.a LFLAGS = -m32 -LDFLAGS = -lpthread -lrt -lfreetype -m32 +LDFLAGS = -lpthread -lrt -lz -lfreetype -m32 TARGET = ../bin/tsMuxeR SOURCES= ./src/aac.cpp ./src/aacStreamReader.cpp ./src/AbstractDemuxer.cpp ./src/abstractMuxer.cpp ./src/ac3Codec.cpp ./src/ac3StreamReader.cpp \ @@ -26,9 +27,10 @@ SOURCES= ./src/aac.cpp ./src/aacStreamReader.cpp ./src/AbstractDemuxer.cpp ./src ./src/simplePacketizerReader.cpp ./src/singleFileMuxer.cpp ./src/srtStreamReader.cpp ./src/stdafx.cpp ./src/textSubtitles.cpp ./src/textSubtitlesRender.cpp \ ./src/textSubtitlesRenderFT.cpp ./src/tsDemuxer.cpp ./src/tsMuxer.cpp ./src/tsPacket.cpp ./src/utf8Converter.cpp ./src/vc1Parser.cpp ./src/combinedH264Demuxer.cpp - OBJECTS=$(SOURCES:.cpp=.o) +$(shell mkdir -p $(DIRS)) + all: $(SOURCES) $(TARGET) .PHONY : debug release debug: all @@ -47,9 +49,8 @@ clean: install: cp ../bin/tsMuxeR ../install/ cp ../bin/tsMuxerGUI ../install/ - cp ../release_notes.txt ../install/ + cp ../CHANGELOG.md ../install/release_notes.txt upx --lzma ../install/tsMuxeR upx --lzma ../install/tsMuxerGUI - tar -cf ../tsMuxeR.tar -C ../install . - gzip ../tsMuxeR.tar + tar -czf ../tsMuxeR.tar.gz -C ../install . diff --git a/tsMuxer/src/h264StreamReader.cpp b/tsMuxer/src/h264StreamReader.cpp index c01225a..bc899e2 100644 --- a/tsMuxer/src/h264StreamReader.cpp +++ b/tsMuxer/src/h264StreamReader.cpp @@ -108,7 +108,8 @@ CheckStreamRez H264StreamReader::checkStream(uint8_t* buffer, int len) delete sps; return rez; } - m_spsMap.insert(make_pair(sps->seq_parameter_set_id, sps)); + // m_spsMap.insert(make_pair(sps->seq_parameter_set_id, sps)); + m_spsMap.insert(make_pair(sps->seq_parameter_set_id, sps)); if (tmpDescr.empty()) tmpDescr = sps->getStreamDescr(); break; @@ -126,7 +127,8 @@ CheckStreamRez H264StreamReader::checkStream(uint8_t* buffer, int len) delete pps; break; } - m_ppsMap.insert(make_pair(pps->pic_parameter_set_id, pps)); + // m_ppsMap.insert(make_pair(pps->pic_parameter_set_id, pps)); + m_ppsMap.insert(make_pair(pps->pic_parameter_set_id, pps)); break; } case nuSEI: diff --git a/tsMuxer/src/textSubtitlesRenderFT.cpp b/tsMuxer/src/textSubtitlesRenderFT.cpp index 365aafe..771c4f7 100644 --- a/tsMuxer/src/textSubtitlesRenderFT.cpp +++ b/tsMuxer/src/textSubtitlesRenderFT.cpp @@ -185,7 +185,8 @@ int TextSubtitlesRenderFT::loadFont(const string& fontName, FT_Face& face) int error = FT_New_Face( library, fontName.c_str(), 0, &face ); if (error) return error; - m_fontMap.insert(make_pair(fontName, face)); + // m_fontMap.insert(make_pair(fontName, face)); + m_fontMap.insert(make_pair(fontName, face)); } else face = itr->second;