Click here to Skip to main content
15,894,297 members
Articles / Programming Languages / C++

DynObj - C++ Cross Platform Plugin Objects

Rate me:
Please Sign up or sign in to vote.
4.95/5 (34 votes)
27 Sep 200727 min read 145.8K   3.4K   132  
DynObj is an open source library that provides a C++ application with run-time class loading facilities
#ifndef SCSTR_HPP
#define SCSTR_HPP

// A simple string type for Ansi/Unicode
// Expects a type scChar to be defined
// Also expects that ExpArr.hpp is included at this point

#include <string.h>
#include <stdio.h>
#include <ctype.h>


#ifndef SCCHAR_TYPEDEF
	#ifndef scChar
		#warning scChar not defined, defaulting to char
		#define scChar char
	#endif	
#endif

#ifndef scInt 
	// For string length
	#define scInt int
#endif

/*
#ifndef EA_ASSERT
	#define EA_ASSERT assert
	#include <assert.h>
#endif
*/
#include "ExpArr.hpp"

#include "sc.h"

#ifndef STR_AT_END 
	#define STR_AT_END ((int)0x80000000)
#endif



class scString : public ExpArr<scChar,scInt> {
public: 
	scString( const scChar *ps=NULL ) : ExpArr<scChar,scInt>(ps,ps?(int)scstrlen(ps):0) { 
        Push((scChar)0);
	}
	scString( const scString &s ) : ExpArr<scChar,scInt>(s) { }
	scString( const scChar *ps, int len ) : ExpArr<scChar,scInt>( ps, len<0? (ps?scstrlen(ps):0) :len ) { Push(0); }
	// Concatenation constructor
	scString( const scChar *ps1, const scChar *ps2, int l1=-1, int l2=-1 ) { 
		if(l1==-1) l1 = ps1?(int)scstrlen(ps1):0; 
		if(l2==-1) l2 = ps2?(int)scstrlen(ps2):0; 
		MinTotalSize(l1+l2+1);
		Push( ps1,l1 );
		Push( ps2,l2 );
		Push(0);
	}
	// Construct from an interval (begin end)
	scString( bool dummy, const scChar *ps, const scChar *pe) : ExpArr<scChar,scInt>() { Assign(ps,pe); }
	
	// To allow quick formatting of an int
	scString( bool dummy, int i, const char *fmt=NULL ){ char buf[64]; sprintf(buf,fmt?fmt:"%d",i); Assign(buf); } 
	
	// To allow quick formatting of a double
	scString( bool dummy, double d, const char *fmt=NULL ){ char buf[64]; sprintf(buf,fmt?fmt:"%e",d); Assign(buf); } 
	
	scString &Assign(const scChar *ps, int l=-1){ 
	    ExpArr<scChar,scInt>::Empty();
	    Push(ps, ps ? (l<0?(int)scstrlen(ps):l) : 0);
	    Push((scChar)0);
	    return *this;
	}

	scString &Assign(const scChar *ps, const scChar *pend ){ 
		return Assign( ps, ps && pend ? pend-ps : -1 );
	}

	scString &operator = (const scString &s){ 
		return Assign(s,s.Length());
	    //ExpArr<scChar,scInt>::Empty();
	    //Push(s.Base(),s.ExpArr<scChar,scInt>::Size());
	    //return *this;
	}

	scString &operator = (const scChar *ps){
		return Assign(ps,-1);
	    //ExpArr<scChar,scInt>::Empty();
	    //Push(ps,ps?scstrlen(ps):0);
	    //Push((scChar)0);
	    //return *this;
	}

	operator const scChar*() const { return ta; }

	scString &operator += (const scChar *ps ){ 
		return Append(ps,-1);
	    //if(!ps) return *this;
	    //Pop();
	    //Push(ps,scstrlen(ps)+1);
	    //return *this;
	}

	scString &operator += (const scString &s ){ 
	    Pop();
	    Push(s.Base(),s.ExpArr<scChar,scInt>::Size());
	    return *this;
	}

