diff options
Diffstat (limited to 'Src/Wasabi/bfc/util')
-rw-r--r-- | Src/Wasabi/bfc/util/base64.cpp | 315 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/base64.h | 16 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/findopenrect.cpp | 251 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/findopenrect.h | 63 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/inifile.cpp | 56 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/inifile.h | 28 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/profile.c | 288 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/profile.h | 26 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/profiler.cpp | 6 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/profiler.h | 128 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/timefmt.cpp | 71 | ||||
-rw-r--r-- | Src/Wasabi/bfc/util/timefmt.h | 46 |
12 files changed, 1294 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/util/base64.cpp b/Src/Wasabi/bfc/util/base64.cpp new file mode 100644 index 00000000..1a67b9f1 --- /dev/null +++ b/Src/Wasabi/bfc/util/base64.cpp @@ -0,0 +1,315 @@ +/* Based on code from Dave Winer (http://www.scripting.com/midas/base64/) */ +#include "precomp_wasabi_bfc.h" +#include "base64.h" + +char Base64::encodingTable [64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + +int Base64::encode(MemBlock<char> &htext, MemBlock<char> &h64, int linelength) { + /* + encode the handle. some funny stuff about linelength -- it only makes + sense to make it a multiple of 4. if it's not a multiple of 4, we make it + so (by only checking it every 4 characters. + further, if it's 0, we don't add any line breaks at all. + */ + unsigned long ixtext; + unsigned long lentext; + unsigned long origsize; + long ctremaining; + unsigned char inbuf [3] = {0}, outbuf [4] = {0}; + short i; + short charsonline = 0, ctcopy; + + ixtext = 0; + + lentext = htext.getSize(); + + while (1) { + ctremaining = lentext - ixtext; + + if (ctremaining <= 0) + break; + + for (i = 0; i < 3; i++) { + unsigned long ix = ixtext + i; + if (ix < lentext) + inbuf [i] = *htext.getMemory(ix); + else + inbuf [i] = 0; + } + + outbuf [0] = (inbuf [0] & 0xFC) >> 2; + outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); + outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); + outbuf [3] = inbuf [2] & 0x3F; + + origsize = h64.getSize(); + h64.setSize(origsize + 4); + + ctcopy = 4; + + switch (ctremaining) { + case 1: + ctcopy = 2; + break; + case 2: + ctcopy = 3; + break; + } + + for (i = 0; i < ctcopy; i++) + *h64.getMemory(origsize + i) = encodingTable[outbuf[i]]; + + for (i = ctcopy; i < 4; i++) + *h64.getMemory(origsize + i) = '='; + + ixtext += 3; + charsonline += 4; + + if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ + if (charsonline >= linelength) { + charsonline = 0; + origsize = h64.getSize(); + h64.setSize(origsize + 1); + *h64.getMemory() = '\n'; + } + } + } + return 1; +} +int Base64::encode(MemBlock<char> &htext, MemBlock<wchar_t> &h64, int linelength) { + /* + encode the handle. some funny stuff about linelength -- it only makes + sense to make it a multiple of 4. if it's not a multiple of 4, we make it + so (by only checking it every 4 characters. + further, if it's 0, we don't add any line breaks at all. + */ + unsigned long ixtext; + unsigned long lentext; + unsigned long origsize; + long ctremaining; + unsigned char inbuf [3] = {0}, outbuf [4] = {0}; + short i; + short charsonline = 0, ctcopy; + + ixtext = 0; + + lentext = htext.getSize(); + + while (1) { + ctremaining = lentext - ixtext; + + if (ctremaining <= 0) + break; + + for (i = 0; i < 3; i++) { + unsigned long ix = ixtext + i; + if (ix < lentext) + inbuf [i] = *htext.getMemory(ix); + else + inbuf [i] = 0; + } + + outbuf [0] = (inbuf [0] & 0xFC) >> 2; + outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); + outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); + outbuf [3] = inbuf [2] & 0x3F; + + origsize = h64.getSize(); + h64.setSize(origsize + 4); + + ctcopy = 4; + + switch (ctremaining) { + case 1: + ctcopy = 2; + break; + case 2: + ctcopy = 3; + break; + } + + for (i = 0; i < ctcopy; i++) + *h64.getMemory(origsize + i) = encodingTable[outbuf[i]]; + + for (i = ctcopy; i < 4; i++) + *h64.getMemory(origsize + i) = '='; + + ixtext += 3; + charsonline += 4; + + if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/ + if (charsonline >= linelength) { + charsonline = 0; + origsize = h64.getSize(); + h64.setSize(origsize + 1); + *h64.getMemory() = '\n'; + } + } + } + return 1; +} + + +int Base64::decode(MemBlock<char> &h64, MemBlock<char> &htext) { + unsigned long ixtext; + unsigned long lentext; + unsigned long origsize; + unsigned char ch; + unsigned char inbuf [4] = {0}, outbuf [4] = {0}; + short i, ixinbuf; + boolean flignore; + boolean flendtext = false; + + ixtext = 0; + + lentext = h64.getSize(); + + ixinbuf = 0; + + while (true) { + if (ixtext >= lentext) + break; + ch = *h64.getMemory(ixtext++); + + flignore = 0; + + if ((ch >= 'A') && (ch <= 'Z')) + ch = ch - 'A'; + else if ((ch >= 'a') && (ch <= 'z')) + ch = ch - 'a' + 26; + else if ((ch >= '0') && (ch <= '9')) + ch = ch - '0' + 52; + else if (ch == '+') + ch = 62; + else if (ch == '=') /*no op -- can't ignore this one*/ + flendtext = true; + else if (ch == '/') + ch = 63; + else + flignore = true; + + if (!flignore) { + short ctcharsinbuf = 3; + boolean flbreak = false; + + if (flendtext) { + if (ixinbuf == 0) + break; + + if ((ixinbuf == 1) || (ixinbuf == 2)) + ctcharsinbuf = 1; + else + ctcharsinbuf = 2; + + ixinbuf = 3; + flbreak = 1; + } + + inbuf [ixinbuf++] = ch; + + if (ixinbuf == 4) { + ixinbuf = 0; + + outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); + outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); + outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); + + origsize = htext.getSize(); + htext.setSize(origsize + ctcharsinbuf); + + for (i = 0; i < ctcharsinbuf; i++) + *htext.getMemory(origsize + i) = outbuf[i]; + } + + if (flbreak) + break; + } + } + + return 1; +} +int Base64::decode(MemBlock<wchar_t> &h64, MemBlock<char> &htext) { + unsigned long ixtext; + unsigned long lentext; + unsigned long origsize; + unsigned char ch; + unsigned char inbuf [4] = {0}, outbuf [4] = {0}; + short i, ixinbuf; + boolean flignore; + boolean flendtext = false; + + ixtext = 0; + + lentext = h64.getSize(); + + ixinbuf = 0; + + while (true) { + if (ixtext >= lentext) + break; + ch = (unsigned char)*h64.getMemory(ixtext++); + + flignore = 0; + + if ((ch >= 'A') && (ch <= 'Z')) + ch = ch - 'A'; + else if ((ch >= 'a') && (ch <= 'z')) + ch = ch - 'a' + 26; + else if ((ch >= '0') && (ch <= '9')) + ch = ch - '0' + 52; + else if (ch == '+') + ch = 62; + else if (ch == '=') /*no op -- can't ignore this one*/ + flendtext = true; + else if (ch == '/') + ch = 63; + else + flignore = true; + + if (!flignore) { + short ctcharsinbuf = 3; + boolean flbreak = false; + + if (flendtext) { + if (ixinbuf == 0) + break; + + if ((ixinbuf == 1) || (ixinbuf == 2)) + ctcharsinbuf = 1; + else + ctcharsinbuf = 2; + + ixinbuf = 3; + flbreak = 1; + } + + inbuf [ixinbuf++] = ch; + + if (ixinbuf == 4) { + ixinbuf = 0; + + outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4); + outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2); + outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F); + + origsize = htext.getSize(); + htext.setSize(origsize + ctcharsinbuf); + + for (i = 0; i < ctcharsinbuf; i++) + *htext.getMemory(origsize + i) = outbuf[i]; + } + + if (flbreak) + break; + } + } + + return 1; +} + + diff --git a/Src/Wasabi/bfc/util/base64.h b/Src/Wasabi/bfc/util/base64.h new file mode 100644 index 00000000..fc4fd658 --- /dev/null +++ b/Src/Wasabi/bfc/util/base64.h @@ -0,0 +1,16 @@ +#ifndef _BASE64_H +#define _BASE64_H + +#include <bfc/memblock.h> + +class Base64 { +public: + static int decode(MemBlock<wchar_t> &h64, MemBlock<char> &htext); + static int decode(MemBlock<char> &h64, MemBlock<char> &htext); + static int encode(MemBlock<char> &htext, MemBlock<char> &h64, int linelength); + static int encode(MemBlock<char> &htext, MemBlock<wchar_t> &h64, int linelength); +private: + static char encodingTable[64]; +}; + +#endif diff --git a/Src/Wasabi/bfc/util/findopenrect.cpp b/Src/Wasabi/bfc/util/findopenrect.cpp new file mode 100644 index 00000000..537651d2 --- /dev/null +++ b/Src/Wasabi/bfc/util/findopenrect.cpp @@ -0,0 +1,251 @@ +#include <precomp.h> +#include "findopenrect.h" + +#include <bfc/pair.h> + +//CUT #define MAXTRIALS 10000 // unless time runs out +#define MOUSEPENALTY 65536 + +FindOpenRect::FindOpenRect() +{ + timelimit = 100; + iters = 0; + xdiv = ydiv = 1; + fn = compare_overlapArea; + userdata = userdata2 = 0; + bsfval = bsfdist = 0; +} + +void FindOpenRect::setCompareRectsFn(compareRectsFn _fn) +{ + fn = _fn; +} + +RECT FindOpenRect::find(const RECT &vr, const PtrList<RECT> &list, const RECT &prev, unsigned long userdata, unsigned long userdata2) +{ + beginFind(vr, list, prev, userdata, userdata2); + return findMore(); +} + +void FindOpenRect::beginFind(const RECT &viewport, const PtrList<RECT> &_list, + const RECT &_prev, unsigned long _userdata, unsigned long _userdata2) +{ + vr = viewport; + list.copyFrom(&_list); + prev = _prev; + userdata = _userdata; + userdata2 = _userdata2; + + // reset best rect found so far + //CUT bsf_nooverlap = prev; + //CUT found_nooverlap=0; + //CUT bsf_overlap = prev; + //CUT bsfval_nooverlap = 1e100; + //CUT bsfval_overlap = 1e100; + bsfrect = prev; + bsfval = 10e10; + bsfdist = 10e10; + + //CUT POINT mousepos; + //CUT Std::getMousePos(&mousepos); +} + +RECT FindOpenRect::findMore() +{ + int w = prev.right - prev.left, h = prev.bottom - prev.top; + int vw = vr.right - vr.left; + int vh = vr.bottom - vr.top; + + if (vw <= w || vh <= h) + { + DebugStringW(L"findopenrect: window too big for viewport"); + } + + + double started = Wasabi::Std::getTimeStampMS(); + + for (int c = 0; /*CUTc < MAXTRIALS*/; c++) + { + + // too bad = crashy crash :P love, BU + if (c != 0 && (vw <= w || vh <= h)) + break; + + // set the trial rect + RECT tr; + if (iters == 0) + { // try prev + tr = prev; + } + else + { + int x = Wasabi::Std::random32(vw - w) + vr.top; + int y = Wasabi::Std::random32(vh - h) + vr.left; + if (xdiv != 1) x -= x % xdiv; + if (ydiv != 1) y -= y % ydiv; + tr = Wasabi::Std::makeRect(x, y, x + w, y + h); + } + + // add up the coverage of trial position + trySingleRect(tr, TRUE); + + if (timelimit > 0 && c > 0 && (int)((Wasabi::Std::getTimeStampMS() - started)*1000.f) > timelimit) + { + // DebugString("FindOpenRect::find() timeout, %d iters", c); + break; + } + } + + return getBestRectSoFar(); +} + +typedef Pair<RECT, double> RectV; + +namespace +{ + class Sorter + { + public: + static int compareItem(RectV *p1, RectV* p2) + { + return -CMP3(p1->b, p2->b); + } + }; +}; + +double FindOpenRect::trySingleRect(const RECT &tr, int early_out) +{ +#if 0 + PtrListQuickSorted<RectV, Sorter> candidates(list.getNumItems()); + foreach(list) + double d = compare_overlapArea(tr, *list.getfor()); + candidates.addItem(new RectV(*list.getfor(), d)); + endfor + candidates.sort(); +#else + PtrList<RECT> candidates; + candidates.copyFrom(&list); +#endif + + double trarea = 0; + + foreach(candidates) +#if 0 + RECT *wr = &candidates.getfor()->a; +#else + RECT *wr = candidates.getfor(); +#endif + //CUT double bsf = MIN(found_nooverlap ? 0 : bsfval_nooverlap, bsfval_overlap); + trarea += (*fn)(tr, *wr, userdata, userdata2, foreach_index, bsfval); + + // early quit if not breaking any records + if (early_out && trarea >= bsfval) break; + + endfor + +#if 0 + candidates.deleteAll(); +#endif + + if (trarea < 0.005) trarea = 0; + +#if 0 + // found one that does not overlap! + if (trarea == 0) + { + if (val < bsfval_nooverlap) + { // if it's closer than prev closest, save it + bsf_nooverlap = tr; + bsfval_nooverlap = val; + found_nooverlap = 1; + } + } + else + { + if (trarea < bsfval_overlap) + { // overlaps least stuff + bsf_overlap = tr; + bsfval_overlap = trarea; + } + } +#endif + if (trarea == 0) + { + // find the distance from the previous + double val = SQRT(SQR(prev.left - tr.left) + SQR(prev.top - tr.top)); + if (bsfdist > val) + { + bsfrect = tr; + bsfdist = val; + } + } + else + { + if (trarea < bsfval) + { + bsfrect = tr; + bsfval = trarea; + } + } + iters++; + return trarea; +} + +double FindOpenRect::compare_overlapArea(const RECT &rect, const RECT &dest, unsigned long userdata, unsigned long userdata2, int index, double bsf) +{ + RECT intersection; + if (Wasabi::Std::rectIntersect(rect, dest, &intersection)) + { + intersection.right -= intersection.left; + intersection.bottom -= intersection.top; + return intersection.right * intersection.bottom; + } + return 0; +} + +void FindOpenRect::setTimeLimit(int ms) +{ + timelimit = ms; +} + +int FindOpenRect::getNumIters() +{ + return iters; +} + +void FindOpenRect::resetNumIters() +{ + iters = 0; +} + +double FindOpenRect::getBestValSoFar() +{ + return (bsfval == 10e10) ? 0 : bsfval; +} + +RECT FindOpenRect::getBestRectSoFar() +{ + return bsfrect; +} + +void FindOpenRect::setBestSoFar(double bsf, const RECT &bestrect) +{ + if (bsf > 0 && bsfval > bsf) + { + bsfval = bsf; + bsfrect = bestrect; + bsfdist = SQRT(SQR(prev.left - bsfrect.left) + SQR(prev.top - bsfrect.top)); + //CUTDebugString("*******************8 better BSF ****************"); + } +} + +RECT FindOpenRect::getOriginalRect() +{ + return prev; +} + +void FindOpenRect::setCoordDivisor(int _xdiv, int _ydiv) +{ + xdiv = MAX(_xdiv, 1); + ydiv = MAX(_ydiv, 1); +} diff --git a/Src/Wasabi/bfc/util/findopenrect.h b/Src/Wasabi/bfc/util/findopenrect.h new file mode 100644 index 00000000..97fdc5cb --- /dev/null +++ b/Src/Wasabi/bfc/util/findopenrect.h @@ -0,0 +1,63 @@ +#ifndef _FINDOPENRECT_H +#define _FINDOPENRECT_H + +#include <bfc/wasabi_std.h> +#include <bfc/ptrlist.h> + +class FindOpenRect +{ +public: + FindOpenRect(); + + typedef double (*compareRectsFn)(const RECT &rect, const RECT &dest, unsigned long userdata, unsigned long userdata2, int index, double bsf); + static double compare_overlapArea(const RECT &rect, const RECT &dest, unsigned long userdata = 0, unsigned long userdata2 = 0, int index = 0, double bsf = 0); + + void setCompareRectsFn(compareRectsFn fn); + + // this one does it all in one call + RECT find(const RECT &viewport, const PtrList<RECT> &list, + const RECT &prev, unsigned long userdata = 0, unsigned long userdata2 = 0); + + // these let you do it over time + void beginFind(const RECT &viewport, const PtrList<RECT> &list, + const RECT &prev, unsigned long userdata = 0, unsigned long userdata2 = 0); + RECT findMore(); + + double trySingleRect(const RECT &r, int early_out = FALSE); + + void setTimeLimit(int ms); + int getNumIters(); + void resetNumIters(); + + double getBestValSoFar(); + RECT getBestRectSoFar(); + + // this only sets it if it's a better value + void setBestSoFar(double bsf, const RECT &bestrect); + + RECT getOriginalRect(); + + void setCoordDivisor(int xdiv, int ydiv); + +private: + RECT vr, prev; + PtrList<RECT> list; + compareRectsFn fn; + unsigned long userdata, userdata2; + + int timelimit; + int iters; + + int xdiv, ydiv; + + RECT bsfrect; + double bsfval; + double bsfdist; + //CUT RECT bsf_nooverlap; + //CUT int found_nooverlap; + //CUT RECT bsf_overlap; + //CUT double bsfval_nooverlap; + //CUT double bsfval_overlap; +}; + +#endif diff --git a/Src/Wasabi/bfc/util/inifile.cpp b/Src/Wasabi/bfc/util/inifile.cpp new file mode 100644 index 00000000..dba5a9b5 --- /dev/null +++ b/Src/Wasabi/bfc/util/inifile.cpp @@ -0,0 +1,56 @@ +#include <precomp.h> + +#include "inifile.h" +#include <bfc/nsguid.h> + +#ifndef WIN32 +#include "profile.h" +#endif + +IniFile::IniFile(const wchar_t *_filename) : filename(_filename) { } + +void IniFile::setString(const wchar_t *section, const wchar_t *tagname, const wchar_t *val) { + WritePrivateProfileStringW(section, tagname, val, filename); +} + +wchar_t *IniFile::getString(const wchar_t *section, const wchar_t *tagname, wchar_t *buf, int buflen, const wchar_t *default_val) { + GetPrivateProfileStringW(section, tagname, default_val, buf, buflen, filename); + return buf; +} + +StringW IniFile::getString(const wchar_t *section, const wchar_t *tagname, const wchar_t *default_val) { + wchar_t buf[WA_MAX_PATH]=L""; + getString(section, tagname, buf, WA_MAX_PATH-1, default_val); + return StringW(buf); +} + +void IniFile::setInt(const wchar_t *section, const wchar_t *tagname, int val) { + setString(section, tagname, StringPrintfW(val)); +} + +int IniFile::getInt(const wchar_t *section, const wchar_t *tagname, int default_val) { + wchar_t buf[MAX_PATH] = {0}; + getString(section, tagname, buf, sizeof(buf), StringPrintfW(default_val)); + return WTOI(buf); +} + +int IniFile::getBool(const wchar_t *section, const wchar_t *tagname, int default_val) { + wchar_t buf[MAX_PATH] = {0}; + getString(section, tagname, buf, sizeof(buf), default_val ? L"true" : L"false"); + if (!_wcsicmp(buf, L"true")) return 1; + return 0; +} + +void IniFile::setBool(const wchar_t *section, const wchar_t *tagname, int val) { + setString(section, tagname, val ? L"true" : L"false"); +} + +GUID IniFile::getGuid(const wchar_t *section, const wchar_t *tagname, GUID default_val) { + wchar_t buf[MAX_PATH] = {0}; + getString(section, tagname, buf, sizeof(buf), StringPrintfW(default_val)); + return nsGUID::fromCharW(buf); +} + +void IniFile::setGuid(const wchar_t *section, const wchar_t *tagname, const GUID &val) { + setString(section, tagname, StringPrintfW(val)); +} diff --git a/Src/Wasabi/bfc/util/inifile.h b/Src/Wasabi/bfc/util/inifile.h new file mode 100644 index 00000000..6ce7b151 --- /dev/null +++ b/Src/Wasabi/bfc/util/inifile.h @@ -0,0 +1,28 @@ +#ifndef _INIFILE_H +#define _INIFILE_H + +#include <bfc/string/StringW.h> + +class IniFile +{ +public: + IniFile(const wchar_t *_filename); + + void setString(const wchar_t *section, const wchar_t *tagname, const wchar_t *val); + wchar_t *getString(const wchar_t *section, const wchar_t *tagname, wchar_t *buf, int buflen, const wchar_t *default_val = L""); // returns buf + StringW getString(const wchar_t *section, const wchar_t *tagname, const wchar_t *default_val=L""); + + void setInt(const wchar_t *section, const wchar_t *tagname, int val); + int getInt(const wchar_t *section, const wchar_t *tagname, int default_val = 0); + + int getBool(const wchar_t *section, const wchar_t *tagname, int default_val = 0); + void setBool(const wchar_t *section, const wchar_t *tagname, int val); + + GUID getGuid(const wchar_t *section, const wchar_t *tagname, GUID default_val = INVALID_GUID); + void setGuid(const wchar_t *section, const wchar_t *tagname, const GUID &val); + +private: + StringW filename; +}; + +#endif diff --git a/Src/Wasabi/bfc/util/profile.c b/Src/Wasabi/bfc/util/profile.c new file mode 100644 index 00000000..3049945a --- /dev/null +++ b/Src/Wasabi/bfc/util/profile.c @@ -0,0 +1,288 @@ +#pragma warn -aus +//---------------------------------------------------------------------------- +// MS Windows Style .ini File Interface for C++ +// This is the first version. +// Programed by xuyifeng, 1995.10, china +//---------------------------------------------------------------------------- +// Test history: +// Compiler OS TEST +// --------------------------------------------------------------- +// Watcom C++ 10.0a Rational System DOS4GW 100% tested +// Borland C++ 3.1 DOS 100% tested +// 10/4/97 - Bugfix: added fclose(is); at the end of getProfileString -lonerunnr/ags +//---------------------------------------------------------------------------- +#include <stdio.h> +#include <stdlib.h> +#include <sys/io.h> +#include <string.h> +#include <ctype.h> +#ifdef LINUX +#include <X11/Xos.h> +#define _strnicmp strncasecmp +#endif + +#include "profile.h" + +#define False 0 +#define True 1 + +//------------------------------------------------------------------------------ +// titlePos: get a section title position & length in a string. +//------------------------------------------------------------------------------ +static char *titlePos( char *buf, int *len ) +{ + char *p = buf, *q; + + while( *p && isspace(*p) ) p++; + if( *p != '[' ) + return 0; + + q = p+1; + while( *q && *q != ']' ) q++; + if( *q != ']' ) + return 0; + if( len ) + *len = (int)(q - p - 1); + return p+1; +} + +//------------------------------------------------------------------------------ +// isTitleLine: check if a string is a section title line +//------------------------------------------------------------------------------ +static int isTitleLine( char *bufPtr ) +{ + return titlePos( bufPtr, 0 ) != 0; +} + +//------------------------------------------------------------------------------ +// containTitle: check if a string contain a section a title +//------------------------------------------------------------------------------ +static int containTitle( char *buf, const char *section ) +{ + int len = 0; + char *p = titlePos(buf, &len); + if (p) + { + if( strlen( section ) == len && _strnicmp( section, p, len ) == 0 ) + return True; + } + return False; +} + +//------------------------------------------------------------------------------ +// gotoSection: move file position to start line of a section +//------------------------------------------------------------------------------ +static int gotoSection( FILE *is, const char *section ) +{ + char line[256] = {0}; + while( fgets(line, 256, is) != NULL) + if( containTitle( line, section ) ) + return True; + return False; +} + +//------------------------------------------------------------------------------ +// textPos: get content's position of a entry +//------------------------------------------------------------------------------ +static char *textPos( char *buf, const char *entry ) +{ + if( buf[0] == ';' ) // it is comment line + return 0; + + char *p = strchr( buf, '=' ); + if (!p) + return 0; + + int len = (int)(p - buf); + if( strlen(entry) == len && _strnicmp( buf, entry, len ) == 0 ) + return p+1; + + return 0; +} + +//------------------------------------------------------------------------------ +// stripQuotationChar: strip a pair of quotation chars in a string +//------------------------------------------------------------------------------ +static void stripQuotationChar( char *buf ) +{ + char *p = buf; + while( *p && isspace(*p) ) p++; + + if( !(*p == '\"' || *p == '\'') ) + return; + + char *q = p+strlen(p); + while( *q != *p && q > p ) q--; + if( q == p ) + return; + int len = (int)(q - p - 1); + memmove( buf, p+1, len ); + buf[len] = 0; +} + +//------------------------------------------------------------------------------ +// readEntry: read content of entry +//------------------------------------------------------------------------------ +static int readEntry( FILE *is, const char *entry, char *buf, int bufSize, + int strip ) +{ + char lineBuf[256] = {0}; + char *cur = buf; + *cur = '\0'; + int len = -1; + while( fgets(lineBuf, 256, is) != NULL) + { + if (lineBuf[strlen(lineBuf)-1] == '\n') + lineBuf[strlen(lineBuf)-1] = 0; + + if( isTitleLine( lineBuf ) ) // section is ended + break; + + char *p = textPos( lineBuf, entry ); // not equal this entry + if( p == 0 ) + continue; + + if( strip ) + stripQuotationChar( p ); + + len = strlen(p); + if( bufSize-1 < len ) + len = bufSize-1; + + strncpy( cur, p, len ); + cur[len] = 0; + break; + } + + return len; +} + +//------------------------------------------------------------------------------ +// getProfileString: +//------------------------------------------------------------------------------ +int GetPrivateProfileString( const char *section, + const char *entry, + const char *defaultString, + char *buffer, + int bufLen, + const char *fileName ) +{ + FILE *is; + int len = -1; + + is = fopen(fileName, "rt"); + + if( is && gotoSection( is, section ) ) + len = readEntry(is, entry, buffer, bufLen, True); + + if (len < 0) //can not read entry, use default string + { + strncpy( buffer, defaultString, bufLen-1 ); + buffer[bufLen-1] = 0; + len = strlen(buffer); + } + if (is) fclose(is); + return len; +} + +//---------------------------------------------------------------------------- +// getProfileInt: +//---------------------------------------------------------------------------- +long GetPrivateProfileInt( const char *section, + const char *entry, + long defaultInt, + const char *fileName ) +{ + char buf[256]; + char iBuf[34]; //"34" is max space "_itoa" required under 32 bit C++ + + sprintf(iBuf, "%d", defaultInt); + GetPrivateProfileString( section, entry, iBuf, buf, 256, fileName ); + return atol( buf ); +} + +static void writeEntry( FILE *os, const char *entry, const char *string ) +{ + fprintf(os, "%s=%s\n", entry, string); +} + +//------------------------------------------------------------------------------ +// writeProfileString: +//------------------------------------------------------------------------------ +int WritePrivateProfileString( const char *section, + const char *entry, + const char *string, + const char *fileName ) +{ + char path [8192] = {0}; + char drive[256] = {0}; + char dir [256] = {0}; + char file [256] = {0}; + char ext [256] = {0}; + char buf [256] = {0}; + + int titleFound; + + // work better on network! + _splitpath( path, drive, dir, file, ext ); + _makepath( path, drive, dir, mkstemp("iniXXXXXX"), "" ); + + FILE *is = fopen(fileName, "rt"); + FILE *os = fopen(path, "wt"); + + if(!is || !os || entry == 0) // maybe can not create file or invalid entry + { + if (is) fclose(is); + if (os) fclose(os); + return 0; + } + + titleFound = False; + if (is) + { + while (fgets(buf, 256, is) != NULL) + { + fputs(buf, os); + if( containTitle(buf, section) ) + { + titleFound = True; + break; + } + } + } + + if (!titleFound) // add section + { + fprintf(os, "[%s]\n", section); + writeEntry( os, entry, string ); + } + else + { + while (fgets(buf, 256, is) != NULL) + { + if (isTitleLine(buf)) // section ended, but still not found the entry + break; + + if (textPos(buf, entry)) // entry found, so rewrite it + { + break; + } + fputs(buf, os); + } + + writeEntry(os, entry, string); + + if (is) + { + while(fgets(buf, 256, is) != NULL) // copy left lines + fputs(buf, os); + } + } + if (is) fclose(is); + if (os) fclose(os); + unlink(fileName); + rename(path, fileName); + return strlen(string); +} + +#pragma warn .aus
\ No newline at end of file diff --git a/Src/Wasabi/bfc/util/profile.h b/Src/Wasabi/bfc/util/profile.h new file mode 100644 index 00000000..9d0df724 --- /dev/null +++ b/Src/Wasabi/bfc/util/profile.h @@ -0,0 +1,26 @@ +// +// profile.h +// Profile support. +// Programed by XuYiFeng 1995.4.25, All rights reserved. +// + +#ifndef __PROFILE_H +#define __PROFILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +long GetPrivateProfileInt( const char *section, const char *entry, long defaultInt, + const char *fileName ); +int GetPrivateProfileString( const char *section, const char *entry, + const char *defaultString, char *buffer, + int bufLen, const char *fileName ); +int WritePrivateProfileString( const char *section, const char *entry, + const char *string, const char *fileName ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Src/Wasabi/bfc/util/profiler.cpp b/Src/Wasabi/bfc/util/profiler.cpp new file mode 100644 index 00000000..3871434f --- /dev/null +++ b/Src/Wasabi/bfc/util/profiler.cpp @@ -0,0 +1,6 @@ +#include <precomp.h> +#include "profiler.h" + +PtrListInsertSorted<__ProfilerEntry, __ProfilerEntrySort> __profiler_entries; + +int __profiler_indent; diff --git a/Src/Wasabi/bfc/util/profiler.h b/Src/Wasabi/bfc/util/profiler.h new file mode 100644 index 00000000..e7b71e81 --- /dev/null +++ b/Src/Wasabi/bfc/util/profiler.h @@ -0,0 +1,128 @@ +#ifndef _PROFILER_H +#define _PROFILER_H + +#include <bfc/wasabi_std.h> +#include <bfc/string/bfcstring.h> +#include <bfc/ptrlist.h> + + +#ifdef NO_PROFILING +#define PR_ENTER(msg) +#define PR_LEAVE() +#else + +#define _PR_ENTER(msg, line) { __Profiler __prx##line(msg) +#define _PR_ENTER2(msg, msg2, line) { __Profiler __prx##line(msg, msg2) +#define PR_ENTER(msg) _PR_ENTER(msg, line) +#define PR_ENTER2(msg, msg2) _PR_ENTER2(msg, msg2, line) +#define PR_LEAVE() } + +class __ProfilerEntry { + public: + __ProfilerEntry(const char *txt) { text = txt; totaltime = 0; totaln = 0; subcount = 0; lastcps = -1;} + virtual ~__ProfilerEntry() {} + + void add(float ms) { totaltime += ms; totaln++; + if (subcount == 0) { + firstcall = Wasabi::Std::getTimeStampMS(); + } + if (Wasabi::Std::getTimeStampMS() - firstcall < 1) { + subcount++; + } else { + lastcps = subcount; + subcount = 0; + } + } + float getAverage() { if (totaln == 0) return 0; return totaltime / (float)totaln; } + float getTotal() { return totaltime; } + const char *getText() { return text; } + int getLastCPS() { return lastcps; } + + private: + float totaltime; + int totaln; + stdtimevalms firstcall; + int lastcps; + int subcount; + String text; +}; + +class __ProfilerEntrySort { +public: + static int compareAttrib(const wchar_t *attrib, void *item) { + return STRICMP((const char *)attrib, ((__ProfilerEntry*)item)->getText()); + } + static int compareItem(void *i1, void *i2) { + return STRICMP(((__ProfilerEntry*)i1)->getText(), ((__ProfilerEntry*)i2)->getText()); + } +}; + +extern COMEXP PtrListInsertSorted<__ProfilerEntry, __ProfilerEntrySort> __profiler_entries; +extern COMEXP int __profiler_indent; + +class __ProfilerManager { + public: + static void log(const char *txt, float ms, float *total, float *average, int *lastcps) { + int pos=-1; + __ProfilerEntry *e = __profiler_entries.findItem((const wchar_t *)txt, &pos); + if (pos < 0 || e == NULL) { + e = new __ProfilerEntry(txt); + __profiler_entries.addItem(e); + } + if (e != NULL) { + e->add(ms); + if (total != NULL) *total = e->getTotal(); + if (average != NULL) *average = e->getAverage(); + if (lastcps != NULL) *lastcps = e->getLastCPS(); + } + } +}; + +#undef USE_TICK_COUNT + +class __Profiler { +public: + __Profiler(const char *text, const char *text2="") : str(text), str2(text2) { + if (!str2.isempty()) str2 += " "; +#ifdef USE_TICK_COUNT + ts1 = GetTickCount(); +#else + ts1 = Wasabi::Std::getTimeStampMS(); +#endif + __profiler_indent++; + } + ~__Profiler() { + __profiler_indent--; +#ifdef USE_TICK_COUNT + stdtimevalms ts2 = GetTickCount(); +#else + stdtimevalms ts2 = Wasabi::Std::getTimeStampMS(); +#endif + float ms = (float)((ts2 - ts1) +#ifndef USE_TICK_COUNT +*1000.0 +#endif +); + float total=0; + float average=0; + int lastcps=0; + __ProfilerManager::log(str, ms, &total, &average, &lastcps); + char buf[4096]; + if (lastcps >= 0) + sprintf(buf, "%*sProfiler: %s: %s%6.4f ms (total: %6.4f ms, average: %6.4f ms, calls per second : %d)\n", __profiler_indent*4, " ", str.getValue(), str2.getValue(), ms, total, average, lastcps); + else + sprintf(buf, "%*sProfiler: %s: %s%6.4f ms (total: %6.4f ms, average: %6.4f ms)\n", __profiler_indent*4, " ", str.getValue(), str2.getValue(), ms, total, average); +#ifdef _WIN32 + OutputDebugStringA(buf); +#else +#warning port me +#endif + } +private: + String str, str2; + stdtimevalms ts1; +}; + +#endif//!NO_PROFILING + +#endif diff --git a/Src/Wasabi/bfc/util/timefmt.cpp b/Src/Wasabi/bfc/util/timefmt.cpp new file mode 100644 index 00000000..f0968ac6 --- /dev/null +++ b/Src/Wasabi/bfc/util/timefmt.cpp @@ -0,0 +1,71 @@ +#include <precomp.h> +#include <bfc/wasabi_std.h> +#include <time.h> +#include "timefmt.h" + +void TimeFmt::printMinSec(int sec, wchar_t *buf, int buflen) +{ + int minutes, seconds; + int negative = sec < 0; + + if (buf == NULL) return; + + if (sec == -1) + { + *buf = 0; + return; + } + + seconds = sec % 60; + sec /= 60; + minutes = sec; + + StringPrintfW sp(L"%s%d:%02d", (minutes == 0 && negative) ? L"-" : L"", minutes, ABS(seconds)); + WCSCPYN(buf, sp, buflen); +} + +void TimeFmt::printHourMinSec(int sec, wchar_t *buf, int buflen, int hoursonlyifneeded) +{ + int hours, minutes, seconds; + int negative = sec < 0; + + sec = ABS(sec); + if (buf == NULL) return; + + if (sec == -1) { + *buf = 0; + return; + } + + hours = sec / 3600; + sec -= hours * 3600; + seconds = sec % 60; + sec /= 60; + minutes = sec; + + StringW sp; + if (hoursonlyifneeded && hours == 0) + sp = StringPrintfW(L"%s%d:%02d", (minutes == 0 && negative) ? L"-" : L"", minutes, seconds); + else + sp = StringPrintfW(L"%s%d:%02d:%02d", (hours == 0 && negative) ? L"-" : L"", hours, minutes, seconds); + + WCSCPYN(buf, sp, buflen); +} + +void TimeFmt::printTimeStamp(wchar_t *buf, int bufsize, int ts) +{ + if (ts == 0) + { + WCSCPYN(buf, L"Never", bufsize); // FUCKO: load from lang pack + return; + } + + struct tm *tm_now; + tm_now = localtime((const time_t *)&ts); + if (tm_now == NULL) + { + *buf = 0; + return; + } + wcsftime(buf, bufsize, L"%a %b %Y %d %I:%M:%S %p", tm_now); +} diff --git a/Src/Wasabi/bfc/util/timefmt.h b/Src/Wasabi/bfc/util/timefmt.h new file mode 100644 index 00000000..b24e0a99 --- /dev/null +++ b/Src/Wasabi/bfc/util/timefmt.h @@ -0,0 +1,46 @@ +//PORTABLE +#ifndef _TIMEFMT_H +#define _TIMEFMT_H + +/** + Simple time formatting. Can format into a minutes:seconds style + display based on count in seconds only. + + Can also format a timestamp into human readable format. + + @author Nullsoft + @ver 1.0 +*/ +class TimeFmt { +public: + /** + Formats a time value in seconds to minute:seconds. + + If the buffer is too small, the string will be + truncated. + + @param seconds Time value to convert. + @param buf Buffer to receive formatted string. + @param buflen Length of the buffer. + */ + static void printMinSec(int seconds, wchar_t *buf, int buflen); + static void printHourMinSec(int seconds, wchar_t *buf, int buflen, int hoursonlyifneeded=0); + + /** + Formats a time value (from unix timestamp) to + human readable format. + + If the buffer is too small, the string will be + truncated. + + Example of formatted output: + Tue Sep 10 18:34:42 PDT 2002 + + @param buf Buffer to receive the formatted string. + @param bufsize Length of the buffer. + @param ts The timestamp to use. + */ + static void printTimeStamp(wchar_t *buf, int bufsize, int ts); +}; + +#endif |