Added custom string class that mirrors the C++ std::string API but also allows for fixed size buffers on the stack. This new class also has various C style functions (like sprintf) built into it.
This commit is contained in:
parent
0123e1fbf8
commit
6832eaa964
|
@ -0,0 +1,274 @@
|
||||||
|
// StringUtils.h
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
// C Style string copy function that guarantees null termination
|
||||||
|
inline char *Strlcpy( char* dest, const char* src, size_t n )
|
||||||
|
{
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
size_t i=0;
|
||||||
|
n--; // minus 1 to make sure we have room for null byte
|
||||||
|
while ( (i < n) && (src[i] != 0) )
|
||||||
|
{
|
||||||
|
dest[i] = src[i]; i++;
|
||||||
|
}
|
||||||
|
dest[i] = 0; // Force Null
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// Custom string type that will allows for fixed size strings on using stack memory with a similar C++ std::string API
|
||||||
|
namespace FCEU
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
class BaseString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BaseString(T* buffer = nullptr, size_t size = 0)
|
||||||
|
{
|
||||||
|
buf = buffer;
|
||||||
|
bufSize = size;
|
||||||
|
end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& assign( const T* str )
|
||||||
|
{
|
||||||
|
if (bufSize > 0)
|
||||||
|
{
|
||||||
|
size_t i=0;
|
||||||
|
const size_t bufEnd = bufSize - 1;
|
||||||
|
while ( (i < bufEnd) && (str[i] != 0) )
|
||||||
|
{
|
||||||
|
buf[i] = str[i]; i++;
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
end = i;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& assign( BaseString& s )
|
||||||
|
{
|
||||||
|
assign( s.buf );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& assign( std::string& s )
|
||||||
|
{
|
||||||
|
assign( s.c_str() );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& append( const T* str )
|
||||||
|
{
|
||||||
|
if (bufSize > 0)
|
||||||
|
{
|
||||||
|
size_t j=0;
|
||||||
|
size_t i=end;
|
||||||
|
const size_t bufEnd = bufSize - 1;
|
||||||
|
while ( (i < bufEnd) && (str[j] != 0) )
|
||||||
|
{
|
||||||
|
buf[i] = str[j]; i++; j++;
|
||||||
|
}
|
||||||
|
buf[i] = 0;
|
||||||
|
end = i;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& append( BaseString& s )
|
||||||
|
{
|
||||||
|
append( s.buf );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& append( std::string& s )
|
||||||
|
{
|
||||||
|
append( s.c_str() );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& operator= (const T* op)
|
||||||
|
{
|
||||||
|
assign(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString& operator= (BaseString& op)
|
||||||
|
{
|
||||||
|
assign(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[] (int idx)
|
||||||
|
{
|
||||||
|
return buf[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
if (bufSize > 0)
|
||||||
|
{
|
||||||
|
buf[0] = 0;
|
||||||
|
}
|
||||||
|
end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* c_str()
|
||||||
|
{
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size()
|
||||||
|
{
|
||||||
|
return end;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toStdString()
|
||||||
|
{
|
||||||
|
return std::string(c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int sprintf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 2, 3 )
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
retval = ::vsnprintf( buf, bufSize, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int append_sprintf( __FCEU_PRINTF_FORMAT const char *format, ...) __FCEU_PRINTF_ATTRIBUTE( 2, 3 )
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
size_t sizeAvail = 0;
|
||||||
|
if (bufSize > end)
|
||||||
|
{
|
||||||
|
sizeAvail = bufSize - end;
|
||||||
|
}
|
||||||
|
retval = ::vsnprintf( &buf[end], sizeAvail, format, args);
|
||||||
|
va_end(args);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
long strtol(int base = 10)
|
||||||
|
{
|
||||||
|
return ::strtol(buf, nullptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
long long strtoll(int base = 10)
|
||||||
|
{
|
||||||
|
return ::strtoll(buf, nullptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long strtoul(int base = 10)
|
||||||
|
{
|
||||||
|
return ::strtoul(buf, nullptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long long strtoull(int base = 10)
|
||||||
|
{
|
||||||
|
return ::strtoull(buf, nullptr, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* buf;
|
||||||
|
size_t bufSize;
|
||||||
|
size_t end;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <size_t N, typename T = char>
|
||||||
|
class FixedString : public BaseString<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FixedString()
|
||||||
|
: BaseString<T>( fixedBuffer, N )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
FixedString(const char* initValue)
|
||||||
|
: BaseString<T>( fixedBuffer, N )
|
||||||
|
{
|
||||||
|
if (initValue != nullptr)
|
||||||
|
{
|
||||||
|
BaseString<T>::assign(initValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator= (const T* op)
|
||||||
|
{
|
||||||
|
BaseString<T>::assign(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator= (BaseString<T>& op)
|
||||||
|
{
|
||||||
|
BaseString<T>::assign(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator= (std::string& op)
|
||||||
|
{
|
||||||
|
BaseString<T>::assign(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator+= (const T* op)
|
||||||
|
{
|
||||||
|
BaseString<T>::append(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator+= (BaseString<T>& op)
|
||||||
|
{
|
||||||
|
BaseString<T>::append(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseString<T>& operator+= (std::string& op)
|
||||||
|
{
|
||||||
|
BaseString<T>::append(op);
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[] (int idx)
|
||||||
|
{
|
||||||
|
return fixedBuffer[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T fixedBuffer[N];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue