Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source incl-master const-headers String.h
Document Actions

String.h

by Michael L Powell last modified 2007-01-26 03:20

Click here to get the file

Size 13.3 kB - File type text/plain

File contents

/*ident	"@(#)String:incl/String.h	3.2" */
/******************************************************************************
*
* C++ Standard Components, Release 3.0.
*
* Copyright (c) 1991, 1992 AT&T and Unix System Laboratories, Inc.
* Copyright (c) 1988, 1989, 1990 AT&T.  All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T and Unix System
* Laboratories, Inc.  The copyright notice above does not evidence
* any actual or intended publication of such source code.
*
******************************************************************************/

#ifndef ATTLCSTRINGH 
#define ATTLCSTRINGH

#include <string.h>
#ifndef __hpux
#include <sysent.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <Pool.h>
#include <memory.h>

class Srep_ATTLC;
class Stringsize;
class String;
class Tmpstring;
class Substring;
class ostream;
class istream;

class Srep_ATTLC {         // String Representation
public:
	enum { MAXS = 8, MAXL = 64 };
	static Srep_ATTLC* nullrep_; // nullrep always has refc == 0 and max == 0
	static Pool* Reelp;  // Pool for "reel" small strings
	static Pool* SPoolp; // Pool for smallish strings
	static void initialize() { if (Reelp == 0) doinitialize(); }
	static void doinitialize();
	static Srep_ATTLC* nullrep() { initialize(); return nullrep_; }
	static Srep_ATTLC *new_srep(unsigned);
	static Srep_ATTLC *get_long(unsigned);
	unsigned len;
	unsigned max;
	unsigned char refc;
	char str[MAXS];
	Srep_ATTLC() { len = 0; max = 0; refc = 0; }
	void rcdec() { if(refc && --refc==0)  delete_srep(); }
	void rcuninc() { --refc; }
	void rcinc() { if(refc) refc++; }
	void delete_srep();
};

class Stringsize {	 // for declarations of large Strings
	unsigned int i;
	friend class String;
public:
	Stringsize(unsigned int x) { i = x; }
	~Stringsize() {}
	int size() { return i; }
};
	
