⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dstring.cpp

📁 NMEA protocol for serial GPS communications
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <ctype.h>#include "dstring.h"#include "genarray.h"#include <stdarg.h>#pragma intrinsic strcpy#pragma intrinsic memset#pragma intrinsic memcpyconst char *String::NULLCHARSTRING = "";String String::NULLSTRING;inline void String::String_data::operator++(){refcnt++;}void String::String_data::operator--(){if(--refcnt == 0)delete this;}String::String_data *String::newsdp(size_t nbytes){	String::String_data *sp = (String::String_data*)new char[sizeof(int)+nbytes];	sp->refcnt = 1;        assert(sp);	return sp;}String::String_data *String::newsdp(String::String_data *sdp){	unsigned nbytes = strlen(sdp->data)+1;	String::String_data *sp = newsdp(nbytes);	memcpy(sp->data, sdp->data, nbytes);	return sp;}unsigned String::hashval(const char *cp){	unsigned res = 0;        char c;	while((c = *cp++) != 0)		res += c;        return res;}#ifdef STRING_POOL_ALLOC// A special allocation pool for Strings (the String handle is small// and is allocated a lot).String * String::freelist = 0;const int allocblocksize = 100;void * String::operator new(size_t size){	// First of all, check that we are allocating the right size of	// object. This may not be true if we are allocating a derived	// kind of object which is bigger, and the appropriate redefinition	// of of operator new() has not been done for that class.	// If the size is "wrong", then we let the standard operator handle it.	// See also the comment in operator delete() for a similar concern	if(size != sizeof(String))		return ::operator new(size);	// Is there no remaining space allocated?	if(freelist == 0){		// Grab a new chunk of allocblocksize elements		freelist = (String *)new char[allocblocksize * sizeof(String)];		if(freelist == 0)			return 0;		// Now make sure that they all form an appropriately-linked list		for(int i = 0; i < allocblocksize-1; i++)			freelist[i].freeptr = &freelist[i+1];		freelist[i].freeptr = 0;	}	// Retrieve first item from the list and return it	String *shp = freelist;	freelist = freelist->freeptr;	return shp;}void String::operator delete(void *vp, size_t size){	// We do not have a cast-iron guarantee that the size is right,	// since we may be deleting a derived class object through its	// base class pointer and it's apparent size will be wrong.	// On the other hand, if it has a virtual destructor, or the	// delete is applied to a non-base pointer, the size WILL be right.	// If we can tell that this was not really allocated from the pool,	// hand it back to the global delete operator.	if(size != sizeof(String)){		::delete(vp);		return;	}	// Well, it looks as if it is one of ours. Stitch it into the free	// list. If it wasn't allocated the normal way and is bigger, this	// means that we will lose some memory	((String *)vp)->freeptr = freelist;	freelist = (String *)vp;}#endif// if our current data is shared with others, take a copy of it (it is// about to be changed)void String::single_copy(){	if(sdp->refcnt == 1)		return;	String_data *nsdp = newsdp(sdp);	--*sdp;	sdp = nsdp;}// WARNING - init() must only be called by constructors (assumes cp unset)void String::init(const char *ccp){	if(ccp){		size_t l = strlen(ccp)+1;		sdp = newsdp(l);		memcpy(sdp->data, ccp, l);	}else{		sdp = newsdp(1);		sdp->data[0] = 0;	}}String::String(){	init("");}String::String(const char * s){	init(s);}String::String(char c){	static char car[2];	car[0] = c;	car[1] = 0;	init(car);}// Create a substringString::String(const char *ccp, size_t nbytes){	size_t l = strlen(ccp);	if(nbytes < l)		l = nbytes;	sdp = newsdp(l+1);	memcpy(sdp->data, ccp, l);	sdp->data[l] = 0;}/* * This is very awk-like! * Construct a String from an int - build the character representation * of the int first, then build a String! */String::String(int i){	char car[20];	::sprintf(car,"%d", i);	init(car);}String::String(unsigned u){	char car[20];	::sprintf(car,"%u", u);	init(car);}String::String(long l){	char car[20];	::sprintf(car,"%ld", l);	init(car);}String::String(unsigned long l){	char car[20];	::sprintf(car,"%lu", l);	init(car);}String::String(const String& s){	sdp = s.sdp;	++*sdp;}String & String::operator =(const String & s){	++*s.sdp;	--*sdp;	sdp = s.sdp;        return *this;}String & String::operator = (const char *ccp){	if(ccp == 0){		printf("Panic: assigning null String\n");		exit(-1);	}	size_t l = strlen(ccp)+1;	String_data *nsdp = newsdp(l);	memcpy(nsdp->data, ccp, l);	--*sdp;	sdp = nsdp;        return *this;}String::~String(){	--*sdp;}String operator +(const String &s1, const String &s2){	size_t newlen, oldlen;	oldlen = s1.nchars();	size_t s2len = s2.nchars();	newlen = oldlen + s2len;	assert(newlen >= oldlen && newlen >= s2len);	String::String_data *nsdp = String::newsdp(newlen+1);	// strcpy(nsdp->data, s1.sdp->data);	memcpy(nsdp->data, s1.sdp->data, oldlen);	// strcpy(nsdp->data+oldlen, s2.sdp->data);	memcpy(nsdp->data+oldlen, s2.sdp->data, s2len+1);	// String reslt(nsdp);	// --*reslt.sdp;	// reslt.sdp = nsdp;	// return reslt;	return nsdp;		// Use special constructor}String operator +(const String &cs, const char *csp){	return cs + String(csp);}String operator +(const String &cs, char c){	return cs + String(c);}String operator +(char c, const String &cs){	return String(c) + cs;}String operator +(const char *csp, const String &cs){	return String(csp)+cs;}String & String::operator +=(char c){	static char car[2];	car[0] = c;	car[1] = 0;	return operator +=(car);}String & String::operator +=(const String& s){	return operator = (*this+s);}String & String::operator +=(const char *csp){	return operator = (*this+csp);}void String::operator ++(){	String i(operator int() + 1);	operator =(i);}String::operator int()const{	return (int)strtol(sdp->data, 0, 0);}int operator ==(const String& s1, const String& s2){	return(strcmp(s1.sdp->data, s2.sdp->data) == 0);}int operator ==(const String& s1, const char *s2){	return(strcmp(s1.sdp->data, s2) == 0);}int operator	>(const String& cs1, const String& cs2){	return strcmp(cs1.sdp->data, cs2.sdp->data) > 0;}int operator	>(const String& cs1, const char * cs2){	return strcmp(cs1.sdp->data, cs2) > 0;}int operator	<(const String& cs1, const String& cs2){	return strcmp(cs1.sdp->data, cs2.sdp->data) < 0;}int operator	<(const String& cs1, const char * cs2){	return strcmp(cs1.sdp->data, cs2) < 0;}char String::operator [](size_t index1)const{	if(index1 <= 0 || index1 > nchars()){		return(0);	}	return(sdp->data[index1-1]);}String String::substr(size_t start, size_t len)const{	const size_t nc = nchars();	//printf("substring: start %lu, len %lu nc %lu\n", start, len, nc);	if(start < 1 || start > nc){		return("");	}	if(len < 1){		return("");	}	/*	 * len is allowed to be `too' long. Shorten if necessary	 * Explanation of arithmetic: assume n bytes length (1..n)	 * then start+allowable_length == n+1 (consider start==1, len == n).	 * Clearly, allowable_length = n+1 - start	 */	// This first test should eliminate nasty problems caused by overflow.	// The problem was caused by substr(6,-6);	if(len > nc){		len = nc;	}	if(start+len > nc+1)		len = nc + 1 - start;	//printf("substring: start %lu, len %lu nc %lu\n", start, len, nc);	/* can't use strncpy - doesn't guarantee a null at the end */	String_data *nsdp = newsdp(len+1);	// char *ncp = new char [nc+1];	memcpy(nsdp->data, sdp->data+start-1, len);	nsdp->data[len] = 0;	// String temp = ncp;	// delete [] ncp;	return(nsdp);}String String::left(size_t n)const{	return substr(1, n);}String String::right(size_t n)const{	const nc = nchars();	int start = nc-n+1;	if(start < 1)        	start = 1;        return substr(start, n);}// Could be more efficient, but this hack works for the presentString String::tailstr(size_t startpos1)const{	return substr(startpos1, nchars());}// copy cp2 into cp - don't ovewrite the end or copy the nullvoid copystr(char *cp, const char *cp2){	while(*cp)		if(*cp2)			*cp++ = *cp2++;		else			return;}// Set the designated character to the designated valuevoid String::set_char(size_t index1, char cval){	if(index1 <= 0 || index1 > nchars())		return;	single_copy();	sdp->data[index1-1] = cval;}// Set the subString at startpos with the contents of set_from.// Make room at the end if necessary.// The funny stuff with tmpstr is because we may be setting a subString// of ourselves with ourself (this is like String assign, but nastier)void String::set_substr(size_t startpos, const char * set_from, char filler){	const size_t oldlen = nchars();	if(startpos < 1){		return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -