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

📄 pstring.cxx

📁 PTypes (C++ Portable Types Library) is a simple alternative to the STL that includes multithreading
💻 CXX
字号:
/* * *  C++ Portable Types Library (PTypes) *  Version 1.7.5   Released 9-Mar-2003 * *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan * *  http://www.melikyan.com/ptypes/ *  http://ptypes.sourceforge.net/ * */#include <stdlib.h>#include <string.h>#include <time.h>#include "ptypes.h"#include "pasync.h"	// for atomic increment and decrement#include "ptime.h"      // nowstring is defined in this modulePTYPES_BEGINstatic void stringoverflow() {    fatal(CRIT_FIRST + 21, "String overflow");}const int quant = 64;const int qmask = ~63;const int quant2 = 4096;const int qmask2 = ~4095;int stralloc;char   emptystrbuf[strrecsize + 4];char*  emptystr = emptystrbuf + strrecsize;string nullstring;static int quantize(int numchars) {    int numalloc = numchars + 1 + strrecsize;    if (numalloc <= 16)        return 16;    if (numalloc <= 32)        return 32;    else if (numalloc <= 2048)        return (numalloc + quant - 1) & qmask;    else        return (numalloc + quant2 - 1) & qmask2;}void string::_alloc(int numchars) {    if (numchars <= 0) stringoverflow();    size_t a = quantize(numchars);#ifdef DEBUG    stralloc += a;#endif    data = (char*)(memalloc(a)) + strrecsize;    STR_LENGTH(data) = numchars;    STR_REFCOUNT(data) = 1;    data[numchars] = 0;}void string::_realloc(int numchars) {    if (numchars <= 0 || STR_LENGTH(data) <= 0)        stringoverflow();    int a = quantize(numchars);    int b = quantize(STR_LENGTH(data));    if (a != b)    {#ifdef DEBUG        stralloc += a - b;#endif        data = (char*)(memrealloc(data - strrecsize, a)) + strrecsize;    }    STR_LENGTH(data) = numchars;    data[numchars] = 0;}void string::_free() {#ifdef DEBUG    stralloc -= quantize(STR_LENGTH(data));#endif    memfree((char*)(STR_BASE(data)));    data = emptystr;}void string::initialize(const char* sc, int initlen) {    if (initlen <= 0 || sc == nil)        data = emptystr;     else     {        _alloc(initlen);        memmove(data, sc, initlen);    }}void string::initialize(const char* sc) {    initialize(sc, hstrlen(sc));}void string::initialize(char c) {    _alloc(1);    data[0] = c;}void string::initialize(const string& s){    data = s.data;    pincrement(&STR_REFCOUNT(data));}void string::finalize() {    if (STR_LENGTH(data) != 0)        if (pdecrement(&STR_REFCOUNT(data)) == 0)            _free();    data = emptystr;}/*//// a fatser, single-threaded version of unique()// will be used in the future for the single-threaded version of PTypes// char* unique(string& s) {    if (!isempty(s) && refcount(s) > 1)    {        char* olddata = s.data;        s._alloc(length(s));        memcpy(s.data, olddata, length(s));        STR_REFCOUNT(olddata)--;    }    return s.data;}*/char* unique(string& s) {    if (STR_LENGTH(s.data) != 0)    {        // by incrementing the refcount for this object we "lock" the buffer        // from being concurrently unique'd        // if refcount > 2 it means it was actually > 1 before        if (pincrement(&STR_REFCOUNT(s.data)) > 2)        {            string t;            int len = STR_LENGTH(s.data);            // the refcount is already incremented, so that we can assign the pointer directly            t.data = s.data;            // allocate and copy data            s._alloc(len);            memcpy(s.data, t.data, len);            // we must decrement refcount for t since we detached its buffer 'illegally'            pdecrement(&STR_REFCOUNT(t.data));            // here the destructor for t is being called; the buffer may be freed            // if string buffer was detached concurrently        }        else            // refcount was 1 before incrementing, so we can assign it directly            // instead of costly pdecrement()            STR_REFCOUNT(s.data) = 1;    }    return s.data;}void setlength(string& s, int newlen){    int curlen = length(s);    if (newlen < 0)         return;        // if becoming empty    if (newlen == 0)        s.finalize();        // if otherwise s was empty before    else if (curlen == 0)        s._alloc(newlen);    // if length is not changing, return a unique string    else if (newlen == curlen)        unique(s);    // thread-safe reallocation; see comments in unique()    else    {        if (pincrement(&STR_REFCOUNT(s.data)) > 2)        {            string t;            t.data = s.data;            s._alloc(newlen);            memcpy(s.data, t.data, imin(curlen, newlen));            pdecrement(&STR_REFCOUNT(t.data));        }        else        {            STR_REFCOUNT(s.data) = 1;            s._realloc(newlen);        }    }}void string::assign(const char* sc, int initlen) {    if (STR_LENGTH(data) > 0 && initlen > 0)    {        // thread-safe assignment with possible        // reuse of the buffer        if (pincrement(&STR_REFCOUNT(data)) > 2)        {            string t;            t.data= data;            _alloc(initlen);            memcpy(data, sc, initlen);            pdecrement(&STR_REFCOUNT(t.data));        }        else        {            STR_REFCOUNT(data) = 1;            _realloc(initlen);            memmove(data, sc, initlen);        }    }    else    {        finalize();        if (initlen == 1)            initialize(sc[0]);        else            initialize(sc, initlen);    }}void string::assign(const char* sc) {    assign(sc, hstrlen(sc));}void string::assign(char c) {    assign(&c, 1);}void string::assign(const string& s) {    if (data != s.data)    {        finalize();        initialize(s);    }}string dup(const string& s){    return string(s.data, length(s));}string nowstring(const char* fmt, bool utc){    time_t longtime;    time(&longtime);    tm* t;    if (utc)        t = gmtime(&longtime);    else        t = localtime(&longtime);    char buf[128];    int r = strftime(buf, sizeof(buf), fmt, t);    buf[r] = 0;    return string(buf);}PTYPES_END

⌨️ 快捷键说明

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