class String {		//  the String
	Srep_ATTLC *d;
	friend class Tmpstring;
	friend class Substring;
	String(Srep_ATTLC* r) { d = r; }
	String& newcopy(char);
	void reserve_grow(int);
	void overflow() const;
public:
	String() { d = Srep_ATTLC::nullrep(); }
	String(const char*);
	String(const char*,unsigned);
	String(char c) { d = Srep_ATTLC::new_srep(1); d->str[0]=c; }
	String(Stringsize s) { d = Srep_ATTLC::new_srep(s.i); d->len=0; }
	String(const String& s) {
		d = s.d; d->rcinc();
		if (d->refc == 0 && d->max != 0) s.overflow();
	}
	inline String(const Tmpstring&);
	inline String(const Substring&);
	friend String int_to_str(int);
	friend String long_to_str(long);
	inline operator const char*() const;
	~String() { d->rcdec(); }
	/* ASSIGNMENT */
	inline String& operator=(const String&);
	void assign(const char*, unsigned len);
	String& operator=(const char*);
	inline String& operator=(char);
	String& operator=(Stringsize);
	/* CHANGE SIZE */
	void reserve(Stringsize n) {
		if (n.i >= d->max) reserve_grow(n.i);
	}
	inline void shrink(int);
	/* special version for G2++ */
	void g2_shrink(int newlen) { if (newlen < d->len) d->len = newlen; }
	/* APPENDING */
	String& operator+=(const String&);
	void append(const char*, unsigned len);
	String& operator+=(const char*);
	inline String& operator+=(char);
	inline String& put(const String&);
	inline String& put(const char*);
	inline String& put(char);
	/* ADDITION */
	friend Tmpstring operator+(const String&,const String&);
	friend Tmpstring operator+(const String&,const char*);
	friend Tmpstring operator+(const String&,char);
	friend Tmpstring operator+(const char*,const String&);
	friend Tmpstring operator+(char,const String&);
	/* MISCELLANEOUS */
	inline void pad(int, int = -1);
	/* special version for G2++ */
	void g2_pad(int n, int att_pad_char = -1) {
		if (n + d->len >= d->max) reserve_grow(n + d->len);
		if (att_pad_char != -1) memset(&d->str[d->len], att_pad_char, n);
		d->len += n;
	}
	unsigned length() const { return d->len; } 
	int is_empty() const { return d->len ? 0 : 1; } 
	void make_empty() { assign("", 0); }
	unsigned max() const { return d->max; } 
	int nrefs() const { return d->refc; }
	const Srep_ATTLC *rep() const { return d; }
	inline void uniq();
	inline char char_at(unsigned) const;
	char& operator[](unsigned);
	char& operator[](int i) {return ((*this).operator[]((unsigned) i));}
	inline char operator[](unsigned) const;
	char operator[](int i) const {return ((*this).operator[]((unsigned) i));}
	Substring operator()(unsigned,unsigned); 
	Substring operator()(unsigned);
	String chunk(unsigned,unsigned) const; 
	String chunk(unsigned) const;
	int index(const String&,unsigned pos = 0) const;
	int index(char,unsigned pos = 0) const;
	int hashval() const;
	char* dump(char* s) const { 
		memcpy(s,d->str,d->len); 
		s[d->len]='\0'; return s;
	}
	int getX(char&);
	int get() { char c; return getX(c); }
	int unputX(char&);
	int unput() { char c; return unputX(c); }
	String& unget(char);
	String& unget(const String&);
	inline int firstX(char&) const;			
	inline int lastX(char&) const;
	/* COMPARISON OPERATORS */
	inline int compare(const String&) const;
	inline int compare(const char*) const;
	friend inline int operator==(const String&,const String&);
	friend inline int operator==(const String&,const char*);
	friend inline int operator!=(const String&,const String&);
	friend inline int operator!=(const String&,const char*);
	/* SYSTEM FUNCTIONS */
#if defined(SYSV) && !defined(__hpux)
	friend int read(int, String&, unsigned);
#else
	friend int read(int, String&, int);
#endif
	friend int write(int fd, const String& s) {
		return write(fd, s.d->str, s.d->len);
	}
	friend int puts(const String&);
	friend int fputs(const String&, FILE*);
	/* STRING(3) FUNCTIONS */
	int strchr(char) const;
	int strrchr(char) const;
	int strpbrk(const String&) const;
	int strspn(const String&) const;
	int strcspn(const String&) const;
	/* MISCELLANEOUS */
	int match(const String&) const;
	int match(const char *) const;
	int firstdiff(const String&) const;
	int firstdiff(const char *) const;
	/* INPUT/OUTPUT */
	int read(istream&,int);
	friend /*inline*/ ostream& operator<<(ostream&,const String&);
	friend istream& operator>>(istream&,String&);
	/* CASE FUNCTIONS */
	String upper() const;
	String lower() const;
};

class Tmpstring {  // Class of String temporaries for Addition
	Srep_ATTLC *d;
	char strung;
	friend class String;
	void overflow() const;
public:
	Tmpstring(Srep_ATTLC* r) { strung=0; d = r; }
	Tmpstring(const String& s) {
		strung=0; d = s.d; s.d->rcinc();
		if (s.d->refc == 0 && s.d->max != 0) s.overflow();
	}
	Tmpstring(const Tmpstring& t) {
		strung=0; d = t.d; d->rcinc();
		if (d->refc == 0 && d->max != 0) t.overflow();
	}
	Tmpstring& operator+(const String&);
	Tmpstring& operator+(const char*);
	Tmpstring& operator+(char);
	~Tmpstring() { if(!strung) d->rcdec(); }
#ifndef __cplusplus
	friend ostream& operator<<(ostream&,const Tmpstring&);
#endif
};

