📄 stringc.c
字号:
/* * $Id: StringC.C,v 1.6 2000/07/24 13:24:06 evgeny Exp $ * * Copyright (c) 1991 HaL Computer Systems, Inc. All rights reserved. * * HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. * 1315 Dell Avenue * Campbell, CA 95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>/* StringC.c -- implementation of character strings * * Function: * * Class StringC implements character string objects. Operations provided * include & (concatenation) and () (substring extraction). Type * conversions between StringC and char* are provided, permitting the two * to be used interchangeably in many contexts. * * */#include "StringC.h"#include "CharC.h"#include "StrCase.h"#include <unistd.h>extern int debug1, debug2;/*----------------------------------------------------------------------- * Comparison method */static intcompare(const char *cs1, u_int len1, const char *cs2, u_int len2){ if ( (!cs1 && !cs2) || (len1 == 0 && len2 == 0) ) return 0; // two nulls if ( !cs1 || len1 == 0 ) return -1; // string1 null if ( !cs2 || len2 == 0 ) return 1; // string2 null//// Check only up to the end of the shortest string// u_int minLen = MIN(len1, len2); int result = memcmp(cs1, cs2, minLen);//// If these first characters don't match return the result// If they do match and the lengths are equal, then return the result (0)// if ( result != 0 || len1 == len2 ) return result;//// If they do match and the lengths are not equal, compare the lengths// return (len1>len2 ? 1 : -1);} // End compare//---------------------------------------------------------------------------// Null stringStringC StringC::Null;/*--------------------------------------------------------------------------- * Substring constructors */SubStringC::SubStringC(const StringC& s, unsigned pos, unsigned len){ init(s, pos, len);}SubStringC::SubStringC(const StringC& s, const RangeC& r){ init(s, r.firstIndex(), r.length());}SubStringC::SubStringC(SubStringC& ss){ _parent = ss._parent; _subp = ss._subp; _sublen = ss._sublen;}/*--------------------------------------------------------------------------- * Method to initialize substring */voidSubStringC::init(const StringC& s, unsigned pos, unsigned len){ if ( pos >= s._len ) pos = len = 0; if ( pos+len > s._len ) len = s._len - pos; if ( s._p ) { _subp = &s._p[pos]; _sublen = len; } else { _subp = 0; _sublen = 0; } _parent = (StringC *)&s;} // End SubStringC init/*--------------------------------------------------------------------------- * Method to update memory allocation */voidStringC::reallocate(unsigned count, char shrinkOk){//// Allocate enough blocks to hold count chars plus the null terminator// count++; char growing = (_alloc < count); char shrinking = (shrinkOk && _alloc > 32 && count <= (_alloc>>1));//// If we're shrinking, reduce the block size until it becomes smaller than// the amount to be allocated// if ( shrinking ) { while ( BLOCK_SIZE > count && BLOCK_SIZE > 32 ) BLOCK_SIZE /= 2; }//// See if we're reallocating// if ( growing || shrinking ) {//// Count the number of memory blocks needed// unsigned blockSize = BLOCK_SIZE>0 ? BLOCK_SIZE : 32; unsigned blocks = count / blockSize; if ( count % blockSize ) blocks++; if ( blocks < 1 ) blocks = 1;//// Increase the block size if necessary for next time// if ( adjustBlock && BLOCK_SIZE < MAX_BLOCK_SIZE ) { BLOCK_SIZE *= 2; if ( BLOCK_SIZE > MAX_BLOCK_SIZE ) BLOCK_SIZE = MAX_BLOCK_SIZE; } if ( debug2 ) { cout <<"StringC::reallocate:" <<" _len=" << _len <<" _alloc=" << _alloc <<" count=" << count <<" new_alloc=" << blocks * blockSize <<endl; }//// Allocate the memory// _alloc = blocks * blockSize; char *op = _p; _p = new char[_alloc];//// Copy the old data if present// if ( op ) {//// Copy only as much as will now fit// if ( _len >= count ) _len = count-1; memcpy(_p, op, _len); _p[_len] = 0; delete [] op; } else *_p = 0; } // End if we need to reallocate} // End StringC::reallocate/*--------------------------------------------------------------------------- * Method to resize string */unsignedStringC::reSize(unsigned new_capacity){ reallocate(new_capacity, autoShrink); return (_alloc-1);}/*--------------------------------------------------------------------------- * Replace this substring with the given string * The parent of this substring can be divided into 3 parts: * * ------head-------- substring --tail-- * String: ccccccccccccccccccSSSSSSSSSSScccccccc * * The substring is replaced using this process: * 1) Copy head to another string * 2) Copy replacement to other string * 3) Copy tail to other string * 4) Copy other string to parent * 5) Reset substring length */voidSubStringC::ReplaceWith(const char *cs, u_int clen){ int spos = position(); // start position of substring//// Save the part to the right of this substring (the tail)// int tpos = spos + _sublen; int tlen = _parent->length() - tpos; StringC tail = (*_parent)(tpos,tlen);//// If the source points into the destination, we've got to make copies// if ( cs >= _parent->_p && cs <= _parent->_p + _parent->_len ) { StringC head = (*_parent)(0, spos); StringC body(clen); body.Set(cs, clen); *_parent = head; *_parent += body; *_parent += tail; } else {//// Clear the parent from the start of this substring to the end// _parent->Clear(spos);//// Add the new text and the tail// _parent->Append(cs, clen); *_parent += tail; }} // End SubStringC ReplaceWithvoidSubStringC::operator=(const StringC& s){ ReplaceWith(s._p, s._len);}voidSubStringC::operator=(const SubStringC& ss){//// It's not clear what this method should do, but the latter is more useful//#if 1 _parent = ss._parent; _subp = ss._subp; _sublen = ss._sublen;#else ReplaceWith(ss._subp, ss._sublen);#endif}voidSubStringC::operator=(const CharC& c){ ReplaceWith(c.Addr(), c.Length());}voidSubStringC::operator=(const char* cs){ ReplaceWith(cs, cs ? strlen(cs) : 0);}/*--------------------------------------------------------------------------- * Substring concatentation */StringCSubStringC::operator+(const StringC& s){ StringC t(_sublen + s._len); if ( _subp ) memcpy(t._p, _subp, _sublen); if ( s._p ) memcpy(&t._p[_sublen], s._p, s._len); t._len = _sublen + s._len; t._p[t._len] = 0; return (t);}StringCSubStringC::operator+(const SubStringC& ss){ StringC s(ss); return (operator+(s));}StringCSubStringC::operator+(const char* cs){ if (cs) { StringC s(cs); return (operator+(s)); } else { return ((StringC)*this); }}/*--------------------------------------------------------------------------- * Methods to compare against substring */intSubStringC::compare(const StringC& s) const{ return ::compare(_subp, _sublen, s._p, s._len);}intSubStringC::compare(const SubStringC& ss) const{ return ::compare(_subp, _sublen, ss._subp, ss._sublen);}intSubStringC::compare(const char *cs) const{ return ::compare(_subp, _sublen, cs, cs?strlen(cs):0);}/*--------------------------------------------------------------------------- * Return position */unsignedSubStringC::position(){ return (_subp - _parent->_p);}/*--------------------------------------------------------------------------- * String initialization methods */voidStringC::init(){ _len = 0; _alloc = 0; _p = NULL;}voidStringC::init(unsigned count){ init(); reallocate(count); *_p = 0;}voidStringC::init(const char *cs){ if ( cs ) { init((unsigned)strlen(cs)); strcpy(_p, cs); _len = strlen(cs); } else { init(); }}voidStringC::init(const SubStringC& ss){ if ( ss._subp ) { init(ss._sublen); _len = ss._sublen; memcpy(_p, ss._subp, _len); _p[_len] = 0; } else { init(); }}voidStringC::init(const CharC& c){ if ( c.Addr() ) { init(c.Length()); _len = c.Length(); memcpy(_p, c.Addr(), _len); _p[_len] = 0; } else { init(); }}voidStringC::init(const StringC& s){ if ( s._p ) { init(s._len); _len = s._len; memcpy(_p, s._p, _len); _p[_len] = 0; } else { init(); }}/*--------------------------------------------------------------------------- * Method to give us ownership of an allocated string pointer */voidStringC::Own(const char *cs){ if ( _p ) delete [] _p; _p = (char*)cs; _len = cs ? strlen(cs) : 0; _alloc = cs ? _len + 1 : 0;}/*--------------------------------------------------------------------------- * String assignment methods */voidStringC::Set(const char *cs, u_int clen){ if ( cs ) {//// If cs points into this string, make a copy// if ( cs >= _p && cs <= (_p + _len) ) { CharC data(cs, clen); StringC t(data); *this = t; } else {//// If the new string is larger or if we're allowed to shrink and the new// string requires less than half the allocated space, reallocate memory// if ( clen >= _alloc || (autoShrink && _alloc > 32 && clen <= (_alloc>>1)) ) { if ( _p ) { delete [] _p; _p = NULL; _alloc = 0; } reallocate(clen, autoShrink); } _len = clen; memcpy(_p, cs, _len); _p[_len] = 0; } } // End if source address is valid else { if ( _p ) delete [] _p; init(); }} // End Assign char* and lengthStringC&StringC::operator=(const StringC& s){ Set(s._p, s._len); return *this;}StringC&StringC::operator=(const SubStringC& ss){ Set(ss._subp, ss._sublen); return *this;}StringC&StringC::operator=(const CharC& c){ Set(c.Addr(), c.Length()); return *this;}StringC&StringC::operator=(const char *cs){ Set(cs, cs?strlen(cs):0); return *this;}/*--------------------------------------------------------------------------- * String concatentation methods */voidStringC::Add(const char *p1, u_int len1, const char *p2, u_int len2, StringC& t)const{ if ( p1 ) memcpy(t._p, p1, len1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -