mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-18 04:05:46 -04:00
Initial community commit
This commit is contained in:
315
Src/Wasabi/bfc/util/base64.cpp
Normal file
315
Src/Wasabi/bfc/util/base64.cpp
Normal file
@ -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;
|
||||
}
|
||||
|
||||
|
16
Src/Wasabi/bfc/util/base64.h
Normal file
16
Src/Wasabi/bfc/util/base64.h
Normal file
@ -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
|
251
Src/Wasabi/bfc/util/findopenrect.cpp
Normal file
251
Src/Wasabi/bfc/util/findopenrect.cpp
Normal file
@ -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);
|
||||
}
|
63
Src/Wasabi/bfc/util/findopenrect.h
Normal file
63
Src/Wasabi/bfc/util/findopenrect.h
Normal file
@ -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
|
56
Src/Wasabi/bfc/util/inifile.cpp
Normal file
56
Src/Wasabi/bfc/util/inifile.cpp
Normal file
@ -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));
|
||||
}
|
28
Src/Wasabi/bfc/util/inifile.h
Normal file
28
Src/Wasabi/bfc/util/inifile.h
Normal file
@ -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
|
288
Src/Wasabi/bfc/util/profile.c
Normal file
288
Src/Wasabi/bfc/util/profile.c
Normal file
@ -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
|
26
Src/Wasabi/bfc/util/profile.h
Normal file
26
Src/Wasabi/bfc/util/profile.h
Normal file
@ -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
|
6
Src/Wasabi/bfc/util/profiler.cpp
Normal file
6
Src/Wasabi/bfc/util/profiler.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include <precomp.h>
|
||||
#include "profiler.h"
|
||||
|
||||
PtrListInsertSorted<__ProfilerEntry, __ProfilerEntrySort> __profiler_entries;
|
||||
|
||||
int __profiler_indent;
|
128
Src/Wasabi/bfc/util/profiler.h
Normal file
128
Src/Wasabi/bfc/util/profiler.h
Normal file
@ -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
|
71
Src/Wasabi/bfc/util/timefmt.cpp
Normal file
71
Src/Wasabi/bfc/util/timefmt.cpp
Normal file
@ -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);
|
||||
}
|
46
Src/Wasabi/bfc/util/timefmt.h
Normal file
46
Src/Wasabi/bfc/util/timefmt.h
Normal file
@ -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
|
Reference in New Issue
Block a user