class Substring {
	friend class String;
	String *ss;
	int oo;
	int ll;
	Substring(String &i,int o,int l) : ss(&i), oo(o), ll(l) { }
public:
	Substring(const Substring&);
	void operator=(const String&);
	void operator=(const char* s);
	String *it() const { return ss; }
	int offset() const { return oo; }
	int length() const { return ll; }
#ifndef __cplusplus
	friend ostream& operator<<(ostream&,const Substring&);
#endif
};

// inline functions

inline 
String::String(const Tmpstring& t) { ((Tmpstring*) &t)->strung=1; d = t.d; }

inline
String::String(const Substring& s) {
	d = Srep_ATTLC::new_srep(s.ll);
	if(s.ll) memcpy(d->str,s.ss->d->str+s.oo,s.ll);
}

inline
String::operator const char*() const {
	if (d->len >= d->max && d->len)
		((String *) this)->reserve_grow(d->len + 1);
	*(d->str + d->len) = '\0'; 
	return (d->str);
}

inline String&
String::operator=(const String& r) {
        r.d->rcinc();
        if (r.d->refc == 0 && r.d->max != 0) {
        r.d->rcuninc(); // r.d->refc == 255
        r.overflow(); // make new node -- r.d->refc() == 1, oldr.d->refc == 254
        r.d->rcinc(); // now r.d->refc == 2
        }
        d->rcdec();
        d = r.d;
        return *this;
}

inline String&
String::operator=(char c) {
	if(d->refc!=1) {
		d->rcdec();
		d = Srep_ATTLC::new_srep(1);
	}
	d->str[0] = c;
	d->len = 1;
	return *this;
}

inline int
String::compare(const String& s) const {
	register int dlen = d->len;
	register int slen = s.d->len;
	register int i = memcmp(d->str,s.d->str,dlen < slen ? dlen : slen);
	return i ? i : (dlen - slen);
}

inline int
String::compare(const char* s) const {
	register int dlen = d->len;
	register int ln = s ? strlen(s) : 0;
	register int i = memcmp(d->str,s, (dlen < ln ? dlen : ln));
	return i ? i : (dlen - ln);
}

inline int 
strcmp(const String& s,const String& t) {return s.compare(t);}
inline int 
strcmp(const String& s,const char* p) {return s.compare(p);}
inline int 
strcmp(const char* p,const String& t) {return -(t.compare(p));}
inline int 
compare(const String& s,const String& t) {return s.compare(t);}

inline int
operator==(const String& t,const String& s) {
	register int dlen = t.d->len;
	register int retval;
	if ((dlen != s.d->len) || (dlen && t.d->str[0] != s.d->str[0]) || (dlen>1 && t.d->str[1] != s.d->str[1]))
		retval = 0;
	else
		retval = !memcmp(t.d->str,s.d->str,dlen);
	return retval;
}
inline int
operator==(const String& t,const char* s) {
	register int dlen = t.d->len;
	register int retval;
	if (!s || (dlen && t.d->str[0]!=s[0]) || (dlen>1 && s[0]!='\0' && t.d->str[1]!=s[1]))
		retval = 0;
	else
		retval = (dlen != strlen(s)) ? 0 : !memcmp(t.d->str,s,dlen);
	return retval;
}

inline int 
operator==(const char* s,const String& t) { return t==s; }

inline int
operator!=(const String& t,const String& s) {
	register int dlen = t.d->len;
	register int retval;
	if ((dlen != s.d->len) || (dlen && t.d->str[0] != s.d->str[0]) || (dlen>1 && t.d->str[1] != s.d->str[1]))
		retval = 1;
	else
		retval = memcmp(t.d->str,s.d->str,dlen);
	return retval;
}
inline int
operator!=(const String& t,const char* s) {
	register int dlen = t.d->len;
	register int retval;
	if (!s || (dlen && t.d->str[0]!=s[0]) || (dlen>1 && s[0]!='\0' && t.d->str[1]!=s[1]))
		retval = 1;
	else
		retval = (dlen != strlen(s)) ? 1 : memcmp(t.d->str,s,dlen);
	return retval;
}

