mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-streamdev.git
				synced 2023-10-10 17:16:51 +00:00 
			
		
		
		
	- implemented audio track selection for http
This commit is contained in:
		
							
								
								
									
										5
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| # | ||||
| # Makefile for a Video Disk Recorder plugin | ||||
| # | ||||
| # $Id: Makefile,v 1.2 2005/02/08 17:22:35 lordjaxom Exp $ | ||||
| # $Id: Makefile,v 1.3 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  | ||||
| # The official name of this plugin. | ||||
| # This name will be used in the '-P...' option of VDR to load the plugin. | ||||
| @@ -48,8 +48,7 @@ DEFINES += -D_GNU_SOURCE | ||||
|  | ||||
| COMMONOBJS = common.o i18n.o \ | ||||
| 	\ | ||||
| 	tools/file.o tools/source.o tools/select.o tools/shared.o tools/socket.o \ | ||||
| 	tools/tools.o | ||||
| 	tools/source.o tools/select.o tools/socket.o tools/tools.o | ||||
|  | ||||
| CLIENTOBJS = $(PLUGIN)-client.o \ | ||||
| 	\ | ||||
|   | ||||
							
								
								
									
										40
									
								
								common.c
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								common.c
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: common.c,v 1.2 2005/02/08 15:34:38 lordjaxom Exp $ | ||||
|  *  $Id: common.c,v 1.3 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #include <vdr/channels.h> | ||||
| @@ -47,8 +47,16 @@ char *GetNextLine(char *String, uint Length, uint &Offset) { | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| cChannel *ChannelFromString(char *String) { | ||||
| const cChannel *ChannelFromString(char *String, int *Apid) { | ||||
| 	cChannel *channel = NULL; | ||||
| 	char *ptr, *end; | ||||
| 	int apididx = 0; | ||||
| 	 | ||||
| 	if ((ptr = strrchr(String, '+')) != NULL) { | ||||
| 		*(ptr++) = '\0'; | ||||
| 		apididx = strtoul(ptr, &end, 10); | ||||
| 		Dprintf("found apididx: %d\n", apididx); | ||||
| 	} | ||||
|  | ||||
| 	if (isnumber(String)) { | ||||
| 		int temp = strtol(String, NULL, 10); | ||||
| @@ -67,6 +75,34 @@ cChannel *ChannelFromString(char *String) { | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (channel != NULL && apididx > 0) { | ||||
| 		int apid = 0, index = 1; | ||||
| 		const int *apids = channel->Apids();  | ||||
| 		const int *dpids = channel->Dpids();  | ||||
|  | ||||
| 		for (int i = 0; apids[i] != 0; ++i, ++index) { | ||||
| 			Dprintf("checking apid %d\n", apids[i]); | ||||
| 			if (index == apididx) { | ||||
| 				apid = apids[i]; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (apid == 0) { | ||||
| 			for (int i = 0; dpids[i] != 0; ++i, ++index) { | ||||
| 				Dprintf("checking dpid %d\n", dpids[i]); | ||||
| 				if (index == apididx) { | ||||
| 					apid = dpids[i]; | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		if (Apid != NULL)  | ||||
| 			*Apid = apid; | ||||
| 	} | ||||
|  | ||||
| 	return channel; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								common.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								common.h
									
									
									
									
									
								
							| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: common.h,v 1.3 2005/02/08 15:34:38 lordjaxom Exp $ | ||||
|  *  $Id: common.h,v 1.4 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #ifndef VDR_STREAMDEV_COMMON_H | ||||
| @@ -42,7 +42,7 @@ class cChannel; | ||||
|  | ||||
| char *GetNextLine(char *String, uint Length, uint &Offset); | ||||
|  | ||||
| cChannel *ChannelFromString(char *String); | ||||
| const cChannel *ChannelFromString(char *String, int *Apid = NULL); | ||||
|  | ||||
| /* Disable logging if BUFCOUNT buffer overflows occur within BUFOVERTIME | ||||
|    milliseconds. Enable logging again if there is no error within BUFOVERTIME | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: connectionHTTP.c,v 1.5 2005/02/08 19:54:52 lordjaxom Exp $ | ||||
|  *  $Id: connectionHTTP.c,v 1.6 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #include "server/connectionHTTP.h" | ||||
| @@ -8,6 +8,7 @@ | ||||
|  | ||||
| cConnectionHTTP::cConnectionHTTP(void): cServerConnection("HTTP") { | ||||
| 	m_Channel      = NULL; | ||||
| 	m_Apid         = 0; | ||||
| 	m_ListChannel  = NULL; | ||||
| 	m_LiveStreamer = NULL; | ||||
| 	m_Status       = hsRequest; | ||||
| @@ -56,7 +57,7 @@ bool cConnectionHTTP::Command(char *Cmd) { | ||||
| 			cDevice *device = GetDevice(m_Channel, 0); | ||||
| 			if (device != NULL) { | ||||
| 				device->SwitchChannel(m_Channel, false); | ||||
| 				if (m_LiveStreamer->SetChannel(m_Channel, m_StreamType)) { | ||||
| 				if (m_LiveStreamer->SetChannel(m_Channel, m_StreamType, m_Apid)) { | ||||
| 					m_LiveStreamer->SetDevice(device); | ||||
| 					m_Startup = true; | ||||
| 					if (m_StreamType == stES && (m_Channel->Vpid() == 0  | ||||
| @@ -111,8 +112,9 @@ void cConnectionHTTP::Flushed(void) { | ||||
| } | ||||
|  | ||||
| bool cConnectionHTTP::CmdGET(char *Opts) { | ||||
| 	cChannel *chan; | ||||
| 	const cChannel *chan; | ||||
| 	char *ep; | ||||
| 	int apid = 0; | ||||
|  | ||||
| 	Opts = skipspace(Opts); | ||||
| 	while (*Opts == '/') | ||||
| @@ -138,13 +140,17 @@ bool cConnectionHTTP::CmdGET(char *Opts) { | ||||
| 		; | ||||
| 	*ep = '\0'; | ||||
|  | ||||
| 	Dprintf("before channelfromstring\n"); | ||||
| 	if (strncmp(Opts, "channels.htm", 12) == 0) { | ||||
| 		m_ListChannel = Channels.First(); | ||||
| 		m_Status = hsHeaders; | ||||
| 	} else if ((chan = ChannelFromString(Opts)) != NULL) { | ||||
| 	} else if ((chan = ChannelFromString(Opts, &apid)) != NULL) { | ||||
| 		m_Channel = chan; | ||||
| 		m_Apid = apid; | ||||
| 		Dprintf("Apid is %d\n", apid); | ||||
| 		m_Status = hsHeaders; | ||||
| 	} | ||||
| 	Dprintf("after channelfromstring\n"); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: connectionHTTP.h,v 1.1 2004/12/30 22:44:18 lordjaxom Exp $ | ||||
|  *  $Id: connectionHTTP.h,v 1.2 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #ifndef VDR_STREAMDEV_SERVERS_CONNECTIONHTTP_H | ||||
| @@ -21,8 +21,9 @@ private: | ||||
| 		hsListing, | ||||
| 	}; | ||||
|  | ||||
| 	cChannel               *m_Channel; | ||||
| 	cChannel               *m_ListChannel; | ||||
| 	const cChannel         *m_Channel; | ||||
| 	int                     m_Apid; | ||||
| 	const cChannel         *m_ListChannel; | ||||
| 	cStreamdevLiveStreamer *m_LiveStreamer; | ||||
| 	eStreamType             m_StreamType; | ||||
| 	eHTTPStatus             m_Status; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: connectionVTP.c,v 1.4 2005/02/08 17:22:35 lordjaxom Exp $ | ||||
|  *  $Id: connectionVTP.c,v 1.5 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #include "server/connectionVTP.h" | ||||
| @@ -92,7 +92,7 @@ bool cConnectionVTP::CmdCAPS(char *Opts) { | ||||
| } | ||||
|  | ||||
| bool cConnectionVTP::CmdPROV(char *Opts) { | ||||
| 	cChannel *chan; | ||||
| 	const cChannel *chan; | ||||
| 	int prio; | ||||
| 	char *ep; | ||||
| 	 | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
| #include "remux/ts2es.h" | ||||
| #include "common.h" | ||||
|  | ||||
| // --- cStreamdevLiveReceiver ------------------------------------------------- | ||||
|  | ||||
| cStreamdevLiveReceiver::cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, int Ca,  | ||||
|                                                int Priority, const int *Pids): | ||||
| 		cReceiver(Ca, Priority, 0, Pids), | ||||
| @@ -18,30 +20,29 @@ cStreamdevLiveReceiver::~cStreamdevLiveReceiver() | ||||
| 	Detach(); | ||||
| } | ||||
|  | ||||
| void cStreamdevLiveReceiver::Activate(bool On) | ||||
| { | ||||
| 	m_Streamer->Activate(On); | ||||
| } | ||||
|  | ||||
| void cStreamdevLiveReceiver::Receive(uchar *Data, int Length) { | ||||
| 	int p = m_Streamer->Receive(Data, Length); | ||||
| 	if (p != Length) | ||||
| 		m_Streamer->ReportOverflow(Length - p); | ||||
| } | ||||
|  | ||||
| // --- cStreamdevLiveStreamer ------------------------------------------------- | ||||
|  | ||||
| cStreamdevLiveStreamer::cStreamdevLiveStreamer(int Priority): | ||||
| 		cStreamdevStreamer("streamdev-livestreaming") { | ||||
| 	m_Priority   = Priority; | ||||
| 	m_NumPids    = 0; | ||||
| 	m_StreamType = stTSPIDS; | ||||
| 	m_Channel    = NULL; | ||||
| 	m_Device     = NULL; | ||||
| 	m_Receiver   = NULL; | ||||
| 	m_Remux      = NULL; | ||||
| 	m_PESRemux   = NULL; | ||||
| 		cStreamdevStreamer("streamdev-livestreaming"), | ||||
| 		m_Priority(Priority), | ||||
| 		m_NumPids(0), | ||||
| 		m_StreamType(stTSPIDS), | ||||
| 		m_Channel(NULL), | ||||
| 		m_Device(NULL), | ||||
| 		m_Receiver(NULL), | ||||
| 		m_PESRemux(NULL), | ||||
| 		m_Remux(NULL) | ||||
| { | ||||
| } | ||||
|  | ||||
| cStreamdevLiveStreamer::~cStreamdevLiveStreamer() { | ||||
| cStreamdevLiveStreamer::~cStreamdevLiveStreamer()  | ||||
| { | ||||
| 	Dprintf("Desctructing Live streamer\n"); | ||||
| 	delete m_Receiver; | ||||
| 	delete m_Remux; | ||||
| @@ -50,21 +51,12 @@ cStreamdevLiveStreamer::~cStreamdevLiveStreamer() { | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void cStreamdevLiveStreamer::Detach(void) { | ||||
| 	m_Device->Detach(m_Receiver); | ||||
| } | ||||
|  | ||||
| void cStreamdevLiveStreamer::Attach(void) { | ||||
| 	m_Device->AttachReceiver(m_Receiver); | ||||
| } | ||||
|  | ||||
| void cStreamdevLiveStreamer::Start(cTBSocket *Socket) { | ||||
| 	Dprintf("LIVESTREAMER START\n"); | ||||
| 	cStreamdevStreamer::Start(Socket); | ||||
| } | ||||
|  | ||||
| bool cStreamdevLiveStreamer::SetPid(int Pid, bool On) { | ||||
| bool cStreamdevLiveStreamer::SetPid(int Pid, bool On)  | ||||
| { | ||||
| 	int idx; | ||||
|  | ||||
| 	if (Pid == 0) | ||||
| 		return true; | ||||
| 	 | ||||
| 	if (On) { | ||||
| 		for (idx = 0; idx < m_NumPids; ++idx) { | ||||
| @@ -100,7 +92,7 @@ bool cStreamdevLiveStreamer::SetPid(int Pid, bool On) { | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType)  | ||||
| bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid)  | ||||
| { | ||||
| 	Dprintf("Initializing Remuxer for full channel transfer\n"); | ||||
| 	printf("ca pid: %d\n", Channel->Ca()); | ||||
| @@ -109,29 +101,38 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str | ||||
| 	switch (m_StreamType) { | ||||
| 	case stES:  | ||||
| 		{ | ||||
| 			int pid = ISRADIO(Channel) ? Channel->Apid(0) : Channel->Vpid(); | ||||
| 			int pid = ISRADIO(m_Channel) ? m_Channel->Apid(0) : m_Channel->Vpid(); | ||||
| 			if (Apid != 0) | ||||
| 				pid = Apid; | ||||
| 			m_Remux = new cTS2ESRemux(pid); | ||||
| 			return SetPid(pid, true); | ||||
| 		} | ||||
|  | ||||
| 	case stPES:  | ||||
| 		m_PESRemux = new cRemux(Channel->Vpid(), Channel->Apids(), Channel->Dpids(),  | ||||
| 		                        Channel->Spids(), false); | ||||
| 		return SetPid(Channel->Vpid(),  true) | ||||
| 		    && SetPid(Channel->Apid(0), true) | ||||
| 		    && SetPid(Channel->Apid(1), true) | ||||
| 		    && SetPid(Channel->Dpid(0), true); | ||||
| 		Dprintf("PES\n"); | ||||
| 		m_PESRemux = new cRemux(m_Channel->Vpid(), m_Channel->Apids(), m_Channel->Dpids(),  | ||||
| 								m_Channel->Spids(), false); | ||||
| 		if (Apid != 0) | ||||
| 			return SetPid(m_Channel->Vpid(),  true) | ||||
| 			    && SetPid(Apid, true); | ||||
| 		else | ||||
| 			return SetPid(m_Channel->Vpid(),  true) | ||||
| 			    && SetPid(m_Channel->Apid(0), true) | ||||
| 			    && SetPid(m_Channel->Dpid(0), true); | ||||
|  | ||||
| 	case stPS:   | ||||
| 		m_Remux = new cTS2PSRemux(Channel->Vpid(), Channel->Apid(0), 0, 0, 0, true); | ||||
| 		return SetPid(Channel->Vpid(),  true) | ||||
| 		    && SetPid(Channel->Apid(0), true); | ||||
| 		m_Remux = new cTS2PSRemux(m_Channel->Vpid(), m_Channel->Apid(0), 0, 0, 0, true); | ||||
| 		return SetPid(m_Channel->Vpid(),  true) | ||||
| 		    && SetPid(m_Channel->Apid(0), true); | ||||
|  | ||||
| 	case stTS: | ||||
| 		return SetPid(Channel->Vpid(),  true) | ||||
| 		    && SetPid(Channel->Apid(0), true) | ||||
| 		    && SetPid(Channel->Apid(1), true) | ||||
| 		    && SetPid(Channel->Dpid(0), true); | ||||
| 		if (Apid != 0) | ||||
| 			return SetPid(m_Channel->Vpid(),  true) | ||||
| 			    && SetPid(Apid, true); | ||||
| 		else | ||||
| 			return SetPid(m_Channel->Vpid(),  true) | ||||
| 			    && SetPid(m_Channel->Apid(0), true) | ||||
| 			    && SetPid(m_Channel->Dpid(0), true); | ||||
|  | ||||
| 	case stTSPIDS: | ||||
| 		Dprintf("pid streaming mode\n"); | ||||
| @@ -140,8 +141,8 @@ bool cStreamdevLiveStreamer::SetChannel(const cChannel *Channel, eStreamType Str | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool cStreamdevLiveStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask,  | ||||
| 		bool On) { | ||||
| bool cStreamdevLiveStreamer::SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On)  | ||||
| { | ||||
| #if 0 | ||||
| 	Dprintf("setting filter\n"); | ||||
| 	if (On) { | ||||
| @@ -195,49 +196,19 @@ void cStreamdevLiveStreamer::Del(int Count) | ||||
| 	case stTS: | ||||
| 	case stTSPIDS: | ||||
| 		cStreamdevStreamer::Del(Count); | ||||
| 		break; | ||||
|  | ||||
| 	case stPES: | ||||
| 		m_PESRemux->Del(Count); | ||||
| 		break; | ||||
|  | ||||
| 	default: | ||||
| 		abort(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // TODO: Remuxer einbinden | ||||
| #if 0 | ||||
| uchar *cStreamdevLiveStreamer::Process(const uchar *Data, int &Count, int &Result) { | ||||
| 	uchar *remuxed = m_Remux != NULL ? m_Remux->Process(Data, Count, Result) | ||||
| 			: cStreamdevStreamer::Process(Data, Count, Result); | ||||
| 	if (remuxed) { | ||||
| 		/*if (Socket()->Type() == SOCK_DGRAM) { | ||||
| 			free(m_Buffer); | ||||
| 			Result += 12; | ||||
| 			m_Buffer = MALLOC(uchar, Result); | ||||
| 			m_Buffer[0] = 0x01; | ||||
| 			m_Buffer[1] = 0x02; | ||||
| 			m_Buffer[2] = 0x03; | ||||
| 			m_Buffer[3] = 0x04; | ||||
| 			m_Buffer[4] = (Result & 0xff000000) >> 24; | ||||
| 			m_Buffer[5] = (Result & 0xff0000) >> 16; | ||||
| 			m_Buffer[6] = (Result & 0xff00) >> 8; | ||||
| 			m_Buffer[7] = (Result & 0xff); | ||||
| 			m_Buffer[8] = (m_Sequence & 0xff000000) >> 24; | ||||
| 			m_Buffer[9] = (m_Sequence & 0xff0000) >> 16; | ||||
| 			m_Buffer[10] = (m_Sequence & 0xff00) >> 8; | ||||
| 			m_Buffer[11] = (m_Sequence & 0xff); | ||||
| 			memcpy(m_Buffer + 12, Data, Result - 12); | ||||
| 			if (m_Sequence++ == 0x7fffffff) | ||||
| 				m_Sequence = 0; | ||||
| 			return m_Buffer; | ||||
| 		}*/ | ||||
| 		return remuxed; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| std::string cStreamdevLiveStreamer::Report(void) { | ||||
| std::string cStreamdevLiveStreamer::Report(void)  | ||||
| { | ||||
| 	std::string result; | ||||
|  | ||||
| 	if (m_Device != NULL) | ||||
|   | ||||
| @@ -8,13 +8,11 @@ | ||||
| #include "server/livefilter.h" | ||||
| #include "common.h" | ||||
|  | ||||
| #if MAXRECEIVEPIDS < 16 | ||||
| #	error Too few receiver pids allowed! Please contact sascha@akv-soft.de! | ||||
| #endif | ||||
|  | ||||
| class cTSRemux; | ||||
| class cRemux; | ||||
|  | ||||
| // --- cStreamdevLiveReceiver ------------------------------------------------- | ||||
|  | ||||
| class cStreamdevLiveReceiver: public cReceiver { | ||||
| 	friend class cStreamdevLiveStreamer; | ||||
|  | ||||
| @@ -26,11 +24,12 @@ protected: | ||||
| 	virtual void Receive(uchar *Data, int Length); | ||||
|  | ||||
| public: | ||||
| 	cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, int Ca, int Priority, | ||||
| 	                       const int *Pids); | ||||
| 	cStreamdevLiveReceiver(cStreamdevLiveStreamer *Streamer, int Ca, int Priority, const int *Pids); | ||||
| 	virtual ~cStreamdevLiveReceiver(); | ||||
| }; | ||||
|  | ||||
| // --- cStreamdevLiveStreamer ------------------------------------------------- | ||||
|  | ||||
| class cStreamdevLiveStreamer: public cStreamdevStreamer { | ||||
| private: | ||||
| 	int                     m_Priority; | ||||
| @@ -42,7 +41,6 @@ private: | ||||
| 	cStreamdevLiveReceiver *m_Receiver; | ||||
| 	cRemux                 *m_PESRemux; | ||||
| 	cTSRemux               *m_Remux; | ||||
| 	uchar                  *m_Buffer; | ||||
|  | ||||
| public: | ||||
| 	cStreamdevLiveStreamer(int Priority); | ||||
| @@ -50,20 +48,26 @@ public: | ||||
|  | ||||
| 	void SetDevice(cDevice *Device) { m_Device = Device; } | ||||
| 	bool SetPid(int Pid, bool On); | ||||
| 	bool SetChannel(const cChannel *Channel, eStreamType StreamType); | ||||
| 	bool SetChannel(const cChannel *Channel, eStreamType StreamType, int Apid = 0); | ||||
| 	bool SetFilter(u_short Pid, u_char Tid, u_char Mask, bool On); | ||||
| 	 | ||||
| 	virtual int Put(const uchar *Data, int Count); | ||||
| 	virtual uchar *Get(int &Count); | ||||
| 	virtual void Del(int Count); | ||||
|  | ||||
| 	virtual void Detach(void); | ||||
| 	virtual void Attach(void); | ||||
| 	virtual void Attach(void) { Dprintf("attach %p\n", m_Device);m_Device->AttachReceiver(m_Receiver); } | ||||
| 	virtual void Detach(void) { m_Device->Detach(m_Receiver); } | ||||
|  | ||||
| 	virtual void Start(cTBSocket *Socket); | ||||
| 	 | ||||
| 	// Statistical purposes: | ||||
| 	virtual std::string Report(void); | ||||
| }; | ||||
|  | ||||
| // --- cStreamdevLiveReceiver reverse inlines --------------------------------- | ||||
|  | ||||
| inline void cStreamdevLiveReceiver::Activate(bool On)  | ||||
| {  | ||||
| 	Dprintf("LiveReceiver->Activate()\n"); | ||||
| 	m_Streamer->Activate(On);  | ||||
| } | ||||
|  | ||||
| #endif // VDR_STREAMDEV_LIVESTREAMER_H | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: streamer.c,v 1.5 2005/02/09 19:47:09 lordjaxom Exp $ | ||||
|  *  $Id: streamer.c,v 1.6 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #include <vdr/ringbuffer.h> | ||||
| @@ -13,6 +13,8 @@ | ||||
| #include "tools/socket.h" | ||||
| #include "common.h" | ||||
|  | ||||
| // --- cStreamdevWriter ------------------------------------------------------- | ||||
|  | ||||
| cStreamdevWriter::cStreamdevWriter(cTBSocket *Socket, cStreamdevStreamer *Streamer): | ||||
| 		cThread("streamdev-writer"), | ||||
| 		m_Streamer(Streamer), | ||||
| @@ -29,6 +31,7 @@ cStreamdevWriter::~cStreamdevWriter() | ||||
|  | ||||
| void cStreamdevWriter::Action(void) | ||||
| { | ||||
| 	Dprintf("Writer start\n"); | ||||
| 	int max = 0; | ||||
| 	m_Active = true; | ||||
| 	while (m_Active) { | ||||
| @@ -49,13 +52,15 @@ void cStreamdevWriter::Action(void) | ||||
| 	Dprintf("Max. Transmit Blocksize was: %d\n", max); | ||||
| } | ||||
|  | ||||
| // --- cStreamdevStreamer ----------------------------------------------------- | ||||
|  | ||||
| cStreamdevStreamer::cStreamdevStreamer(const char *Name): | ||||
| 		cThread(Name), | ||||
| 		m_Active(false), | ||||
| 		m_Writer(NULL), | ||||
| 		m_RingBuffer(new cRingBufferLinear(STREAMERBUFSIZE, TS_SIZE * 2, true,  | ||||
| 	                                       "streamdev-streamer")), | ||||
| 		m_SendBuffer(new cRingBufferLinear(WRITERBUFSIZE, MAXTRANSMITBLOCKSIZE)) | ||||
| 		m_SendBuffer(new cRingBufferLinear(WRITERBUFSIZE, TS_SIZE * 2)) | ||||
| { | ||||
| 	m_RingBuffer->SetTimeouts(0, 100); | ||||
| 	m_SendBuffer->SetTimeouts(0, 100); | ||||
| @@ -71,12 +76,14 @@ cStreamdevStreamer::~cStreamdevStreamer() | ||||
|  | ||||
| void cStreamdevStreamer::Start(cTBSocket *Socket)  | ||||
| { | ||||
| 	Dprintf("start streamer\n"); | ||||
| 	m_Writer = new cStreamdevWriter(Socket, this); | ||||
| 	Attach(); | ||||
| } | ||||
|  | ||||
| void cStreamdevStreamer::Activate(bool On)  | ||||
| { | ||||
| 	Dprintf("activate streamer\n"); | ||||
| 	if (On && !m_Active) { | ||||
| 		m_Writer->Start(); | ||||
| 		cThread::Start(); | ||||
| @@ -92,21 +99,6 @@ void cStreamdevStreamer::Stop(void) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int cStreamdevStreamer::Put(const uchar *Data, int Count) | ||||
| { | ||||
| 	return m_SendBuffer->Put(Data, Count); | ||||
| } | ||||
|  | ||||
| uchar *cStreamdevStreamer::Get(int &Count) | ||||
| { | ||||
| 	return m_SendBuffer->Get(Count); | ||||
| } | ||||
|  | ||||
| void cStreamdevStreamer::Del(int Count) | ||||
| { | ||||
| 	return m_SendBuffer->Del(Count); | ||||
| } | ||||
|  | ||||
| void cStreamdevStreamer::Action(void)  | ||||
| { | ||||
| 	int max = 0; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  *  $Id: streamer.h,v 1.3 2005/02/08 19:54:52 lordjaxom Exp $ | ||||
|  *  $Id: streamer.h,v 1.4 2005/02/10 22:24:26 lordjaxom Exp $ | ||||
|  */ | ||||
|   | ||||
| #ifndef VDR_STREAMDEV_STREAMER_H | ||||
| @@ -12,10 +12,11 @@ | ||||
| class cTBSocket; | ||||
| class cStreamdevStreamer; | ||||
|  | ||||
| #define MAXTRANSMITBLOCKSIZE TS_SIZE*10 | ||||
| #define STREAMERBUFSIZE MEGABYTE(4) | ||||
| #define WRITERBUFSIZE KILOBYTE(192) | ||||
|  | ||||
| // --- cStreamdevWriter ------------------------------------------------------- | ||||
|  | ||||
| class cStreamdevWriter: public cThread { | ||||
| private: | ||||
| 	cStreamdevStreamer *m_Streamer; | ||||
| @@ -30,6 +31,8 @@ public: | ||||
| 	virtual ~cStreamdevWriter(); | ||||
| }; | ||||
|  | ||||
| // --- cStreamdevStreamer ----------------------------------------------------- | ||||
|  | ||||
| class cStreamdevStreamer: public cThread { | ||||
| private: | ||||
| 	bool               m_Active; | ||||
| @@ -40,8 +43,6 @@ private: | ||||
| protected: | ||||
| 	virtual void Action(void); | ||||
|  | ||||
| 	//const cTBSocket *Socket(void) const { return m_Socket; } | ||||
|  | ||||
| public: | ||||
| 	cStreamdevStreamer(const char *Name); | ||||
| 	virtual ~cStreamdevStreamer(); | ||||
| @@ -53,9 +54,9 @@ public: | ||||
| 	int Receive(uchar *Data, int Length) { return m_RingBuffer->Put(Data, Length); } | ||||
| 	void ReportOverflow(int Bytes) { m_RingBuffer->ReportOverflow(Bytes); } | ||||
| 	 | ||||
| 	virtual int Put(const uchar *Data, int Count); | ||||
| 	virtual uchar *Get(int &Count); | ||||
| 	virtual void Del(int Count); | ||||
| 	virtual int Put(const uchar *Data, int Count) { return m_SendBuffer->Put(Data, Count); } | ||||
| 	virtual uchar *Get(int &Count) { return m_SendBuffer->Get(Count); } | ||||
| 	virtual void Del(int Count) { m_SendBuffer->Del(Count); } | ||||
|  | ||||
| 	virtual void Detach(void) = 0; | ||||
| 	virtual void Attach(void) = 0; | ||||
|   | ||||
							
								
								
									
										96
									
								
								tools/file.c
									
									
									
									
									
								
							
							
						
						
									
										96
									
								
								tools/file.c
									
									
									
									
									
								
							| @@ -1,96 +0,0 @@ | ||||
| #include "tools/file.h" | ||||
|  | ||||
| #include <vdr/tools.h> | ||||
| #include <sys/stat.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| cTBFile::cTBFile(void) { | ||||
| } | ||||
|  | ||||
| cTBFile::~cTBFile() { | ||||
| 	Close(); | ||||
| } | ||||
|  | ||||
| bool cTBFile::Open(const std::string &Filename, int Mode, mode_t Attribs) { | ||||
| 	int filed; | ||||
|  | ||||
| 	if (IsOpen()) Close(); | ||||
|  | ||||
| 	if ((filed = ::open(Filename.c_str(), Mode, Attribs)) == -1) | ||||
| 		return false; | ||||
|  | ||||
| 	if (!cTBSource::Open(filed)) | ||||
| 		return false; | ||||
|  | ||||
| 	m_Filename = Filename; | ||||
| 	m_Anonymous = false; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool cTBFile::Open(uint Fileno) { | ||||
| 	if (IsOpen()) Close(); | ||||
|  | ||||
| 	if (!cTBSource::Open(Fileno)) | ||||
| 		return false; | ||||
|  | ||||
| 	m_Filename = (std::string)"<&" + (const char*)itoa(Fileno) + ">"; | ||||
| 	m_Anonymous = true; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool cTBFile::Close(void) { | ||||
| 	bool ret = true; | ||||
|  | ||||
| 	if (!IsOpen()) | ||||
| 		ERRNUL(EBADF); | ||||
|  | ||||
| 	if (::close(*this) == -1) | ||||
| 		ret = false; | ||||
|  | ||||
| 	if (!cTBSource::Close()) | ||||
| 		ret = false; | ||||
|  | ||||
| 	m_Filename = ""; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| bool cTBFile::Unlink(void) const { | ||||
| 	if (m_Filename == "") | ||||
| 		ERRNUL(ENOENT); | ||||
|  | ||||
| 	if (!IsOpen()) | ||||
| 		ERRNUL(EBADF); | ||||
|  | ||||
| 	if (m_Anonymous) | ||||
| 		ERRNUL(EINVAL); | ||||
|  | ||||
| 	return cTBFile::Unlink(m_Filename); | ||||
| } | ||||
|  | ||||
| bool cTBFile::Unlink(const std::string &Filename) { | ||||
| 	return (::unlink(Filename.c_str()) != -1); | ||||
| } | ||||
|  | ||||
| ssize_t cTBFile::Size(void) const { | ||||
| 	struct stat buf; | ||||
| 	 | ||||
| 	if (!IsOpen()) | ||||
| 		ERRSYS(EBADF); | ||||
|  | ||||
| 	if (fstat(*this, &buf) == -1) | ||||
| 		return -1; | ||||
|  | ||||
| 	return buf.st_size; | ||||
| } | ||||
|  | ||||
| ssize_t cTBFile::Size(const std::string &Filename) { | ||||
| 	struct stat buf; | ||||
| 	 | ||||
| 	if (stat(Filename.c_str(), &buf) == -1) | ||||
| 		return -1; | ||||
|  | ||||
| 	return buf.st_size; | ||||
| } | ||||
							
								
								
									
										100
									
								
								tools/file.h
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								tools/file.h
									
									
									
									
									
								
							| @@ -1,100 +0,0 @@ | ||||
| #ifndef TOOLBOX_FILE_H | ||||
| #define TOOLBOX_FILE_H | ||||
|  | ||||
| #include "tools/tools.h" | ||||
| #include "tools/source.h" | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
| #include <string> | ||||
|  | ||||
| /* cTBFile provides a cTBSource-derived interface for input and output on UNIX  | ||||
|    files. */ | ||||
|  | ||||
| class cTBFile: public cTBSource { | ||||
| private: | ||||
| 	bool m_Anonymous; | ||||
| 	std::string m_Filename; | ||||
|  | ||||
| 	/* Unhide and forbid baseclass method */ | ||||
| 	virtual bool Open(int Fd, bool IsUnixFd = false) { return false; } | ||||
|  | ||||
| public: | ||||
| 	cTBFile(void); | ||||
| 	virtual ~cTBFile(); | ||||
|  | ||||
| 	/* enum eFileType represents the modes a file can be opened with. The full | ||||
| 	   open mode is one of the first three, maybe or'ed with one of the others. | ||||
| 	   */ | ||||
| 	enum eFileType { | ||||
| 		ReadOnly  = O_RDONLY, | ||||
| 		WriteOnly = O_WRONLY, | ||||
| 		ReadWrite = O_RDWR, | ||||
| 		 | ||||
| 		Create    = O_CREAT, | ||||
| 		Exclude   = O_EXCL, | ||||
| 		Truncate  = O_TRUNC, | ||||
| 		Append    = O_APPEND | ||||
| 	}; | ||||
|  | ||||
| 	/* See cTBSource::SysRead()  | ||||
| 	   Reimplemented for UNIX files. */ | ||||
| 	virtual ssize_t SysRead(void *Buffer, size_t Length) const; | ||||
|  | ||||
| 	/* See cTBSource::SysWrite()  | ||||
| 	   Reimplemented for UNIX files. */ | ||||
| 	virtual ssize_t SysWrite(const void *Buffer, size_t Length) const; | ||||
|  | ||||
| 	/* Open() opens the file referred to by Filename according to the given  | ||||
| 	   Mode. If the file is created, it receives the attributes given by  | ||||
| 	   Attribs, defaulting to rw-------. Returns true on success and false on | ||||
| 	   error, setting errno appropriately. */ | ||||
| 	virtual bool Open(const std::string &Filename, int Mode,  | ||||
| 			mode_t Attribs = S_IRUSR + S_IWUSR); | ||||
|  | ||||
| 	/* Open() associates this file object with Fileno. Fileno must refer to a | ||||
| 	   previously opened file descriptor, which will be set non-blocking by | ||||
| 	   this call. If successful, true is returned, false otherwise and errno | ||||
| 	   is set appropriately. */ | ||||
| 	virtual bool Open(uint Fileno); | ||||
|  | ||||
| 	/* Close() closes the associated file descriptor and releases all  | ||||
| 	   structures. Returns true on success and false otherwise, setting errno | ||||
| 	   appropriately. The object is in the closed state afterwards, even if | ||||
| 	   an error occured. */ | ||||
| 	virtual bool Close(void); | ||||
| 	 | ||||
| 	/* Unlink() unlinks (deletes) the associated file from the underlying  | ||||
| 	   filesystem. Returns true on success and false otherwise, setting errno | ||||
| 	   appropriately. The file must be opened by filename to use this. */ | ||||
| 	virtual bool Unlink(void) const; | ||||
|  | ||||
| 	/* Unlink() unlinks (deletes) the file referred to by Filename from the | ||||
| 	   underlying filesystem. Returns true on success and false otherwise,  | ||||
| 	   setting errno appropriately. */ | ||||
| 	static  bool Unlink(const std::string &Filename); | ||||
|  | ||||
| 	/* Size() returns the current size of the associated file. Returns the  | ||||
| 	   exact size of the file in bytes. Returns -1 on error, setting errno to | ||||
| 	   an appropriate value. */ | ||||
| 	virtual ssize_t Size(void) const; | ||||
|  | ||||
| 	/* Size() returns the current size of the file referred to by Filename. | ||||
| 	   Symbolic links are followed (the size of the link-target is returned). | ||||
| 	   Returns the exact size of the file in bytes. Returns -1 on error,  | ||||
| 	   setting errno to an appropriate value. */ | ||||
| 	static  ssize_t Size(const std::string &Filename); | ||||
| }; | ||||
|  | ||||
| inline ssize_t cTBFile::SysRead(void *Buffer, size_t Length) const { | ||||
| 	return ::read(*this, Buffer, Length); | ||||
| } | ||||
|  | ||||
| inline ssize_t cTBFile::SysWrite(const void *Buffer, size_t Length) const { | ||||
| 	return ::write(*this, Buffer, Length); | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif // TOOLBOX_FILE_H | ||||
| @@ -1,90 +0,0 @@ | ||||
| #include "tools/shared.h" | ||||
|  | ||||
| #include <errno.h> | ||||
| #include <stddef.h> | ||||
| #include <string.h> | ||||
|  | ||||
| cSharedData *cSharedData::Construct (size_t Length) { | ||||
| 	size_t reallength = sizeof(cSharedData) + Length; | ||||
| 	cSharedData *ret = (cSharedData*)new char[reallength]; | ||||
|  | ||||
| 	ret->m_Length = Length; | ||||
| 	ret->m_NumRefs = 0; | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| cTBShared::cTBShared(void) { | ||||
| 	m_Buffer = NULL; | ||||
| } | ||||
|  | ||||
| cTBShared::cTBShared (const cTBShared &src) { | ||||
| 	m_Buffer = src.m_Buffer; | ||||
| 	if (m_Buffer) | ||||
| 		++*m_Buffer; | ||||
| } | ||||
|  | ||||
| cTBShared::~cTBShared () { | ||||
| 	if (m_Buffer) | ||||
| 		Release(); | ||||
| } | ||||
|  | ||||
| void cTBShared::Clear () { | ||||
| 	if (m_Buffer) | ||||
| 		Release(); | ||||
| 	m_Buffer = 0; | ||||
| } | ||||
|  | ||||
| void cTBShared::Set (const cTBShared &src) { | ||||
| 	if (m_Buffer) | ||||
| 		Release(); | ||||
|  | ||||
| 	m_Buffer = src.m_Buffer; | ||||
| 	if (m_Buffer) | ||||
| 		++*m_Buffer; | ||||
| } | ||||
|  | ||||
| void cTBShared::Release () { | ||||
| 	CHECK_PTR(m_Buffer); | ||||
|  | ||||
| 	if (--*m_Buffer == 0) | ||||
| 		delete[] (char*)m_Buffer; | ||||
|  | ||||
| 	m_Buffer = 0; | ||||
| } | ||||
|  | ||||
| void cTBShared::Release(uint newsize) { | ||||
| 	CHECK_PTR(m_Buffer); | ||||
|  | ||||
| 	Allocate(newsize, true); | ||||
| } | ||||
|  | ||||
| void cTBShared::Exclusive () { | ||||
| 	CHECK_PTR(m_Buffer); | ||||
|  | ||||
| 	if (m_Buffer->Refs() == 1) | ||||
| 		return; | ||||
|  | ||||
| 	cSharedData *copy = cSharedData::Construct(m_Buffer->Size()); | ||||
| 	memcpy(*copy, *m_Buffer, m_Buffer->Size()); | ||||
|  | ||||
| 	Release(); | ||||
|  | ||||
| 	m_Buffer = copy; | ||||
| 	++*m_Buffer; | ||||
| } | ||||
|  | ||||
| void cTBShared::Allocate (size_t len, bool keep /* = false */) { | ||||
| 	if (m_Buffer && (m_Buffer->Refs() == 1) && (m_Buffer->Size() == len)) | ||||
| 		return; | ||||
|  | ||||
| 	cSharedData *newBuffer = cSharedData::Construct(len); | ||||
| 	if (m_Buffer) { | ||||
| 		if (keep) | ||||
| 			memcpy(*newBuffer, *m_Buffer, len < m_Buffer->Size() ? len : m_Buffer->Size()); | ||||
|  | ||||
| 		Release(); | ||||
| 	} | ||||
| 	m_Buffer = newBuffer; | ||||
| 	++*m_Buffer; | ||||
| } | ||||
|  | ||||
| @@ -1,65 +0,0 @@ | ||||
| #ifndef TOOLBOX_SHARED_H | ||||
| #define TOOLBOX_SHARED_H | ||||
|  | ||||
| #include "tools/tools.h" | ||||
|  | ||||
| struct cSharedData { | ||||
| private: | ||||
| 	uint  m_Length; | ||||
| 	uint  m_NumRefs; | ||||
|  | ||||
| public: | ||||
| 	static cSharedData *Construct (size_t Length); | ||||
| 	 | ||||
| 	operator char * () { return this ? (char*)(this+1) : 0; } | ||||
|  | ||||
| 	uint operator++ () { return ++m_NumRefs; } | ||||
| 	uint operator-- () { return --m_NumRefs; } | ||||
|  | ||||
| 	size_t Size() const { return m_Length; } | ||||
|  | ||||
| 	uint Refs () const { return m_NumRefs; } | ||||
| }; | ||||
|  | ||||
| class cTBShared { | ||||
| private: | ||||
| 	cSharedData *m_Buffer; | ||||
|  | ||||
| protected: | ||||
| 	void Release(); | ||||
| 	void Exclusive(); | ||||
| 	void Allocate(size_t len, bool keep = false); | ||||
| 	 | ||||
| 	char *Buffer() const { return m_Buffer ? (char*)*m_Buffer : (char*)0; } | ||||
| 	 | ||||
| public: | ||||
| 	cTBShared (void); | ||||
| 	cTBShared (const cTBShared &src); | ||||
| 	virtual ~cTBShared (); | ||||
|  | ||||
| 	virtual void  Clear    (); | ||||
| 	virtual void  Set      (const cTBShared &src); | ||||
| 	 | ||||
| 	virtual char *Buffer   (uint size); | ||||
| 	virtual void  Release  (uint newsize); | ||||
|  | ||||
| 	cTBShared &operator= (const cTBShared &src) { Set(src); return *this; } | ||||
|  | ||||
| 	operator const void * () const { return m_Buffer ? (const void*)*m_Buffer : (const void*)0; } | ||||
| 	operator void * () const { return m_Buffer ? (void*)*m_Buffer : (void*)0; } | ||||
|  | ||||
| 	operator const char * () const { return m_Buffer ? (const char*)*m_Buffer : (const char*)0; } | ||||
|  | ||||
| 	size_t Size() const { return m_Buffer ? m_Buffer->Size() : 0; } | ||||
| 	size_t Length() const { return m_Buffer ? m_Buffer->Size() : 0; } | ||||
|  | ||||
| 	// friend cSource &operator>> (cSource &dest, cTBShared &str); | ||||
| }; | ||||
|  | ||||
| inline char *cTBShared::Buffer(uint size) { | ||||
| 	if ((!m_Buffer) || (m_Buffer->Refs() > 1) || (size > m_Buffer->Size())) | ||||
| 		Allocate(size, true); | ||||
| 	return Buffer(); | ||||
| } | ||||
|  | ||||
| #endif // TOOLBOX_SHARED_H | ||||
							
								
								
									
										454
									
								
								tools/string.c
									
									
									
									
									
								
							
							
						
						
									
										454
									
								
								tools/string.c
									
									
									
									
									
								
							| @@ -1,454 +0,0 @@ | ||||
| #include "tools/string.h" | ||||
| #ifdef TOOLBOX_REGEX | ||||
| #	include "tools/regex.h" | ||||
| #endif | ||||
|  | ||||
| #include <string.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <ctype.h> | ||||
| #include <limits.h> | ||||
| #include <math.h> | ||||
| #include <errno.h> | ||||
|  | ||||
| const cTBString cTBString::Null; | ||||
|  | ||||
| cTBString::cTBString():  | ||||
| 		cTBShared(), | ||||
| 		m_StringLen(0) { | ||||
| } | ||||
|  | ||||
| cTBString::cTBString(const cTBString &src):  | ||||
| 		cTBShared(src), | ||||
| 		m_StringLen(src.m_StringLen) { | ||||
| } | ||||
|  | ||||
| cTBString::cTBString(const char *src) { | ||||
| 	Set(src); | ||||
| } | ||||
|  | ||||
| cTBString::cTBString(const uchar *src) { | ||||
| 	Set(src); | ||||
| } | ||||
|  | ||||
| cTBString::cTBString(char src) { | ||||
| 	Set(src); | ||||
| } | ||||
|  | ||||
| cTBString::~cTBString () { | ||||
| } | ||||
|  | ||||
| void cTBString::Release(uint newsize) { | ||||
| 	m_StringLen = newsize; | ||||
| 	cTBShared::Release(m_StringLen + 1); | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Clear() { | ||||
| 	cTBShared::Clear(); | ||||
| 	m_StringLen = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Set(const cTBString &String) { | ||||
| 	cTBShared::Set(String); | ||||
| 	m_StringLen = String.m_StringLen; | ||||
| } | ||||
|  | ||||
| void cTBString::Set (const char *String) { | ||||
| 	m_StringLen = strlen(String); | ||||
| 	Allocate(m_StringLen + 1); | ||||
|  | ||||
| 	memcpy(Buffer(), String, m_StringLen); | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Set (const uchar *String) { | ||||
| 	Set((const char*)String); | ||||
| } | ||||
|  | ||||
| void cTBString::Set (char Character) { | ||||
| 	m_StringLen = 1; | ||||
| 	Allocate(m_StringLen + 1); | ||||
|  | ||||
| 	Buffer()[0] = Character; | ||||
| 	Buffer()[1] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Fill(char Character, int Length) { | ||||
| 	if (Length != -1) { | ||||
| 		m_StringLen = Length; | ||||
| 		Allocate(m_StringLen + 1); | ||||
| 	} | ||||
| 	memset(Buffer(), Character, m_StringLen); | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Append(const cTBString &src) { | ||||
| 	Allocate(m_StringLen + src.m_StringLen + 1, true); | ||||
|  | ||||
| 	memcpy(Buffer() + m_StringLen, src.Buffer(), src.m_StringLen); | ||||
| 	m_StringLen += src.m_StringLen; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Append(const char *src) { | ||||
| 	uint len = strlen(src); | ||||
| 	Allocate(m_StringLen + len + 1, true); | ||||
|  | ||||
| 	memcpy(Buffer() + m_StringLen, src, len); | ||||
| 	m_StringLen += len; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Append(char src) { | ||||
| 	Allocate(m_StringLen + 2, true); | ||||
|  | ||||
| 	Buffer()[m_StringLen] = src; | ||||
| 	++m_StringLen; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Prepend(const cTBString &src) { | ||||
| 	Allocate(m_StringLen + src.m_StringLen + 1, true); | ||||
|  | ||||
| 	memmove(Buffer() + src.m_StringLen, Buffer(), m_StringLen); | ||||
| 	memcpy(Buffer(), src.Buffer(), src.m_StringLen); | ||||
| 	m_StringLen += src.m_StringLen; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Prepend(const char *src) { | ||||
| 	uint len = strlen(src); | ||||
| 	Allocate(m_StringLen + len + 1, true); | ||||
|  | ||||
| 	memmove(Buffer() + len, Buffer(), m_StringLen); | ||||
| 	memcpy(Buffer(), src, len); | ||||
| 	m_StringLen += len; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Prepend(char src) { | ||||
| 	Allocate(m_StringLen + 2, true); | ||||
|  | ||||
| 	memmove(Buffer() + 1, Buffer(), m_StringLen); | ||||
| 	Buffer()[0] = src; | ||||
| 	Buffer()[++m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Insert(uint Index, const cTBString &String) { | ||||
| 	Allocate(m_StringLen + String.m_StringLen + 1, true); | ||||
|  | ||||
| 	memmove(Buffer() + Index + String.m_StringLen, Buffer() + Index, m_StringLen - Index); | ||||
| 	memcpy(Buffer() + Index, String.Buffer(), String.m_StringLen); | ||||
| 	m_StringLen += String.m_StringLen; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Insert(uint Index, const char *String) { | ||||
| 	uint len = strlen(String); | ||||
| 	Allocate(m_StringLen + len + 1, true); | ||||
|  | ||||
| 	memmove(Buffer() + Index + len, Buffer() + Index, m_StringLen - Index); | ||||
| 	memcpy(Buffer() + Index, String, len); | ||||
| 	m_StringLen += len; | ||||
| 	Buffer()[m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| void cTBString::Insert(uint Index, char Character) { | ||||
| 	Allocate(m_StringLen + 2, true); | ||||
|  | ||||
| 	memmove(Buffer() + Index + 1, Buffer() + Index, m_StringLen - Index); | ||||
| 	Buffer()[Index] = Character; | ||||
| 	Buffer()[++m_StringLen] = 0; | ||||
| } | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Left(uint count) const, ret) | ||||
| 	if (count > m_StringLen) | ||||
| 		count = m_StringLen; | ||||
|  | ||||
| 	ret.Allocate(count + 1); | ||||
| 	memcpy(ret.Buffer(), Buffer(), count); | ||||
| 	ret.Buffer()[count] = 0; | ||||
| 	ret.m_StringLen = count; | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Right(uint count) const, ret) | ||||
| 	if (count > m_StringLen) | ||||
| 		count = m_StringLen; | ||||
|  | ||||
| 	ret.Allocate(count + 1); | ||||
| 	memcpy(ret.Buffer(), Buffer() + m_StringLen - count, count); | ||||
| 	ret.Buffer()[count] = 0; | ||||
| 	ret.m_StringLen = count; | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Mid(int idx, int count) const, ret) | ||||
| 	if (idx < 0) | ||||
| 		idx = m_StringLen + idx; | ||||
|  | ||||
| 	if ((count < 0) || (count > (int)m_StringLen - idx)) | ||||
| 		count = m_StringLen - idx; | ||||
|  | ||||
| 	ret.Allocate(count + 1); | ||||
| 	memcpy(ret.Buffer(), Buffer() + idx, count); | ||||
| 	ret.Buffer()[count] = 0; | ||||
| 	ret.m_StringLen = count; | ||||
| RETURN(ret) | ||||
|  | ||||
| int cTBString::Find (const cTBString &String, uint Offset) const { | ||||
| 	if (Offset >= m_StringLen) | ||||
| 		return -1; | ||||
|  | ||||
| 	char *pos = strstr(Buffer() + Offset, String.Buffer()); | ||||
| 	if (pos) return (pos - Buffer()); | ||||
| 	else     return -1; | ||||
| } | ||||
|  | ||||
| int cTBString::Find (const char *String, uint Offset) const { | ||||
| 	if (Offset >= m_StringLen) | ||||
| 		return -1; | ||||
|  | ||||
| 	char *pos = strstr(Buffer() + Offset, String); | ||||
| 	if (pos) return (pos - Buffer()); | ||||
| 	else     return -1; | ||||
| } | ||||
|  | ||||
| int cTBString::Find (char Character, uint Offset) const { | ||||
| 	if (Offset >= m_StringLen) | ||||
| 		return -1; | ||||
|  | ||||
| 	char *pos = strchr(Buffer() + Offset, Character); | ||||
| 	if (pos) return (pos - Buffer()); | ||||
| 	else     return -1; | ||||
| } | ||||
|  | ||||
| #ifdef TOOLBOX_REGEX | ||||
| bool cTBString::Find (cTBRegEx &Regex, uint Offset) const { | ||||
| 	return Regex.Match(Buffer(), Offset); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| void cTBString::Format (const char *fmt, ...) { | ||||
| 	int n, size = 128; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	char *buf = Buffer(size); | ||||
|  | ||||
| 	while (1) { | ||||
| 		va_start(ap, fmt); | ||||
| 		n = vsnprintf(buf, size, fmt, ap); | ||||
| 		va_end(ap); | ||||
|  | ||||
| 		if ((n > -1) && (n < size)) | ||||
| 			break; | ||||
|  | ||||
| 		if (n > -1) | ||||
| 			size = n + 1; | ||||
| 		else | ||||
| 			size *= 2; | ||||
|  | ||||
| 		buf = Buffer(size); | ||||
| 	} | ||||
| 	Release(n); | ||||
| } | ||||
|  | ||||
| void cTBString::Format(const cTBString &fmt, ...) { | ||||
| 	int n, size = 128; | ||||
| 	va_list ap; | ||||
|  | ||||
| 	char *buf = Buffer(size); | ||||
|  | ||||
| 	while (1) { | ||||
| 		va_start(ap, &fmt); | ||||
| 		n = vsnprintf(buf, size, fmt, ap); | ||||
| 		va_end(ap); | ||||
|  | ||||
| 		if ((n > -1) && (n < size)) | ||||
| 			break; | ||||
|  | ||||
| 		if (n > -1) | ||||
| 			size = n + 1; | ||||
| 		else | ||||
| 			size *= 2; | ||||
|  | ||||
| 		buf = Buffer(size); | ||||
| 	} | ||||
| 	Release(n); | ||||
| } | ||||
|  | ||||
| template<cTBString::TOFUNC F> | ||||
| cTBString cTBString::ToAnything(void) const { | ||||
| 	const char *src; | ||||
| 	char *dest; | ||||
| 	cTBString ret; | ||||
|  | ||||
| 	src = Buffer(); | ||||
| 	dest = ret.Buffer(m_StringLen + 1); | ||||
|  | ||||
| 	for (; src < Buffer() + m_StringLen; ++src, ++dest) | ||||
| 		*dest = F(*src); | ||||
|  | ||||
| 	*dest = '\0'; | ||||
|  | ||||
| 	ret.Release(m_StringLen); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| template<cTBString::ISFUNC F> | ||||
| bool cTBString::IsAnything(void) const { | ||||
| 	const char *ptr = Buffer(); | ||||
|  | ||||
| 	for (; ptr < Buffer() + m_StringLen; ++ptr) | ||||
| 		if (!F(*ptr)) return false; | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| short cTBString::ToShort(bool *Ok) const { | ||||
| 	long ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	ret = strtol(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && ret >= SHRT_MIN && ret <= SHRT_MAX) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (short)ret; | ||||
| } | ||||
|  | ||||
| ushort cTBString::ToUShort(bool *Ok) const { | ||||
| 	ulong ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	ret = strtoul(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && ret <= USHRT_MAX) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (ushort)ret; | ||||
| } | ||||
|  | ||||
| int cTBString::ToInt(bool *Ok) const { | ||||
| 	long ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	ret = strtol(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && ret >= INT_MIN && ret <= INT_MAX) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (int)ret; | ||||
| } | ||||
|  | ||||
| uint cTBString::ToUInt(bool *Ok) const { | ||||
| 	ulong ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	ret = strtoul(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && ret <= UINT_MAX) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (uint)ret; | ||||
| } | ||||
|  | ||||
| long cTBString::ToLong(bool *Ok) const { | ||||
| 	long ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	errno = 0; | ||||
| 	ret = strtol(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && errno != ERANGE) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (long)ret; | ||||
| } | ||||
|  | ||||
| ulong cTBString::ToULong(bool *Ok) const { | ||||
| 	ulong ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	errno = 0; | ||||
| 	ret = strtoul(Buffer(), &endptr, 0); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && errno != ERANGE) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (ulong)ret; | ||||
| } | ||||
|  | ||||
| float cTBString::ToFloat(bool *Ok) const { | ||||
| 	double ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	ret = strtod(Buffer(), &endptr); | ||||
|  | ||||
| 	if (!IsEmpty() && *endptr == '\0' && errno != ERANGE) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (float)ret; | ||||
| } | ||||
|  | ||||
| double cTBString::ToDouble(bool *Ok) const { | ||||
| 	double ret; | ||||
| 	char *endptr; | ||||
| 	bool res = false; | ||||
|  | ||||
| 	errno = 0; | ||||
| 	ret = strtol(Buffer(), &endptr, 0); | ||||
| 	 | ||||
| 	if (!IsEmpty() && *endptr == '\0' && errno != ERANGE) | ||||
| 		res = true; | ||||
|  | ||||
| 	if (Ok) *Ok = res; | ||||
| 	return (double)ret; | ||||
| } | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(short Num), ret) | ||||
| 	ret.Format("%hd", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(ushort Num), ret) | ||||
| 	ret.Format("%hu", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(int Num), ret) | ||||
| 	ret.Format("%d", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(uint Num), ret) | ||||
| 	ret.Format("%u", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(long Num), ret) | ||||
| 	ret.Format("%ld", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(ulong Num), ret) | ||||
| 	ret.Format("%lu", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(float Num), ret) | ||||
| 	ret.Format("%f", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
| RETURNS(cTBString, cTBString::Number(double Num), ret) | ||||
| 	ret.Format("%f", Num); | ||||
| RETURN(ret) | ||||
|  | ||||
							
								
								
									
										353
									
								
								tools/string.h
									
									
									
									
									
								
							
							
						
						
									
										353
									
								
								tools/string.h
									
									
									
									
									
								
							| @@ -1,353 +0,0 @@ | ||||
| #ifndef TOOLBOX_STRING_H | ||||
| #define TOOLBOX_STRING_H | ||||
|  | ||||
| #include "tools/tools.h" | ||||
| #include "tools/shared.h" | ||||
| //#include "tools/source.h" | ||||
|  | ||||
| #include <ctype.h> | ||||
| #include <stddef.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #ifdef TOOLBOX_REGEX | ||||
| class cTBRegEx; | ||||
| #endif | ||||
|  | ||||
| class cTBString: public cTBShared { | ||||
| private: | ||||
| 	uint m_StringLen; | ||||
| 	 | ||||
| 	/* Unhide and forbid baseclass method */ | ||||
| 	virtual void  Set (const cTBShared &src) {} | ||||
|  | ||||
| public: | ||||
| 	cTBString (); | ||||
| 	cTBString (const cTBString &src); | ||||
| 	cTBString (const uchar *src); | ||||
| 	cTBString (const char *src); | ||||
| 	cTBString (char src); | ||||
| 	virtual ~cTBString (); | ||||
|  | ||||
| 	static const cTBString Null; | ||||
|  | ||||
| 	void Clear (); | ||||
| 	void Set   (const cTBString &String); | ||||
| 	void Set   (const uchar *String); | ||||
| 	void Set   (const char *String); | ||||
| 	void Set   (char Character); | ||||
|  | ||||
| 	void Fill  (char Character, int Length = -1); | ||||
|  | ||||
| 	void Release (uint newsize); | ||||
|  | ||||
| 	cTBString &operator= (const cTBString &src) { Set(src); return *this; } | ||||
| 	cTBString &operator= (const char *src) 	{ Set(src); return *this; } | ||||
| 	cTBString &operator= (char src)			{ Set(src); return *this; } | ||||
|  | ||||
| 	void Append (const cTBString &src); | ||||
| 	void Append (const char *src); | ||||
| 	void Append (char src); | ||||
|  | ||||
| 	friend cTBString operator+ (const cTBString &a, const cTBString &b); | ||||
| 	friend cTBString operator+ (const cTBString &a, const char *b); | ||||
| 	friend cTBString operator+ (const char *a, const cTBString &b); | ||||
| 	friend cTBString operator+ (const cTBString &a, char b); | ||||
| 	friend cTBString operator+ (char a, const cTBString &b); | ||||
|  | ||||
| 	friend cTBString &operator+= (cTBString &a, const cTBString &b); | ||||
| 	friend cTBString &operator+= (cTBString &a, const char *b); | ||||
| 	friend cTBString &operator+= (cTBString &a, char b); | ||||
|  | ||||
| 	void Prepend (const cTBString &src); | ||||
| 	void Prepend (const char *src); | ||||
| 	void Prepend (char src); | ||||
| 	 | ||||
| 	void Insert (uint Index, const cTBString &src); | ||||
| 	void Insert (uint Index, const char *src); | ||||
| 	void Insert (uint Index, char src); | ||||
|  | ||||
| 	char At (uint i) const; | ||||
| 	char operator[] (int i) const { return At((uint)i); } | ||||
|  | ||||
| 	char &At (uint i); | ||||
| 	char &operator[] (int i) { return At(i); } | ||||
|  | ||||
| 	cTBString Left  (uint Count) const; | ||||
| 	cTBString Right (uint Count) const; | ||||
| 	cTBString Mid   (int idx, int Count = -1) const; | ||||
|  | ||||
| 	int Find (const cTBString &String, uint Offset = 0) const; | ||||
| 	int Find (const char *String, uint Offset = 0) const; | ||||
| 	int Find (char Character, uint Offset = 0) const; | ||||
| #ifdef TOOLBOX_REGEX | ||||
| 	bool Find (cTBRegEx &Regex, uint Offset = 0) const; | ||||
| #endif | ||||
|  | ||||
| 	void Format (const char *fmt, ...) | ||||
| #if defined(__GNUC__) | ||||
| 		__attribute__ ((format (printf, 2, 3))) | ||||
| #endif | ||||
| 		; | ||||
| 	void Format (const cTBString &fmt, ...); | ||||
|  | ||||
| 	typedef int(*TOFUNC)(int); | ||||
| 	template<TOFUNC F> cTBString ToAnything(void) const; | ||||
|  | ||||
| 	cTBString ToUpper (void) const { return ToAnything<toupper>(); } | ||||
| 	cTBString ToLower (void) const { return ToAnything<tolower>(); } | ||||
|  | ||||
| 	typedef int(*ISFUNC)(int); | ||||
| 	template<ISFUNC F> bool IsAnything(void) const; | ||||
|  | ||||
| 	bool IsAlnum(void) const { return IsAnything<isalnum>(); } | ||||
| 	bool IsAlpha(void) const { return IsAnything<isalpha>(); } | ||||
| 	bool IsAscii(void) const { return IsAnything<isascii>(); } | ||||
| 	bool IsCntrl(void) const { return IsAnything<iscntrl>(); } | ||||
| 	bool IsDigit(void) const { return IsAnything<isdigit>(); } | ||||
| 	bool IsGraph(void) const { return IsAnything<isgraph>(); } | ||||
| 	bool IsLower(void) const { return IsAnything<islower>(); } | ||||
| 	bool IsPrint(void) const { return IsAnything<isprint>(); } | ||||
| 	bool IsPunct(void) const { return IsAnything<ispunct>(); } | ||||
| 	bool IsSpace(void) const { return IsAnything<isspace>(); } | ||||
| 	bool IsUpper(void) const { return IsAnything<isupper>(); } | ||||
| 	bool IsXdigit(void) const { return IsAnything<isxdigit>(); } | ||||
| 	 | ||||
| #if defined(_GNU_SOURCE)		 | ||||
| 	bool IsBlank(void) const { return IsAnything<isblank>(); } | ||||
| #endif | ||||
|  | ||||
| 	uint Length  (void) const { return m_StringLen; } | ||||
| 	bool IsEmpty (void) const { return m_StringLen == 0; } | ||||
| 	bool IsNull  (void) const { return Buffer() == 0; } | ||||
|  | ||||
| 	short ToShort(bool *Ok = NULL) const; | ||||
| 	ushort ToUShort(bool *Ok = NULL) const; | ||||
| 	int ToInt(bool *Ok = NULL) const; | ||||
| 	uint ToUInt(bool *Ok = NULL) const; | ||||
| 	long ToLong(bool *Ok = NULL) const; | ||||
| 	ulong ToULong(bool *Ok = NULL) const; | ||||
| 	float ToFloat(bool *Ok = NULL) const; | ||||
| 	double ToDouble(bool *Ok = NULL) const; | ||||
|  | ||||
| 	static cTBString Number(short Num); | ||||
| 	static cTBString Number(ushort Num); | ||||
| 	static cTBString Number(int Num); | ||||
| 	static cTBString Number(uint Num); | ||||
| 	static cTBString Number(long Num); | ||||
| 	static cTBString Number(ulong Num); | ||||
| 	static cTBString Number(float Num); | ||||
| 	static cTBString Number(double Num); | ||||
|  | ||||
| 	friend bool operator== (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator== (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator== (const char *str1, const cTBString &str2); | ||||
|  | ||||
| 	friend bool operator!= (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator!= (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator!= (const char *str1, const cTBString &str2); | ||||
|  | ||||
| 	friend bool operator< (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator< (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator< (const char *str1, const cTBString &str2); | ||||
| 	 | ||||
| 	friend bool operator> (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator> (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator> (const char *str1, const cTBString &str2); | ||||
| 	 | ||||
| 	friend bool operator<= (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator<= (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator<= (const char *str1, const cTBString &str2); | ||||
| 	 | ||||
| 	friend bool operator>= (const cTBString &str1, const cTBString &str2); | ||||
| 	friend bool operator>= (const cTBString &str1, const char *str2); | ||||
| 	friend bool operator>= (const char *str1, const cTBString &str2); | ||||
| }; | ||||
|  | ||||
| inline char cTBString::At(uint idx) const { | ||||
| 	ASSERT(idx >= m_StringLen); | ||||
| 	return Buffer() ? Buffer()[idx] : 0; | ||||
| } | ||||
|  | ||||
| inline char &cTBString::At(uint idx) { | ||||
| 	static char null = 0; | ||||
| 	ASSERT(idx >= m_StringLen); | ||||
| 	if (Buffer()) { | ||||
| 		Exclusive(); | ||||
| 		return Buffer()[idx]; | ||||
| 	} else | ||||
| 		return (null = 0); | ||||
| } | ||||
|  | ||||
| inline  | ||||
| RETURNS(cTBString, operator+(const cTBString &a, const cTBString &b), ret(a)) | ||||
| 	ret.Append(b); | ||||
| RETURN(ret) | ||||
|  | ||||
| inline  | ||||
| RETURNS(cTBString, operator+ (const cTBString &a, const char *b), ret(a)) | ||||
| 	ret.Append(b); | ||||
| RETURN(ret) | ||||
|  | ||||
| inline  | ||||
| RETURNS(cTBString, operator+ (const char *a, const cTBString &b), ret(a)) | ||||
| 	ret.Append(b); | ||||
| RETURN(ret) | ||||
|  | ||||
| inline  | ||||
| RETURNS(cTBString, operator+ (const cTBString &a, char b), ret(a)) | ||||
| 	ret.Append(b); | ||||
| RETURN(ret) | ||||
|  | ||||
| inline  | ||||
| RETURNS(cTBString, operator+ (char a, const cTBString &b), ret(a)) | ||||
| 	ret.Append(b); | ||||
| RETURN(ret) | ||||
|  | ||||
| inline cTBString &operator+= (cTBString &a, const cTBString &b) { | ||||
| 	a.Append(b); | ||||
| 	return a; | ||||
| } | ||||
|  | ||||
| inline cTBString &operator+= (cTBString &a, const char *b) { | ||||
| 	a.Append(b); | ||||
| 	return a; | ||||
| } | ||||
|  | ||||
| inline cTBString &operator+= (cTBString &a, char b) { | ||||
| 	a.Append(b); | ||||
| 	return a; | ||||
| } | ||||
|  | ||||
| inline bool operator== (const cTBString &str1, const cTBString &str2) { | ||||
| 	if (str1.Length() != str2.Length()) | ||||
| 		return false; | ||||
| 	return memcmp(str1.Buffer(), str2.Buffer(), str1.Length()) == 0; | ||||
| } | ||||
|  | ||||
| inline bool operator== (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	if (str1.Length() != len) | ||||
| 		return false; | ||||
| 	return memcmp(str1.Buffer(), str2, len) == 0; | ||||
| } | ||||
|  | ||||
| inline bool operator== (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	if (len != str2.Length()) | ||||
| 		return false; | ||||
| 	return memcmp(str1, str2.Buffer(), len) == 0; | ||||
| } | ||||
|  | ||||
| inline bool operator!= (const cTBString &str1, const cTBString &str2) { | ||||
| 	if (str1.Length() != str2.Length()) | ||||
| 		return true; | ||||
| 	return memcmp(str1.Buffer(), str2.Buffer(), str1.Length()) != 0; | ||||
| } | ||||
|  | ||||
| inline bool operator!= (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	if (str1.Length() != len) | ||||
| 		return true; | ||||
| 	return memcmp(str1.Buffer(), str2, len) != 0; | ||||
| } | ||||
|  | ||||
| inline bool operator!= (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	if (len != str2.Length()) | ||||
| 		return true; | ||||
| 	return memcmp(str1, str2.Buffer(), len) != 0; | ||||
| } | ||||
|  | ||||
| inline bool operator< (const cTBString &str1, const cTBString &str2) { | ||||
| 	int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length()); | ||||
| 	if ((ret < 0) || ((ret == 0) && (str1.Length() < str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator< (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len); | ||||
| 	if ((ret < 0) || ((ret == 0) && (str1.Length() < len))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator< (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length()); | ||||
| 	if ((ret < 0) || ((ret == 0) && (len < str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator> (const cTBString &str1, const cTBString &str2) { | ||||
| 	int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length()); | ||||
| 	if ((ret > 0) || ((ret == 0) && (str1.Length() < str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator> (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len); | ||||
| 	if ((ret > 0) || ((ret == 0) && (str1.Length() < len))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator> (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length()); | ||||
| 	if ((ret > 0) || ((ret == 0) && (len < str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator<= (const cTBString &str1, const cTBString &str2) { | ||||
| 	int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length()); | ||||
| 	if ((ret < 0) || ((ret == 0) && (str1.Length() <= str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator<= (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len); | ||||
| 	if ((ret < 0) || ((ret == 0) && (str1.Length() <= len))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator<= (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length()); | ||||
| 	if ((ret < 0) || ((ret == 0) && (len <= str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator>= (const cTBString &str1, const cTBString &str2) { | ||||
| 	int ret = memcmp(str1.Buffer(), str2.Buffer(), str1.Length() < str2.Length() ? str1.Length() : str2.Length()); | ||||
| 	if ((ret > 0) || ((ret == 0) && (str1.Length() >= str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator>= (const cTBString &str1, const char *str2) { | ||||
| 	uint len = strlen(str2); | ||||
| 	int ret = memcmp(str1.Buffer(), str2, str1.Length() < len ? str1.Length() : len); | ||||
| 	if ((ret > 0) || ((ret == 0) && (str1.Length() >= len))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| inline bool operator>= (const char *str1, const cTBString &str2) { | ||||
| 	uint len = strlen(str1); | ||||
| 	int ret = memcmp(str1, str2.Buffer(), len < str2.Length() ? len : str2.Length()); | ||||
| 	if ((ret > 0) || ((ret == 0) && (len >= str2.Length()))) | ||||
| 		return true; | ||||
| 	return false; | ||||
| } | ||||
| 		 | ||||
| #endif // TOOLBOX_STRING_H | ||||
		Reference in New Issue
	
	Block a user