	scString &Insert(int at, const scChar *ps, int len=-1){ 
	    if(!ps || !len) return *this;
	    if( at==(int)STR_AT_END ) at = cur_size-1;
	    else{
		    at %= cur_size;	// Including NUL
	    	if( at<0 ) at += cur_size-1;
	    }
	    ExpArr<scChar,scInt>::Insert( ps, len<0?(int)scstrlen(ps):len, at );
	    return *this;
	}
	
	scString &Append(const scChar *ps, int len=-1){ 
		return Insert(STR_AT_END,ps,len);
	}

	scString &Append(scChar ch){ 
		ta[cur_size-1] = ch;
	    Push((scChar)0);
	    return *this;
	}

	scString &Prepend(const scChar *ps, int len=-1){
		return Insert(0,ps,len);
	}

	scString &Prepend(scChar ch){ 
	    InsertOrdered( ch,0 );
	    return *this;
	}

	scString &operator += (const scChar ch ){ 
		return Append(ch);
	}

/*
   scString operator + (const scChar *ps) {
   	return scString(ta,ps,cur_size-1);
   }
*/
	bool operator == (const scChar *ps ) const { 
	    if(!ps) return !Length(); 
	    return !scstrcmp(ta,ps);
	}
	bool operator == (scChar *ps ) const { 
	    if(!ps) return !Length(); 
	    return !scstrcmp(ta,ps);
	}

	bool operator != (const scChar *ps ) const { 
	    return ! operator == (ps);
	}

	// Use base case
	//scChar &operator [] (int ix) { EA_ASSERT(ix<Length()); return Elem(ix); } 

	int Length() const { return cur_size-1; }
	int Size() const { return cur_size-1; }   // Basically to hide ExpArr::Empty
	// Basically to hide ExpArr::SetSize
	bool SetSize( int len ) { 
		bool b = ExpArr<scChar,scInt>::SetSize(len);
		if( !b ) return false;
		Push(0);
		return true;
	}   


	scString &operator += (int i ){
		scChar buf[16]; 
		sprintf(buf,_SC("%d"),i); 
		return *this+=buf; 
	} 

	scString &operator += (double d ){
		scChar buf[32]; 
		sprintf(buf,_SC("%f"),d); 
		return *this+=buf;
	} 

	scString &operator = (int i ){
		scChar buf[16]; 
		sprintf(buf,_SC("%d"),i); 
		return *this=buf; 
	} 

	scString &operator = (double d ){
		scChar buf[32]; 
		sprintf(buf,_SC("%f"),d); 
		return *this=buf;
	} 
	
	scString &Trunc(int pos){ 
	    if( pos<0 ) pos = Length()+pos;
	    if( pos<0 || pos>=Length() ) EA_THROW_RV("scString::Trunc - Invalid pos", *this);
	    //EA_ASSERT(pos>=0 && pos<Length()); 
	    cur_size = pos;
	    Push((scChar)0);
	    return *this;
	}

	scString &SetLength( int len ) { 
	    if(len<=Length()) return Trunc(len);
	    MinTotalSize( len+1 );
	    cur_size = len;
	    Push((scChar)0);
	    return *this;
    }

	scChar *Right( int from_pos ){
	    if( from_pos<0 ) from_pos = Length()+from_pos;
	    if( from_pos<0 || from_pos>=Length() ) return NULL;
		return ta+from_pos;
	}

	scString &Strip( bool left=true, bool right=true ) { 
	    int p_left=0, p_right=cur_size-2;
	    if( left )
	    	for( ; p_left<cur_size && scisspace(ta[p_left]); p_left++ );
	    if( right )
	    	for( ; p_right>=0 && scisspace(ta[p_right]); p_right-- );
	    if( p_left>p_right )
	        return Reset();
        if( p_left )
            memmove(ta,ta+p_left,p_right+1-p_left);
        ta[p_right+1-p_left] = (scChar)0;
        cur_size = p_right+2-p_left;
        return *this;
    }

	scString &Reset( ){ 
	    ExpArr<scChar,scInt>::Empty();
	    Push((scChar)0);
	    return *this;
	}

	scString &Empty( ){ // Basically to hide ExpArr::Empty
	    return Reset();
	}
	