inline int 
operator!=(const char* s,const String& t) { return t!=s; }
inline int 
operator>=(const String& s,const String& t) { return s.compare(t)>=0; }
inline int 
operator>=(const String& t,const char* s) { return t.compare(s)>=0; }
inline int 
operator>=(const char* s,const String& t) { return t.compare(s)<=0; }
inline int 
operator>(const String& s,const String& t) { return s.compare(t)>0; }
inline int 
operator>(const String& t,const char* s) { return t.compare(s)>0; }
inline int 
operator>(const char* s,const String& t) { return t.compare(s)<0; }
inline int 
operator<=(const String& s,const String& t) { return s.compare(t)<=0; }
inline int 
operator<=(const String& t,const char* s) { return t.compare(s)<=0; }
inline int 
operator<=(const char* s,const String& t) { return t.compare(s)>=0; }
inline int 
operator<(const String& s,const String& t) { return s.compare(t)<0; }
inline int 
operator<(const String& t,const char* s) { return t.compare(s)<0; }
inline int 
operator<(const char* s,const String& t) { return t.compare(s)>0; }

/* STRING(3) FUNCTIONS */
inline int 
strchr(const String& s,int c) { return s.strchr((char) c); }
inline int 
strrchr(const String& s,int c){ return s.strrchr((char) c); }
inline int 
strpbrk(const String& s,const String& t) { return s.strpbrk(t);}
inline int 
strpbrk(const char* s,const String& t) { return String(s).strpbrk(t);}
inline int 
strpbrk(const String& s,const char* t) { return s.strpbrk(String(t));}
inline int 
strspn(const String& s,const String& t) { return s.strspn(t);}
inline int 
strspn(const char* s,const String& t) { return String(s).strspn(t);}
inline int 
strspn(const String& s,const char* t) { return s.strspn(String(t));}
inline int 
strcspn(const String& s,const String& t) { return s.strcspn(t);}
inline int 
strcspn(const char* s,const String& t) { return String(s).strcspn(t);}
inline int 
strcspn(const String& s,const char* t) { return s.strcspn(String(t));}

inline char
String::char_at(unsigned i) const {
	return d->str[i];
}

inline char
String::operator[](unsigned i) const {
	return d->str[i];
}

inline int
String::firstX(char &c) const { 
	return d->len > 0 ? (c=d->str[0],1) : 0;
}
inline int
String::lastX(char &c) const { 
	return d->len > 0 ? (c=d->str[d->len - 1],1) : 0;
}
inline int length(const String& s) { return s.length(); }
inline int hashval(const String& s) { return s.hashval(); }

String sgets(istream&);
int fgets(String&, int, FILE*);
int fgets(String&, FILE*);
int gets(String&);

char* Memcpy_String_ATTLC(register char*,register const char*,int);

inline String&
String::operator+=(char c) {
	int append_to_current = 1;
	if (d->refc != 1 || d->len == d->max - 1)
		append_to_current = 0;
	else
		d->str[d->len++] = c;
	String &s = append_to_current ? *this : newcopy(c);
	return s;
}

inline String& String::put(const String& s) { return *this += s; }
inline String& String::put(const char* s) { return *this += s; }
inline String& String::put(char c) { return *this += c; }

inline void
String::uniq() {
	register Srep_ATTLC* x;
	if(d->refc > 1) {
		x = Srep_ATTLC::new_srep(d->len);
		memcpy(x->str,d->str,d->len);
		d->rcdec();
		d = x;
	}
}

inline void
String::shrink(int newlen) {
	uniq();
	if (newlen < d->len)
		d->len = newlen;
}

inline void
String::pad(int n, int att_pad_char) {
	uniq();
	if (n + d->len >= d->max)
		reserve_grow(n + d->len);
	if (att_pad_char != -1)
		memset(&d->str[d->len], att_pad_char, n);
	d->len += n;
}

#endif
« March 2024 »
Su Mo Tu We Th Fr Sa
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: