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

📄 ptypes_test.cxx

📁 使用stl技术,(还没看,是听说的)
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 *
 *  C++ Portable Types Library (PTypes)
 *  Version 1.8.3  Released 25-Aug-2003
 *
 *  Copyright (c) 2001, 2002, 2003 Hovik Melikyan
 *
 *  http://www.melikyan.com/ptypes/
 *  http://ptypes.sourceforge.net/
 *
 */

#include <stdlib.h>
#include <stdio.h>

#include "pport.h"
#include "ptypes.h"
#include "pstreams.h"
#include "pinet.h"
#include "ptime.h"


#ifndef PTYPES_ST
#include "pasync.h"
#endif


USING_PTYPES


void showstr(const char* shouldbe, const char* is) 
{
    pout.putf("[%s] %s\n", shouldbe, is);
}


void showstr(const char* shouldbe, const string& is) 
{
    showstr(shouldbe, pconst(is));
}


void showhex(const char* shouldbe, const char* is, int islen) 
{
    string s;
    int i;
    for (i = 0; i < islen; i++)
        s += itobase((unsigned char)is[i], 16, 2);
    s = lowercase(s);
    showstr(shouldbe, s);
}


void showint(int shouldbe, int is) 
{
    pout.putf("[%d] %d\n", shouldbe, is);
}


void showint(large shouldbe, large is) 
{
    pout.putf("[%lld] %lld\n", shouldbe, is);
}


void showchar(char shouldbe, char is) 
{
    pout.putf("[%c] %c\n", shouldbe, is);
}


//
// string test
//

void string_test1() 
{
    pout.put("\n--- STRING CLASS\n");

    static char strbuf[10] = "STRING";

    char c = 'A';

    string s1 = "string";
    s1 = s1;
    s1 += s1;
    del(s1, 6, 6);
    string s2 = s1;
    string s3;
    string s4(strbuf, strlen(strbuf));
    string s5 = 'A';
    string s6 = c;

    showstr("string", s1);
    showstr(s1, s2);
    showstr("", s3);
    showstr("STRING", s4);
    showint(6, length(s4));
    showint(2, refcount(s1));
    clear(s2);
    showint(1, refcount(s1));
    s2 = s1;
    unique(s1);
    showint(1, refcount(s1));
    setlength(s1, 64);
    string s7 = s1;
    setlength(s1, 3);
    showstr("str", s1);
    showstr("strING", s1 += copy(s4, 3, 3));
    del(s1, 3, 3);
    showstr("str", s1);
    ins("ing", s1, 0);
    showstr("ingstr", s1);
    s2 = "str" + s1 + "ing";
    showstr("stringstring", s2);
    s3 = s2;
    s3 = "strungstrung";
    s3 = s2;
    s3 = "strung";

    s2 = "str" + s1;
    s2 = s1 + "str";
    s2 += "str";

    s2 = 's' + s1;
    s2 = s1 + 's';
    s2 += 's';
    
    s2 = c + s1;
    s2 = s1 + c;
    s2 += c;

    s2 = 'a';
    s2 = c;
}


void string_test2() 
{
    pout.put("\n--- STRING CLASS\n");

    string s1 = "ingstr";
    string s2 = "stringstring";
    string s4 = "STRING";

    showint(1, pos('t', s2));
    showint(2, pos("ri", s2));
    showint(3, pos(s1, s2));
    showint(1, contains("tr", s2, 1));
    showint(0, contains("tr", s2, 2));
    showint(1, s4 == "STRING");
    showchar('R', s4[2]);

    showstr("123456789", itostring(123456789));
    showstr("123", itostring(char(123)));
    showstr("-000123", itostring(-123, 10, 7, '0'));
    showstr("0ABCDE", itostring(0xabcde, 16, 6));
    showstr("-9223372036854775808", itostring(LARGE_MIN));
    showstr("18446744073709551615", itostring(ULARGE_MAX));

    showint(1234, (int)stringtoi("1234"));
    showint(large(0x15AF), stringtoue("15AF", 16));
    showint(LARGE_MAX, stringtoue("5zzzzzzzzzz", 64));

    try
    {
        // out of range by 1
        stringtoue("18446744073709551616", 10);
        fatal(0xb0, "Conversion overflow not detected");
    }
    catch (econv* e)
    {
        showstr("Out of range: ...", e->get_message());
        delete e;
    }

    showint(large(123), stringtoie("123"));
    showint(large(-123), stringtoie("-123"));
    showint(LARGE_MIN, stringtoie("-9223372036854775808"));
    showint(LARGE_MAX, stringtoie("9223372036854775807"));

    try
    {
        // out of range by 1
        stringtoie("9223372036854775808");
        fatal(0xb0, "Conversion overflow not detected");
    }
    catch (econv* e)
    {
        showstr("Out of range: ...", e->get_message());
        delete e;
    }

    showstr("abcabc", lowercase(s1 = "aBCAbc"));
    showstr("abcabc", lowercase(s1));
}


void string_benchmarks()
{
    pout.put("\n--- STRING BENCHMARKS\n");

    int i;
    string s1 = "string";
    string s2;

    // for the first time we run the test to let the VM settle down and stop swapping
    for (i = 0; i < 156000; i++)
        s2 += s1;

    // here is the actual test
    clear(s2);
    datetime start = now();
    for (i = 0; i < 156000; i++)
        s2 += s1;
    datetime diff = now() - start;

    pout.putf("Performance index compared to WinNT on P3/800MHz:\n%.3f\n", diff / 1000.0);
}


//
// cset test
//

void cset_test() 
{
    pout.put("\n--- CSET CLASS\n");

    cset s1 = "~09~0a~0d~F0 A-Z~~";
    cset s2 = "A-F";
    char c = 'B';

    showstr("~09~0a~0d A-Z~~~f0", asstring(s1));
    s1 -= char(0xf0);
    s1 -= cset("~00-~20");
    showstr("A-Z~~", asstring(s1));
    s1 -= s2;
    showstr("G-Z~~", asstring(s1));
    s1 += s2;
    s1 += ' ';
    showstr(" A-Z~~", asstring(s1));
    showint(1, s2 == cset("A-F"));
    showint(1, s2 <= s1);
    s1 -= 'A';
    s1 -= c;
    showint(0, s2 <= s1);
    s1 = s1 + char(0xf1);
    showint(1, char(0xf1) & s1);
    showint(0, char(0xf2) & s1);
}


//
// objlist
//


class known: public unknown {
public:
    int value;
    known(int ivalue): unknown(), value(ivalue) {}
    virtual ~known()  {}
};

typedef tobjlist<known> knownlist;


string ol_asstring(const knownlist& s) {
    string ret = "{";
    for (int i = 0; i < length(s); i++) {
        if (i > 0)
            concat(ret, ", ");
        ret += itostring(s[i]->value);
    }
    concat(ret, '}');
    return ret;
}


void objlist_test() {
    pout.put("\n--- OBJLIST CLASS\n");

    knownlist s1(true);
    known* obj;

    add(s1, new known(10));
    ins(s1, 0, new known(5));
    ins(s1, 2, obj = new known(20));
    add(s1, new known(30));
    add(s1, new known(40));
    del(s1, 4);
    del(s1, 1);

    get(s1, 0);
    showint(3, length(s1));
    showint(1, indexof(s1, obj));
    showstr("{5, 20, 30}", ol_asstring(s1));

    clear(s1);
    showstr("{}", ol_asstring(s1));
}



//
// strlist
//


typedef tstrlist<known> knownstrlist;


string sl_asstring(const knownstrlist& s) {
    string ret = "{";
    for (int i = 0; i < length(s); i++) {
        if (i > 0)
            concat(ret, ", ");
        ret += getstr(s, i) + ":" + itostring(s[i]->value);
    }
    concat(ret, '}');
    return ret;
}


void strlist_test() {
    pout.put("\n--- STRLIST CLASS\n");

    knownstrlist s1(SL_OWNOBJECTS);
    known* obj;

    add(s1, "ten", new known(10));
    ins(s1, 0, "five", new known(5));
    ins(s1, 2, "twenty", obj = new known(20));
    add(s1, "thirty", new known(30));
    add(s1, "forty", new known(40));
    del(s1, 4);
    del(s1, 1);

    showint(3, length(s1));
    showint(1, indexof(s1, obj));
    showint(2, find(s1, "thirty"));
    showint(2, find(s1, "THIRTY"));
    showint(-1, find(s1, "forty"));

    showstr("{five:5, twenty:20, thirty:30}", sl_asstring(s1));

    knownstrlist s2(slflags(SL_OWNOBJECTS | SL_SORTED | SL_CASESENS));
    add(s2, "five", new known(5));
    add(s2, "ten", new known(10));
    add(s2, "twenty", new known(20));
    add(s2, "thirty", new known(30));
    add(s2, "forty", new known(40));

    showint(5, length(s2));
    showint(3, find(s2, "thirty"));
    showint(-1, find(s2, "THIRTY"));
    showint(-1, find(s2, "hovik"));

    showstr("{five:5, forty:40, ten:10, thirty:30, twenty:20}", sl_asstring(s2));

    clear(s2);
    showstr("{}", sl_asstring(s2));

    strlist s3(slflags(SL_OWNOBJECTS | SL_SORTED | SL_DUPLICATES));

    add(s3, "a", nil);
    add(s3, "b", nil);
    add(s3, "b", nil);
    add(s3, "b", nil);
    add(s3, "b", nil);
    add(s3, "b", nil);
    add(s3, "b", nil);
    add(s3, "c", nil);

    showint(1, find(s3, "b"));
}


void strmap_test() {
    pout.put("\n--- STRMAP CLASS\n");

    tstrmap<known> s(SL_OWNOBJECTS);

    put(s, "five", new known(5));
    put(s, "ten", new known(10));
    put(s, "twenty", new known(20));
    put(s, "thirty", new known(30));
    put(s, "forty", new known(40));

    showint(20, get(s, "twenty")->value);
    showint(0, int(get(s, "hovik")));
    showint(5, length(s));
    put(s, "twenty", nil);
    showint(4, length(s));
}


//
// textmap
//


void textmap_test()
{
    pout.put("\n--- TEXTMAP CLASS\n");

    textmap c;

    put(c, "name1", "value1");
    put(c, "name2", "value2");
    put(c, "name1", "value3");
    put(c, "name2", "");
    showint(1, length(c));
    showstr("value3", get(c, "name1"));
    showstr("", get(c, "name2"));
}



//
// streams
//


char buf1[] = "This is a test.";
char buf2[] = "The file should contain readable human text. :)";

const char* fname = "stmtest.txt";

void outfile_test() 
{
    pout.put("\n--- OUTFILE CLASS\n");

    outfile f(fname, false);
    f.set_umode(0600);
    f.set_bufsize(3);

    f.open();
    f.put(buf1[0]);
    f.put(buf1[1]);
    f.put("is is a test.");
    f.puteol();
    f.close();
    
    f.set_append(true);
    f.open();
    f.write(buf2, strlen(buf2));
    f.puteol();
    f.close();

    pnull.put("This should go to nowhere I");
    pnull.put("This should go to nowhere II");
}


void infile_test() 
{
    pout.put("\n--- INFILE CLASS\n");

    infile f(fname);
    f.set_bufsize(3);

    char temp[4];

    f.open();
    pout.putf("%c", f.get());
    pout.putf("%s\n", pconst(f.line()));
    f.read(temp, sizeof temp - 1);
    temp[sizeof temp - 1] = 0;
    pout.putf("%s", temp);
    f.get();
    f.putback();
    pout.putf("%s", pconst(f.token(cset("~20-~FF"))));
    f.preview();
    if (f.get_eol()) 
    {
        f.skipline();
        pout.put("\n");
    }
    if (f.get_eof())
        pout.put("EOF\n");
//    f.error(1, "Test error message");

}


void mem_test()
{
    pout.put("\n--- OUT/IN MEMORY CLASS\n");
    
    outmemory m(12, 5);
    m.open();
    m.put("Memory");
    m.put(" c");
    m.put("lass is working");
    string s(m.get_data(), m.tell());
    showstr("Memory class", s);
}


#ifndef PTYPES_ST

//
// multithreading
//

//
// rwlock test
//

