📄 pstring.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 + -