/* * Copyright 1995, 1996 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ /* * StrBuf.h - multipurpose buffers * * StrPtr, StrRef, and StrBuf are used throughout the system, as buffers * for storing just about any variable length byte data. * * StrPtr is a low-cost (no constructor, no destructor, 8 byte) * pointer/length pair to mutable data. It has a variety of methods * to mangle it. * * StrRef is a kind-of StrPtr that allows the buffer pointer to be set. * As StrPtr doesn't allow this, a StrPtr object itself isn't useful. * * StrNum is a kind-of StrPtr with a temporary buffer whose only purpose * is to hold the string representation of an int. * * StrBuf is a kind-of StrPtr that allocates and extends it own buffer. * * StrFixed is a kind-of StrPtr that points to a character array that * is fixed at construction. * * Classes: * * StrPtr - a pointer/length for arbitrary data * StrRef - StrPtr that can be set * StrBuf - StrPtr of privately allocated data * StrFixed - StrPtr to a fixed length char buffer * StrNum - StrPtr that holds a string of an int * StrHuman - StrPtr that holds a "human-readable" string of an int * * Methods: * * StrPtr::Clear() - set length = 0 * StrPtr::Text() - return buffer pointer * StrPtr::Value() - return buffer pointer (old name) * StrPtr::Length() - return buffer length * StrPtr::GetEnd() - return pointer to character past end * StrPtr::Atoi() - convert to integer and return * StrPtr::Atoi64() - convert to P4INT64 and return * StrPtr::Itoa() - format an int given the end of a buffer * StrPtr::Itoa64() - format a P4INT64 given the end of a buffer * StrPtr::SetLength() - set only length * StrPtr::SetEnd() - set length by calculating from start * StrPtr::[] - get a single character * StrPtr::XCompare() - case exact string compare * StrPtr::CCompare() - case folding string compare * StrPtr::SCompare() - case aware string compare -- see strbuf.cc * StrPtr::SEqual() - case aware character compare -- see strbuf.cc * StrPtr::Contains() - finds a substring * StrPtr::== - compare contents with buffer * StrPtr::!= - compare contents with buffer * StrPtr::< - compare contents with buffer * StrPtr::<= - compare contents with buffer * StrPtr::> - compare contents with buffer * StrPtr::>= - compare contents with buffer * StrPtr::StrCpy() - copy string out to a buffer * StrPtr::StrCat() - copy string out to end of a buffer * StrPtr::CaseFolding() - (static) SCompare sorts A < a, a < B * StrPtr::CaseIgnored() - (static) SCompare sorts A == a, a < B * StrPtr::CaseHybrid() - (static) SCompare sorts Ax < ax, aa < AX * StrPtr::SetCaseFolding() - (static) 0=UNIX, 1=NT, 2=HYBRID * * --- * * StrRef::Set() - set pointer/length * StrRef::+= - move pointer/length * * --- * * StrBuf::StringInit() - mimic actions of constructor * StrBuf::Set() - allocate and fill from buffer * StrBuf::Append() - extend and terminate from buffer * StrBuf::Extend() - append contents from buffer * StrBuf::Terminate() - terminate buffer * StrBuf::Alloc() - allocate space in buffer and return pointer * StrBuf::<< - Append contents from buffer or number * StrBuf::Indent() - fill by indenting contents of another buffer * StrBuf::Expand() - expand a string doing %var substitutions * */ class StrBuf; // On 64 bit platforms, the base 'size_t' type is 64 bits, which is much // more than we need, or can handle. So we use our own size_t type instead; // it's "p4size_t", defined in stdhdrs.h // General String Buffer Sizes # define SIZE_LINESTR 256 # define SIZE_SMALLSTR 1024 # define SIZE_MEDSTR 4096 class StrPtr { public: // Setting, getting char * Text() const { return buffer; } char * Value() const { return buffer; } unsigned char *UText() const { return (unsigned char *)Text(); } p4size_t Length() const { return length; } char * End() const { return Text() + length; } unsigned char *UEnd() const { return UText() + length; } int Atoi() const { return Atoi( buffer ); } bool IsNumeric() const; int EndsWith( const char *s, int l ) const; P4INT64 Atoi64() const { return Atoi64( buffer ); } void SetLength() { length = strlen( buffer ); } void SetLength( p4size_t len ) { length = len; } void SetEnd( char *p ) { length = p - buffer; } char operator[]( p4size_t x ) const { return buffer[x]; } // Compare -- p4ftp legacy int Compare( const StrPtr &s ) const { return SCompare( s ); } // CCompare/SCompare/XCompare int CCompare( const StrPtr &s ) const { return CCompare( buffer, s.buffer ); } int SCompare( const StrPtr &s ) const { return SCompare( buffer, s.buffer ); } int NCompare( const StrPtr &s ) const { return NCompare( buffer, s.buffer ); } static int CCompare( const char *a, const char *b ); static int SCompare( const char *a, const char *b ); static int NCompare( const char *a, const char *b ); static int SCompare( unsigned char a, unsigned char b ) { return a==b ? 0 : SCompareF( a, b ); } static int SEqual( unsigned char a, unsigned char b ) { switch( a^b ) { default: return 0; case 0: return 1; case 'A'^'a': return SEqualF( a, b ); } } int SCompareN( const StrPtr &s ) const; int XCompare( const StrPtr &s ) const { return strcmp( buffer, s.buffer ); } static int XCompare( const char *a, const char *b ) { return strcmp( a, b ); } int XCompareN( const StrPtr &s ) const { return strncmp( buffer, s.buffer, length ); } // More comparing const char *Contains( const StrPtr &s ) const { return strstr( Text(), s.Text() ); } bool operator ==( const char *buf ) const { return strcmp( buffer, buf ) == 0; } bool operator !=( const char *buf ) const { return strcmp( buffer, buf ) != 0; } bool operator <( const char *buf ) const { return strcmp( buffer, buf ) < 0; } bool operator <=( const char *buf ) const { return strcmp( buffer, buf ) <= 0; } bool operator >( const char *buf ) const { return strcmp( buffer, buf ) > 0; } bool operator >=( const char *buf ) const { return strcmp( buffer, buf ) >= 0; } bool operator ==( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) == 0; } bool operator !=( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) != 0; } bool operator <( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) < 0; } bool operator <=( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) <= 0; } bool operator >( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) > 0; } bool operator >=( const StrPtr &s ) const { return strcmp( buffer, s.buffer ) >= 0; } // Copying out // Includes EOS void StrCpy( char *b ) const { memcpy( b, buffer, length + 1 ); } void StrCat( char *b ) const { memcpy( b + strlen( b ), buffer, length + 1 ); } // Formatting and parsing numbers as strings static int Atoi( const char *b ) { return atoi( b ); } static char *Itoa( int v, char *e ) { return Itoa64( v, e ); } static P4INT64 Atoi64( const char *buffer ); static char *Itoa64( P4INT64 v, char *endbuf ); static char *Itox( unsigned int v, char *endbuf ); friend class StrBuf; friend class StrRef; protected: char *buffer; p4size_t length; public: // Case sensitive server? static bool CaseFolding() { return caseUse != ST_UNIX; } static bool CaseIgnored() { return caseUse == ST_WINDOWS; } static bool CaseHybrid() { return caseUse == ST_HYBRID; } static void SetCaseFolding( int c ) { caseUse = (CaseUse)c; foldingSet = true; } static bool CaseFoldingAlreadySet() { return foldingSet; } enum CaseUse { ST_UNIX, ST_WINDOWS, ST_HYBRID }; static CaseUse CaseUsage() { return caseUse; } private: static CaseUse caseUse; static bool foldingSet; static int SEqualF( unsigned char a, unsigned char b ); static int SCompareF( unsigned char a, unsigned char b ); static int NCompareLeft( const unsigned char *a, const unsigned char *b ); static int NCompareRight( const unsigned char *a, const unsigned char *b ); } ; class StrRef : public StrPtr { public: StrRef() {} StrRef( const StrRef &s ) { Set( &s ); } StrRef( const StrPtr &s ) { Set( &s ); } StrRef( const char *buf ) { Set( (char *)buf ); } StrRef( const char *buf, p4size_t len ) { Set( (char *)buf, len ); } static const StrPtr &Null() { return null; } const StrRef & operator =(const StrRef &s) { Set( &s ); return *this; } const StrRef & operator =(const StrPtr &s) { Set( &s ); return *this; } const StrRef & operator =(const char *buf) { Set( (char *)buf ); return *this; } void operator +=( int l ) { buffer += l; length -= l; } void Set( char *buf ) { Set( buf, strlen( buf ) ); } void Set( char *buf, p4size_t len ) { buffer = buf; length = len; } void Set( const StrPtr *s ) { Set( s->buffer, s->length ); } void Set( const StrPtr &s ) { Set( s.buffer, s.length ); } private: static StrRef null; } ; class StrBuf : public StrPtr { public: StrBuf() { StringInit(); } void StringInit() { length = size = 0; buffer = nullStrBuf; } ~StrBuf() { if( buffer != nullStrBuf ) delete []buffer; } // copy constructor, assignment StrBuf( const StrBuf &s ) { StringInit(); Set( &s ); } StrBuf( const StrRef &s ) { StringInit(); Set( &s ); } StrBuf( const StrPtr &s ) { StringInit(); Set( &s ); } StrBuf( const char *buf ) { StringInit(); Set( buf ); } const StrBuf & operator =(const StrBuf &s) { if( this != &s ) Set( &s ); return *this; } const StrBuf & operator =(const StrRef &s) { if( (const StrRef *)this != &s ) Set( &s ); return *this; } const StrBuf & operator =(const StrPtr &s) { if( this != &s ) Set( &s ); return *this; } const StrBuf & operator =(const char *buf) { if( (const char*)this != buf && buffer != buf ) Set( buf ); return *this; } // Setting, getting void Clear( void ) { length = 0; } void Reset( void ) { if( buffer != nullStrBuf ) { delete []buffer; length = size = 0; buffer = nullStrBuf; } } void Reset( const char *buf ) { Reset(); UAppend( buf ); } void Reset( const StrPtr *s ) { Reset(); UAppend( s ); } void Reset( const StrPtr &s ) { Reset(); UAppend( &s ); } void Set( const char *buf ) { if( buf == Text() ) SetLength(); else { Clear(); Append( buf ); } } void Set( const StrPtr *s ) { if( s != this ) { Clear(); UAppend( s ); } } void Set( const StrPtr &s ) { if( &s != this ) { Clear(); UAppend( &s ); } } void Set( const char *buf, p4size_t len ) { if( buf == Text() ) SetLength( len ); else { Clear(); Append( buf, len ); } } void Extend( const char *buf, p4size_t len ) { memcpy( Alloc( len ), buf, len ); } void Extend( char c ) { *Alloc(1) = c; } void Terminate() { Extend(0); --length; } void TruncateBlanks(); // Removes blanks just from the end void TrimBlanks(); // Removes blanks from start and end void Append( const char *buf ); void Append( const StrPtr *s ); void Append( const char *buf, p4size_t len ); void UAppend( const char *buf ); void UAppend( const StrPtr *s ); void UAppend( const char *buf, p4size_t len ); // large-block append void BlockAppend( const char *buf ); void BlockAppend( const StrPtr *s ); void BlockAppend( const char *buf, p4size_t len ); void UBlockAppend( const char *buf ); void UBlockAppend( const StrPtr *s ); void UBlockAppend( const char *buf, p4size_t len ); char * Alloc( p4size_t len ) { p4size_t oldlen = length; if( ( length += len ) > size ) Grow( oldlen ); return buffer + oldlen; } // large block (>= 128KB) allocation; no extra space is reserved char * BlockAlloc( p4size_t len ) { p4size_t oldlen = length; if( ( length += len ) > size ) Reserve( oldlen ); return buffer + oldlen; } void Fill( const char *buf, p4size_t len ); void Fill( const char *buf ) { Fill( buf, Length() ); } p4size_t BufSize() const { return size; } // leading-string compression void Compress( StrPtr *s ); void UnCompress( StrPtr *s ); // trailing-string compression int EncodeTail( StrPtr &s, const char *replaceBytes ); int DecodeTail( StrPtr &s, const char *replaceBytes ); // string << -- append string/number StrBuf& operator <<( const char *s ) { Append( s ); return *this; } StrBuf& operator <<( const StrPtr *s ) { Append( s ); return *this; } StrBuf& operator <<( const StrPtr &s ) { Append( &s ); return *this; } StrBuf& operator <<( int v ); private: p4size_t size; void Grow( p4size_t len ); // reserve a large block of memory (>= 128 KB); don't over-allocate void Reserve( p4size_t oldlen ); // Some DbCompare funcs memcpy from this, so it has be be big // enough that we aren't reaching past valid memory. The // largest one seems to be DbInt64 (8 bytes.) static char nullStrBuf[ 8 ]; } ; class StrFixed : public StrPtr { public: StrFixed( p4size_t l ) { this->length = l; this->buffer = new char[ l ]; } ~StrFixed() { delete []buffer; } void SetBufferSize( p4size_t l ); } ; class StrNum : public StrPtr { public: StrNum() {} StrNum( int v ) { Set( v ); } StrNum( int ok, int v ) { if( ok ) Set( v ); else buffer = buf, length = 0; } void Set( int v ) { buffer = Itoa( v, buf + sizeof( buf ) ); length = buf + sizeof( buf ) - buffer - 1; } void SetHex( int v ) { buffer = Itox( v, buf + sizeof( buf ) ); length = buf + sizeof( buf ) - buffer - 1; } void Set( int v, int digits ) { Set( v ); while( (int)length < digits ) *--buffer = '0', ++length; } # ifdef HAVE_INT64 StrNum( long v ) { Set( (P4INT64)v ); } StrNum( P4INT64 v ) { Set( v ); } void Set( P4INT64 v ) { buffer = Itoa64( v, buf + sizeof( buf ) ); length = buf + sizeof( buf ) - buffer - 1; } # endif private: char buf[24]; } ; class StrHuman : public StrPtr { public: StrHuman() {} StrHuman( long v, int f = 1024 ) { Convert( (P4INT64)v, f ); } StrHuman( P4INT64 v, int f = 1024 ) { Convert( v, f ); } static char *Itoa64( P4INT64 v, char *endbuf, int f ); private: void Convert( P4INT64 v, int f ) { buffer = Itoa64( v, buf + sizeof( buf ), f ); length = buf + sizeof( buf ) - buffer - 1; } char buf[24]; } ;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 16129 | tjuricek |
Rename/move files again... this time to the hyphenated-approach. |
||
//guest/tjuricek/file_system_client/main/vendor/p4api-15.1/macosx105x86_64/include/p4/strbuf.h | |||||
#1 | 16119 | tjuricek | Rename/move to meet workshop project conventions. | ||
//guest/tjuricek/fsclient/vendor/p4api-15.1/macosx105x86_64/include/p4/strbuf.h | |||||
#1 | 16118 | tjuricek |
FSClient initial version: handles add, edit This is a proof-of-concept app that mirrors an existing Perforce workspace to handle running commands like "p4 add" and "p4 edit" automatically when your apps add and write files. See the readme for more information. |