const int rw_max_threads = 30;
const int rw_max_tries = 30;
const int rw_max_delay = 20;
const int rw_rw_ratio = 5;
const bool rw_swap = false;


class rwthread: public thread
{
protected:
    virtual void execute();
public:
    rwthread(): thread(false)  {}
    virtual ~rwthread()        { waitfor(); }
};


rwlock rw;

int reader_cnt = 0;
int writer_cnt = 0;
int total_writers = 0;
int total_readers = 0;
int max_readers = 0;


int prand(int max)
{
    return rand() % max;
}


void rwthread::execute()
{

    for(int i = 0; i < rw_max_tries; i++)
    {
        psleep(prand(rw_max_delay));
        bool writer = prand(rw_rw_ratio) == 0;
        if (writer ^ rw_swap)
        {
            rw.wrlock();
            pout.put('w');
            if (pincrement(&writer_cnt) > 1)
                fatal(0xa0, "Writer: Huh?! Writers in here?");
            pincrement(&total_writers);
        }
        else
        {
            rw.rdlock();
            pout.put('.');
            int t;
            if ((t = pincrement(&reader_cnt)) > max_readers) 
                max_readers = t;
            if (writer_cnt > 0)
                fatal(0xa1, "Reader: Huh?! Writers in here?");
            pincrement(&total_readers);
        }
        psleep(prand(rw_max_delay));
        if (writer ^ rw_swap)
            pdecrement(&writer_cnt);
        else
            pdecrement(&reader_cnt);
        rw.unlock();
    }
}



void rwlock_test()
{
// #ifdef __PTYPES_RWLOCK__
    pout.put("\n--- RWLOCK\n");

    rwthread* threads[rw_max_threads];

    srand((unsigned)time(0));

    int i;
    for(i = 0; i < rw_max_threads; i++)
    {
        threads[i] = new rwthread();
        threads[i]->start();
    }
    for(i = 0; i < rw_max_threads; i++)
        delete threads[i];

    pout.putf("\nmax readers: %d\n", max_readers);
    pout.putline("do writers 'starve'?");
// #endif
}



const int MSG_DIAG = MSG_USER + 1;


//
// class diagmessage
//

class diagmessage: public message
{
protected:
    string module;
    string diagstr;
    friend class diagthread;
public:
    diagmessage(string imodule, string idiagstr)
        : message(MSG_DIAG), module(imodule),
          diagstr(idiagstr)  {}
};


//
// class diagthread
//

class diagthread: public thread, protected msgqueue
{
protected:
    virtual void execute();     // override thread::execute()
    virtual void cleanup();     // override thread::cleanup()
    virtual void msghandler(message& msg);  // override msgqueue::msghandler()
public:
    diagthread(): thread(false), msgqueue()  { }
    void postdiag(string module, string diagstr);
    void postquit();
};


void diagthread::postdiag(string module, string diagstr)
{  
    msgqueue::post(new diagmessage(module, diagstr));
}


void diagthread::postquit()
{ 
    msgqueue::post(MSG_QUIT); 
}


void diagthread::execute()
{
    // starts message queue processing; calls
    // msghandler for each message
    msgqueue::run();
}


void diagthread::cleanup()
{
}


void diagthread::msghandler(message& msg)
{
    switch (msg.id)
    {
    case MSG_DIAG:
	pout.putf("%s: %s\n", pconst(((diagmessage&)msg).module), pconst(((diagmessage&)msg).diagstr));
        break;
    default:
        defhandler(msg);
    }
}


//
// class testthread
//


class testthread: public thread
{
protected:
    diagthread* diag;
    string myname;
    virtual void execute();
    virtual void cleanup();
public:
    semaphore sem;
    tsemaphore tsem;
    testthread(diagthread* idiag)
        : thread(false), diag(idiag), myname("testthread"), sem(0), tsem(0)  {}
};


void testthread::execute()
{
    diag->postdiag(myname, "starts and enters sleep for 1 second");
    psleep(1000);
    diag->postdiag(myname, "signals the timed semaphore");
    tsem.post();
    diag->postdiag(myname, "releases the simple semaphore");
    sem.post();
    diag->postdiag(myname, "enters sleep for 1 more second");
    psleep(1000);
}

⌨️ 快捷键说明

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