	int Subst( scChar find, scChar repl ){
		int n_found = 0;
        for( int ix=cur_size-2; ix>=0; ix-- )
            if( ta[ix]==find ){
            	ta[ix]=repl;
            	n_found++;
            }
        return n_found;
	}

	int Subst( const char *find, const char *repl ){
		int n_found = 0;
	    if( find!=repl && find && *find ){
	    	int pos = 0;
	    	int rl = repl?(int)strlen(repl):0;
	    	int dl = rl - (int)strlen(find);
	    	while( 1 ){
	    		char *pc = strstr(ta+pos,find);
	    		if( !pc ) break;
	    		pos = pc-ta;
	    		if( dl<0 )
	    			// Remove space from array
	    			ExpArr<char>::Remove( -dl, pos );
	    		else if( dl>0 )
	    			// Insert space
	    			//ExpArr<char>::Insert(repl,dl,pos);
	    			ExpArr<char>::MakeSpaceAt( pos, dl );
	    		if( rl )
	    			memcpy(ta+pos,repl,rl);
	    		n_found++;
	    		pos += rl;
	    	}
	    }
        return n_found;
	}

	bool FindAt( const scChar *str, int pos=0/*STR_AT_END for find at end*/ ){
		if( !str || !ta || pos>=cur_size ) return false;
		int sl = (int)strlen(str);
		if( pos>=0 )
			return !strncmp(ta+pos,str,sl);
		else{
			if( pos==STR_AT_END ) pos = 0;
			int dp = cur_size+pos-1-sl;
			if( dp<0 ) return false;
			return !strncmp(ta+dp,str,sl);
		}
	}
	
	bool StartsWith( const scChar *psc ){
		return FindAt( psc,0 );
	}
	
	bool EndsWith( const scChar *psc ){
		return FindAt( psc,STR_AT_END );
	}
	
	int Find( const scChar *psc, bool from_end=false ){
		if( !psc ) return -1;
		scChar *ploc = NULL;
		if( !from_end )
			ploc = scstrstr(ta,psc);
		else{
			int sl = scstrlen(psc);
			ploc = ta + cur_size-sl;
			while( ploc>=ta && scstrncmp(psc,ploc,sl) )
				ploc--;
		}
		return ploc && ploc>=ta? int(ploc-ta) : -1;
	}

	scString Slice( int from, int to=STR_AT_END ){
		if( from<0 ) from=cur_size-1+from;
	   if( from<0 || from>=Length() ) EA_THROW_RV("scString::Slice - Invalid from", *this);
		if( to<0 ){
			if( to==STR_AT_END ) to = cur_size-1;
			else to = cur_size+to-1;
		}
	   if( to!=STR_AT_END && (to<0 || to>=Length()) ) EA_THROW_RV("scString::Slice - Invalid to", *this);
	    
	    if( to<=from ) 
	    	return scString();
	    else  
	    	return scString( ta+from, to-from );
	}
	
	scString &Suffix( const scChar *psc ){
		if( !FindAt(psc,STR_AT_END) ) Append(psc);
		return *this;
	}

	scString &Suffix( scChar ch ){
		if( !ta || cur_size<2 || ta[cur_size-2]!=ch ) Append(ch);
		return *this;
	}

	scString &Prefix( const scChar *psc ){
		if( !FindAt(psc,0) ) Prepend(psc);
		return *this;
	}
	
	scString &Prefix( scChar ch ){
		if( !ta || *ta!=ch ) Prepend(ch);
		return *this;
	}

	bool SaveToFile( const scChar *path ){
		FILE *pf = fopen(path,"w");
		if( !pf ) return false;
		fwrite(Base(),scString::Size(),1,pf);
		fclose(pf);
		return true;
	}
			
	bool LoadFromFile( const scChar *path ){
		FILE *pf = fopen(path,"r");
		if( !pf ) return false;
		char buf[256];
		int rl;
		Empty();
		while( (rl=fread(buf,1,256,pf))>0 )
			Append( buf, rl );
		fclose(pf);
		return true;
	}
};

//scString operator + (const scChar *ps1, const scString &s2);
scString operator + (const scString &s1, const scChar *ps2 );
scString operator + (const scString &s1, const scString &s2 );
	
#endif // SCSTR_HPP


By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions