AXCEL C++ Framework
Elegance through abstraction
axcel.cpp
Go to the documentation of this file.
00001 
00004 #include "axcel.h"
00005 
00006 namespace axcel {
00007 
00008 /*
00009 string net::dns::addrs(const char* lookup) {
00010 #ifdef _WIN32
00011         WSADATA wd;
00012         WSAStartup(MAKEWORD(2, 0), &wd);
00013 #endif
00014         string s;
00015         char buf[48];
00016         struct addrinfo *ai, *ent;
00017         if (getaddrinfo(lookup, 0, 0, &ai))
00018                 return s;
00019         for (ent = ai; ent; ent = ent->ai_next) {
00020                 if (ent->ai_family == AF_INET)
00021                         s += inet_ntop(AF_INET, &((struct sockaddr_in*)ent->ai_addr)->sin_addr, buf, 48);
00022                 else if (ent->ai_family == AF_INET6)
00023                         s += inet_ntop(AF_INET6, &((struct sockaddr_in6*)ent->ai_addr)->sin6_addr, buf, 48);
00024                 s += "\n";
00025         }
00026         freeaddrinfo(ai);
00027 #ifdef _WIN32
00028         WSACleanup();
00029 #endif
00030         return s;
00031 }*/
00032 string io::ios::type() { return string("io::ios"); }
00033 io::ios::operator string () { return string(); }
00034 io::ios& io::ios::operator<< (object& o) { this->output::operator<<(o); return *this; }
00035 io::ios& io::ios::operator<< (bool val) { this->output::operator<<(val); return *this; }
00036 io::ios& io::ios::operator<< (short val) { this->output::operator<<(val); return *this; }
00037 io::ios& io::ios::operator<< (unsigned short val) { this->output::operator<<(val); return *this; }
00038 io::ios& io::ios::operator<< (int val) { this->output::operator<<(val); return *this; }
00039 io::ios& io::ios::operator<< (unsigned int val) { this->output::operator<<(val); return *this; }
00040 io::ios& io::ios::operator<< (long val) { this->output::operator<<(val); return *this; }
00041 io::ios& io::ios::operator<< (unsigned long val) { this->output::operator<<(val); return *this; }
00042 io::ios& io::ios::operator<< (float val) { this->output::operator<<(val); return *this; }
00043 io::ios& io::ios::operator<< (double val) { this->output::operator<<(val); return *this; }
00044 io::ios& io::ios::operator<< (long double val) { this->output::operator<<(val); return *this; }
00045 io::ios& io::ios::operator<< (const void* val) { this->output::operator<<(val); return *this; }
00046 io::ios& io::ios::operator<< (char c) { this->output::operator<<(c); return *this; }
00047 io::ios& io::ios::operator<< (signed char c) { this->output::operator<<(c); return *this; }
00048 io::ios& io::ios::operator<< (unsigned char c) { this->output::operator<<(c); return *this; }
00049 io::ios& io::ios::operator<< (const char* s) { this->output::operator<<(s); return *this; }
00050 io::ios& io::ios::operator<< (string s) { this->output::operator<<(s); return *this; }
00051 io::ios& io::ios::put(object& o) { this->output::put(o); return *this; }
00052 io::ios& io::ios::put(string s) { this->output::put(s); return *this; }
00053 io::ios& io::ios::echo(object& o) { this->output::echo(o); return *this; }
00054 io::ios& io::ios::echo(string s) { this->output::echo(s); return *this; }
00055 io::ios& io::ios::put(bool val) { this->output::put(val); return *this; }
00056 io::ios& io::ios::put(short val) { this->output::put(val); return *this; }
00057 io::ios& io::ios::put(unsigned short val) { this->output::put(val); return *this; }
00058 io::ios& io::ios::put(int val) { this->output::put(val); return *this; }
00059 io::ios& io::ios::put(long val) { this->output::put(val); return *this; }
00060 io::ios& io::ios::put(unsigned long val) { this->output::put(val); return *this; }
00061 io::ios& io::ios::put(float val) { this->output::put(val); return *this; }
00062 io::ios& io::ios::put(double val) { this->output::put(val); return *this; }
00063 io::ios& io::ios::put(long double val) { this->output::put(val); return *this; }
00064 io::ios& io::ios::put(const void* val) { this->output::put(val); return *this; }
00065 io::ios& io::ios::put(char c) { this->output::put(c); return *this; }
00066 io::ios& io::ios::put(signed char c) { this->output::put(c); return *this; }
00067 io::ios& io::ios::put(unsigned char c) { this->output::put(c); return *this; }
00068 io::ios& io::ios::put(const char* s) { this->output::put(s); return *this; }
00069 io::ios& io::ios::echo() { this->output::echo(); return *this; }
00070 io::ios& io::ios::echo(bool val) { this->output::echo(val); return *this; }
00071 io::ios& io::ios::echo(short val) { this->output::echo(val); return *this; }
00072 io::ios& io::ios::echo(unsigned short val) { this->output::echo(val); return *this; }
00073 io::ios& io::ios::echo(int val) { this->output::echo(val); return *this; }
00074 io::ios& io::ios::echo(size_t val) { this->output::echo(val); return *this; }
00075 io::ios& io::ios::echo(long val) { this->output::echo(val); return *this; }
00076 io::ios& io::ios::echo(unsigned long val) { this->output::echo(val); return *this; }
00077 io::ios& io::ios::echo(float val) { this->output::echo(val); return *this; }
00078 io::ios& io::ios::echo(double val) { this->output::echo(val); return *this; }
00079 io::ios& io::ios::echo(long double val) { this->output::echo(val); return *this; }
00080 io::ios& io::ios::echo(const void* val) { this->output::echo(val); return *this; }
00081 io::ios& io::ios::echo(char c) { this->output::echo(c); return *this; }
00082 io::ios& io::ios::echo(signed char c) { this->output::echo(c); return *this; }
00083 io::ios& io::ios::echo(unsigned char c) { this->output::echo(c); return *this; }
00084 io::ios& io::ios::echo(const char* s) { this->output::echo(s); return *this; }
00085 io::ios& io::ios::operator>> (bool& val) { this->input::operator>>(val); return *this; }
00086 io::ios& io::ios::operator>> (short& val) { this->input::operator>>(val); return *this; }
00087 io::ios& io::ios::operator>> (unsigned short& val) { this->input::operator>>(val); return *this; }
00088 io::ios& io::ios::operator>> (int& val) { this->input::operator>>(val); return *this; }
00089 io::ios& io::ios::operator>> (unsigned int& val) { this->input::operator>>(val); return *this; }
00090 io::ios& io::ios::operator>> (long& val) { this->input::operator>>(val); return *this; }
00091 io::ios& io::ios::operator>> (unsigned long& val) { this->input::operator>>(val); return *this; }
00092 io::ios& io::ios::operator>> (long long& val) { this->input::operator>>(val); return *this; }
00093 io::ios& io::ios::operator>> (unsigned long long& val) { this->input::operator>>(val); return *this; }
00094 io::ios& io::ios::operator>> (float& val) { this->input::operator>>(val); return *this; }
00095 io::ios& io::ios::operator>> (double& val) { this->input::operator>>(val); return *this; }
00096 io::ios& io::ios::operator>> (long double& val) { this->input::operator>>(val); return *this; }
00097 io::ios& io::ios::operator>> (void*& val) { this->input::operator>>(val); return *this; }
00098 io::ios& io::ios::operator>> (char& c) { this->input::operator>>(c); return *this; }
00099 io::ios& io::ios::operator>> (char* s) { this->input::operator>>(s); return *this; }
00100 io::ios& io::ios::operator>> (string& s) { this->input::operator>>(s); return *this; }
00101 
00102 struct errno_str errno_strs[] = {
00103         {0, "unknown error"},
00104         {EPERM, "operation not permitted"},
00105         {ENOENT, "no such file or directory"},
00106         {ESRCH, "no such process"},
00107         {EINTR, "interrupted function call"},
00108         {EIO, "input/output error"},
00109         {ENXIO, "no such device or address"},
00110         {E2BIG, "argument list too long"},
00111         {ENOEXEC, "exec format error"},
00112         {EBADF, "bad file descriptor"},
00113         {ECHILD, "no child process"},
00114         {EAGAIN, "resource temporarily unavailable"},
00115         {ENOMEM, "not enough space"},
00116         {EACCES, "permission denied"},
00117         {EFAULT, "bad address"},
00118         {EBUSY, "device or resource busy"},
00119         {EEXIST, "file exists"},
00120         {EXDEV, "improper link"},
00121         {ENODEV, "no such device"},
00122         {ENOTDIR, "not a directory"},
00123         {EISDIR, "is a directory"},
00124         {ENFILE, "too many open files in system"},
00125         {EMFILE, "too many open files"},
00126         {ENOTTY, "inappropriate i/o control operation"},
00127         {EFBIG, "file too large"},
00128         {ENOSPC, "no space left on device"},
00129         {ESPIPE, "invalid seek"},
00130         {EROFS, "read-only file system"},
00131         {EMLINK, "too many links"},
00132         {EPIPE, "broken pipe"},
00133         {EDOM, "mathematics argument out of domain of function"},
00134         {EDEADLK, "resource deadlock avoided"},
00135         {ENAMETOOLONG, "filename too long"},
00136         {ENOLCK, "no locks available"},
00137         {ENOSYS, "function not implemented"},
00138         {ENOTEMPTY, "directory not empty"},
00139         {EINVAL, "invalid argument"},
00140         {ERANGE, "result too large"},
00141         {EILSEQ, "illegal byte sequence"},
00142         {EADDRINUSE, "address already in use"},
00143         {EADDRNOTAVAIL, "address not available"},
00144         {EAFNOSUPPORT, "address family not supported"},
00145         {EALREADY, "connection already in progress"},
00146         {EBADMSG, "bad message"},
00147         {ECANCELED, "operation canceled"},
00148         {ECONNABORTED, "connection aborted"},
00149         {ECONNREFUSED, "connection refused"},
00150         {ECONNRESET, "connection reset"},
00151         {EDESTADDRREQ, "destination address required"},
00152         {EHOSTUNREACH, "host is unreachable"},
00153         {EIDRM, "identifier removed"},
00154         {EINPROGRESS, "operation in progress"},
00155         {EISCONN, "socket is connected"},
00156         {ELOOP, "too many levels of symbolic links"},
00157         {EMSGSIZE, "message too long"},
00158         {ENETDOWN, "network is down"},
00159         {ENETRESET, "connection aborted by network"},
00160         {ENETUNREACH, "network unreachable"},
00161         {ENOBUFS, "no buffer space available"},
00162         {ENODATA, "no message is available"},
00163         {ENOLINK, "link has been severed"},
00164         {ENOMSG, "no message of the desired type"},
00165         {ENOPROTOOPT, "protocol not available"},
00166         {ENOSR, "no stream resources"},
00167         {ENOSTR, "not a stream"},
00168         {ENOTCONN, "the socket is not connected"},
00169         {ENOTRECOVERABLE, "state not recoverable"},
00170         {ENOTSOCK, "not a socket"},
00171         {ENOTSUP, "operation not supported"},
00172         {EOVERFLOW, "value too large too be stored in datatype"},
00173         {EOWNERDEAD, "owner died"},
00174         {EPROTO, "protocol error"},
00175         {EPROTONOSUPPORT, "protocol not supported"},
00176         {EPROTOTYPE, "protocol wrong type for socket"},
00177         {ETIME, "timer expired"},
00178         {ETIMEDOUT, "connection timed out"},
00179         {ETXTBSY, "text file busy"},
00180         {0, 0}
00181 };
00182 
00183 exception::exception() { no = 0; }
00184 exception::exception(int number) { no = number; }
00185 exception::exception(const exception& e) { no = e.no; desc = e.desc; }
00186 exception::exception(const char* msg) { this->operator=(msg); }
00187 string exception::type() { return string("exception"); }
00188 exception& exception::operator= (int number) { no = number; return *this; }
00189 exception& exception::operator= (const exception e) { no = e.no; desc = e.desc; return *this; }
00190 exception& exception::operator= (const char* msg) {
00191         register int i;
00192         for (i = 0; errno_strs[i].str; i++)
00193                 if (!strcmp(errno_strs[i].str, msg)) { no = errno_strs[i].no; return *this; }
00194         no = 0;
00195         return *this;
00196 }
00197 exception::operator string() {
00198         register int i;
00199         for (i = 0; errno_strs[i].str; i++)
00200                 if (no == errno_strs[i].no) return string(errno_strs[i].str);
00201         return string("unknown error");
00202 }
00203 exception object::error() { return exception(errnum); }
00204 bool exception::operator== (exception e) { return no == e.no; }
00205 bool exception::operator== (const char* s) { return this->operator string() == s; }
00206 bool exception::operator== (int num) { return no == num; }
00207 bool exception::operator!= (exception e) { return no != e.no; }
00208 bool exception::operator!= (const char* s) { return this->operator string() != s; }
00209 bool exception::operator!= (int num) { return no != num; }
00210 
00211 char* strcpy2(char* s1, const char* s2) {
00212         if (s2 == NULL) return s1;
00213         return strcpy(s1, s2);
00214 }
00215 
00216 char* strncpy2(char* s1, const char* s2, size_t n) {
00217         if (s2 == NULL) return s1;
00218         return strncpy(s1, s2, n);
00219 }
00220 
00221 data console::dump() {
00222         data d;
00223         char c;
00224         do { c = this->getche(); d << c; } while (c);
00225         //while (this->kbhit()) d << this->getche();
00226         return d;
00227 }
00228 
00229 string fs::tmpnam() {
00230         string s;
00231         s.realloc(256);
00232 	::tmpnam(s.buf);
00233         return s;
00234 }
00235 
00236 data& data::operator= (const char* s) {
00237         if (buf) free(buf);
00238         rewind();
00239         realloc(strlen(s) + 1);
00240         strcpy(buf, s);
00241         return *this;
00242 }
00243 data& data::operator= (object& o) {
00244         if (buf) free(buf);
00245         rewind();
00246         realloc(((string)o).len() + 1);
00247         string q = (string)o;
00248         strcpy(buf, q.buf);
00249         return *this;
00250 }
00251 
00252 //object::operator const char* () { static string cstrbuf = this->operator string (); return cstrbuf.buf; }
00253 string io::iofmt::type() { return string("io::iofmt"); }
00254 string io::iob::type() { return string("io::iob"); }
00255 string io::input::type() { return string("io::input"); }
00256 string io::output::type() { return string("io::output"); }
00257 string fs::file::type() { return string("fs::file"); }
00258 string net::socket::tcp::type() { return string("net::socket::tcp"); }
00259 string string::type() { return string("string"); }
00260 string console::type() { return string("console"); }
00261 string timer::type() { return string("timer"); }
00262 string proc::thread::type() { return string("proc::thread"); }
00263 string proc::library::type() { return string("proc::library"); }
00264 string net::irc::msg::type() { return string("net::irc::msg"); }
00265 string proc::mutex::type() { return string("proc::mutex"); }
00266 string proc::semaphore::type() { return string("proc::semaphore"); }
00267 net::irc::msg::operator string () { return buf; }
00268 
00269 io::iofmt::operator string () {
00270         string s;
00271         s.printf("%d", width);
00272         return s;
00273 }
00274 io::iob::operator string () {
00275         string s;
00276         if (ok()) s = "ok";
00277         else if (hurt()) s = "hurt";
00278         else if (dead()) s = "dead";
00279         else if (eof()) s = "eof";
00280         return s;
00281 }
00282 
00283 fs::file::operator string () { return filename; }
00284 net::socket::tcp::operator string () { return ip(); }
00285 string::operator string () { return *this; }
00286 console::operator string () { string s; s.printf("io::input: %d io::output: %d", ::fileno(in), ::fileno(out)); return s; }
00287 timer::operator string () { return str(); }
00288 proc::thread::operator string () { string s; s.printf("%ld", tid); return s; }
00289 proc::library::operator string () { return libraryname; }
00290 proc::mutex::operator string () { string s; s.printf("%ld", id); return s; }
00291 proc::semaphore::operator string () { string s; s.printf("%ld", id); return s; }
00292 
00300 io::output& io::output::operator<< (object& o) { this->operator<< (((string)o).buf); return *this; }
00301 
00309 io::output& io::output::put(object& o) { return this->operator<<(((string)o).buf); }
00310 
00319 io::output& io::output::echo(object& o) { this->operator<<(((string)o).buf); this->operator<<('\n'); return *this; }
00320 //io::output& io::output::operator<< (string s) { this->operator<< (s.buf); return *this; }
00321 io::output& io::output::put(string s) { return this->operator<<(s.buf); }
00322 io::output& io::output::echo(string s) { this->operator<<(s.buf); this->operator<<('\n'); return *this; }
00323 
00324 io::iofmt::iofmt() {
00325         lfmt = 0;
00326         dec(1);
00327         ltrim(1);
00328         width = 0;
00329         precis = 0;
00330         ltrim(1);
00331 }
00332 
00333 bool io::iofmt::gsbit(int i, long j) {
00334         if (i == -1) return lfmt & j;
00335         else if (i) lfmt |= j;
00336         else lfmt &= ~j;
00337         return i;
00338 }
00339 
00340 //bool io::iofmt::num(int i) { return gsbit(i, 1); }
00341 
00342 
00351 bool io::iofmt::bin(int i) { return gsbit(i, 1); }
00352  
00361 bool io::iofmt::btoa(int i) { return gsbit(i, 1 << 1); }
00362 
00376 bool io::iofmt::base(int i) { return gsbit(i, 1 << 2); }
00377 
00388 bool io::iofmt::zpad(int i) { return gsbit(i, 1 << 3); }
00389 
00400 bool io::iofmt::sign(int i) { return gsbit(i, 1 << 4); }
00401 
00411 bool io::iofmt::deaf(int i) { return gsbit(i, 1 << 5); }
00412 
00421 bool io::iofmt::dec(int i) { if (i == 1) { lfmt &= ~(1 << 7); lfmt &= ~(1 << 8); }return gsbit(i, 1 << 6); }
00422 
00431 bool io::iofmt::hex(int i) { if (i == 1) { lfmt &= ~(1 << 6); lfmt &= ~(1 << 8); } return gsbit(i, 1 << 7); }
00432 
00441 bool io::iofmt::oct(int i) { if (i == 1) { lfmt &= ~(1 << 6); lfmt &= ~(1 << 7); } return gsbit(i, 1 << 8); }
00442 
00451 bool io::iofmt::ltrim(int i) { return gsbit(i, 1 << 9); }
00452 
00461 bool io::iofmt::endnl(int i) { return gsbit(i, 1 << 10); }
00462 
00474 bool io::iofmt::left(int i) { return gsbit(i, 1 << 11); }
00475 
00486 bool io::iofmt::right(int i) { return left(0); }
00487 
00498 bool io::iofmt::fix(int i) { if (i == 1) lfmt &= ~(1 << 13); return gsbit(i, 1 << 12); }
00499 
00512 bool io::iofmt::sci(int i) { if (i == 1) lfmt &= ~(1 << 12); return gsbit(i, 1 << 13); }
00513 
00517 bool io::iob::ok() { return istat & 1; }
00518 
00522 bool io::iob::hurt() { return istat & (1 << 1); }
00523 
00527 bool io::iob::dead() { return istat & (1 << 2); }
00528 
00533 bool io::iob::eof() { return istat & (1 << 3); }
00534 
00539 void io::iob::heal() {  istat = 1; }
00540 
00546 void io::iob::hit() { istat = 1 << 1; }
00547 
00553 void io::iob::kill() { istat = 1 << 2; }
00554 
00560 void io::iob::drain() { istat = 1 << 3; }
00561 
00572 char* io::input::gets(char* s, int size) {
00573         register int c;
00574         for (c = getc(); size ? size > 0 : 1; c = getc(), s++) {
00575                 switch (c) {
00576                 case EOF: *s = 0; s = NULL; break;
00577                 case '\n': *s = '\n'; *(++s) = 0; return s;
00578                 default: *s = c;
00579                 }
00580                 if (size) size--;
00581         }
00582         if (s) *s = 0;
00583         return s;
00584 }
00585 
00586 /*Charp io::input::gets(int size) {
00587         Charp s;
00588         int i = 32, j = 0;
00589         register int c;
00590         s.ptr = (char*)malloc(i);
00591         s.free = true;
00592         for (c = getc(); ; c = getc(), j++) {
00593                 if (size) if (j >= size) break;
00594                 if (j >= i - 4) { i *= 2; s.ptr = (char*)realloc(s, i); }
00595                 switch (c) {
00596                 case EOF: s.ptr[0] = 0; return s;
00597                 case '\n': s.ptr[j] = '\n'; s.ptr[++j] = 0; return s;
00598                 default: s.ptr[j] = c;
00599                 }
00600         }
00601         s.ptr[j] = 0;
00602         return s;
00603 }*/
00604 
00615 size_t io::input::read(char* ptr, size_t size, size_t nmemb) {
00616         register int c;
00617         size_t i, j;
00618         for (i = 0; i < nmemb; i++)
00619                 for (j = 0; j < size; j++) {
00620                         c = getc();
00621                         if (!ok()) return i;
00622                         else ptr[size * i + j] = c;
00623                 }
00624         return i;
00625 }
00626 
00696 int io::input::scanf(const char* format, ...) {
00697         int \
00698                 matched = 0,            //Number of matched tokens
00699                 mods,                                   //Conversion modifier flags
00700                 base;                           //for numeric base
00701         size_t i;                               //a loopy thing
00702         size_t width;                   //field width
00703         register int last;      //Char accumulator
00704         bool \
00705         sign,                                           //signed or unsigned flag
00706         ate = false;                    //leftover character input from last token?
00707         const char* cp;
00708         std::deque<unsigned char> b;    //THE BUFFER
00709         char* tomato;
00710         va_list v;                              //...
00711         //modifier flags
00712         enum {
00713                 unclog = 1,                     //Flush stream after reading?
00714                 discard = 1 << 1,       //Discard input
00715                 mb = 1 << 2,            //byte
00716                 mh = 1 << 3,            //half
00717                 mw = 1 << 4,            //word
00718                 ml = 1 << 5,            //long
00719                 addws = 1 << 6, //do not discard leading whitespace?
00720                 dienl = 1 << 7          //End input on newline?
00721         };
00722         //flush an existing tied stream
00723         //if (knot) knot->flush();
00724         va_start(v, format);
00725         //Loop through format string
00726         for (; *format; format++) {
00727                 mods = 0;
00728                 width = 0;
00729                 b.clear();
00730                 if (*format == '%') {
00731                         format++;
00732                         for (; !isdigit(*format) && !isalpha(*format); format++) {
00733                                 switch (*format) {
00734                                 case '*': mods |= discard; break;
00735                                 case '^': mods |= addws; break;
00736                                 case '$': mods |= dienl; break;
00737                                 case '%':
00738                                         if (!ate) if ((last = getc()) == EOF) goto in_scanf_end;
00739                                         if (last != '%') { hit(); goto in_scanf_end; }
00740                                         ate = false;
00741                                         continue;
00742                                 }
00743                         }
00744                         if (isdigit(*format)) width = stoi<int>(format, 10);
00745                         while (isdigit(*format)) format++;
00746                         if (strpbrk(format, "bhwl") == format) {
00747                                 switch (format[0]) {
00748                                 case 'b': mods |= mb; break;
00749                                 case 'h': mods |= mh; break;
00750                                 case 'w': mods |= mw; break;
00751                                 case 'l': mods |= ml; break;
00752                                 }
00753                                 format++;
00754                         }
00755                         if (strpbrk(format, "DOXIdoxi") == format) {                    
00756                                 if (!ate) if ((last = getc()) == EOF) goto in_scanf_end;
00757                                 if (!(mods & addws))
00758                                         for (; isspace(last); )
00759                                                 if ((last = getc()) == EOF) goto in_scanf_end;
00760                                 if (last == EOF) goto in_scanf_end;
00761                                 else b.push_back(last);
00762                                 if ((last == '+' || last == '-'))
00763                                         if (isupper(*format)) {
00764                                                 hurt(); goto in_scanf_end;
00765                                         } else if ((last = getc()) == EOF)  { goto in_scanf_end;
00766                                         } else { b.push_back(last); }
00767                                         
00768                                 if (last == '0') {;
00769                                         if ((last = getc()) == EOF) goto in_scanf_end;
00770                                         else b.push_back(last);
00771                                         if ((last = 'x' || last == 'X') && (strpbrk(format, "XxIi") != format)) {
00772                                                 hit(); goto in_scanf_end;
00773                                         } else if (strpbrk(format, "OoIi") != format) {
00774                                                 hit(); goto in_scanf_end;
00775                                         }
00776                                 }
00777                                 for (;;) {
00778                                         if ((last = getc()) == EOF) break;
00779                                         if (!(mods & dienl))
00780                                                 if (!(islower(*format) == 'x' ? isxdigit(last) : isdigit(last)))
00781                                                         break;
00782                                         if (last == '\n') break;
00783                                         b.push_back(last);
00784                                         if (width) if (b.size() == width) break;
00785                                 }
00786                                 ate = true;
00787                                 if (mods & discard) break;
00788                                 //null terminate string!
00789                                 b.push_back(0); 
00790                                 //Get numeric base
00791                                 switch (*format) {
00792                                 case 'D': case 'd': base = 10; break;
00793                                 case 'O': case 'o': base = 8; break;
00794                                 case 'X': case 'x': base = 16; break;
00795                                 case 'I': case 'i': base = 0; break;
00796                                 }
00797                                 //Apply modifiers and convert to number
00798                                 if (mods & mb) {
00799                                         if (isupper(*format))
00800                                                 *(va_arg(v, unsigned char*)) = stoi<unsigned char>((char*)&(b[0]), base);
00801                                         else
00802                                                 *(va_arg(v, signed char*)) = stoi<signed char>((char*)&(b[0]), base);
00803                                 } else if (mods & mh) {
00804                                         if (isupper(*format))
00805                                                 *(va_arg(v, unsigned short*)) = stoi<unsigned short>((char*)&(b[0]), base);
00806                                         else
00807                                                 *(va_arg(v, signed short*)) = stoi<signed short>((char*)&(b[0]), base);
00808                                 } else if (mods & mw) {
00809                                         if (isupper(*format))
00810                                                 *(va_arg(v, unsigned long*)) = stoi<unsigned long>((char*)&(b[0]), base);
00811                                         else
00812                                                 *(va_arg(v, signed long*)) = stoi<signed long>((char*)&(b[0]), base);
00813                                 } else if (mods & ml) {
00814                                         if (isupper(*format))
00815                                                 *(va_arg(v, unsigned long long*)) = stoi<unsigned long long>((char*)&(b[0]), base);
00816                                         else
00817                                                 *(va_arg(v, signed long long*)) = stoi<signed long long>((char*)&(b[0]), base);
00818                                 } else {
00819                                         if (isupper(*format))
00820                                                 *(va_arg(v, unsigned int*)) = stoi<unsigned int>((char*)&(b[0]), base);
00821                                         else
00822                                                 *(va_arg(v, signed int*)) = stoi<signed int>((char*)&(b[0]), base);
00823                                 }
00824                         } else if (*format == 'c') {
00825                                 if (!ate) last = getc();
00826                                 if (!(mods & addws))
00827                                         for (; isspace(last); last = getc())
00828                                                 if (last == EOF) goto in_scanf_end;
00829                                 if (last != EOF) b.push_back(last);
00830                                 else goto in_scanf_end;
00831                                 if (!width) width = 1;
00832                                 for (i = 1; ; i++) {
00833                                         if (!(mods & dienl)) if (i == width) break;
00834                                         if (last == EOF) goto in_scanf_end;
00835                                         if (last == '\n') break;
00836                                         b.push_back(last);
00837                                         last = getc();
00838                                 }
00839                                 if (!(mods & discard)) {
00840                                         tomato = va_arg(v, char*);
00841                                         for (; !b.empty(); b.pop_front(), tomato++)
00842                                                 *tomato = b.front();
00843                                 }
00844                                 ate = false;
00845                         } else if (*format == 's') {
00846                                 if (!ate) if ((last = getc()) == EOF)
00847                                         goto in_scanf_end;
00848                                 if (!(mods & addws)) {
00849                                         for (; isspace(last); last = getc())
00850                                                 if (last == EOF) goto in_scanf_end;
00851                                 } else {
00852                                         for (; isspace(last); last = getc())
00853                                                 if (last == EOF) goto in_scanf_end;
00854                                                 else b.push_back(last);
00855                                 }
00856                                 for (i = 1; ; i++) {
00857                                         if (last == EOF) break;
00858                                         if (!(mods & dienl)) {
00859                                                 if (isspace(last)) { ate = false; break; }
00860                                         } else if (last == '\n') { ate = false; break; }
00861                                         if (width) if (i == width) { ate = true; break; }
00862                                         b.push_back(last);
00863                                         last = getc();
00864                                 }
00865                                 b.push_back(0);
00866                                 if (mods & discard) continue;
00867                                 tomato = va_arg(v, char*);
00868                                 for (; !b.empty(); b.pop_front(), tomato++)
00869                                         *tomato = b.front();
00870                         } else if (*format == 'f') {
00871                                 sign = false;
00872                                 if (!ate) last = getc();
00873                                 if (!(mods & addws))
00874                                         for (; isspace(last); )
00875                                                 if ((last = getc()) == EOF) goto in_scanf_end;
00876                                 if (last != EOF) b.push_back(last);
00877                                 else goto in_scanf_end;
00878                                 if (!(
00879                                 last == '+' ||
00880                                 last == '-' ||
00881                                 isdigit(last)
00882                                 )) { hit(); goto in_scanf_end; }
00883                                 for (;;) {
00884                                         if ((last = getc()) == EOF) break;
00885                                         if (!(mods & dienl)) {
00886                                                 if (last == '.' && sign) break;
00887                                                 if (!isdigit(last) && last != '.') break;
00888                                         }
00889                                         if (last == '\n') break;
00890                                         else if (last == '.') sign = true;
00891                                         b.push_back(last);
00892                                         if (width) if (b.size() == width) break;
00893                                 }
00894                                 b.push_back(0);
00895                                 ate = true;
00896                                 if (mods & discard) break;
00897                                 if (mods & mw)
00898                                         *(va_arg(v, double*)) = stof<double>((char*)&(b[0]));
00899                                 else if (mods & ml)
00900                                         *(va_arg(v, long double*)) = stof<long double>((char*)&(b[0]));
00901                                 else
00902                                         *(va_arg(v, float*)) = stof<float>((char*)&(b[0]));
00903                         }
00904                         matched++;
00905                 } else if (isspace(*format)) {
00906                         do format++; while (isspace(*format));
00907                         format--;
00908                         if (!ate) if ((last = getc()) == EOF) goto in_scanf_end;
00909                         if (isspace(last)) ate = false;
00910                         while (isspace(last))
00911                                 if ((last = getc()) == EOF) goto in_scanf_end;
00912                         if (!isspace(last)) ate = true;
00913                 } else {
00914                         if (!ate) if ((last = getc()) == EOF) goto in_scanf_end;
00915                         if (last != *format) { hit(); goto in_scanf_end; }
00916                         ate = false;
00917                 }
00918         } // 149
00919 in_scanf_end:
00920         va_end(v);
00921         return matched;
00922 }
00923 
00924 char* io::input::in_fmt(char* s, char d, char m) {
00925         int i = 0;
00926         if (fmt.hex()) {
00927                 if (isupper(d)) d = 'X';
00928                 else d = 'x';
00929         } else if (fmt.oct()) {
00930                 if (isupper(d)) d = 'O';
00931                 else d = 'o';
00932         }
00933         s[i++] = '%';
00934         if (!fmt.ltrim()) s[i++] = '^';
00935         if (fmt.endnl()) s[i++] = '$';
00936         if (fmt.deaf()) s[i++] = '*';
00937         i += sprintf(&(s[i]), "%d", fmt.width);
00938         if (m) s[i++] = m;
00939         s[i++] = d;
00940         s[i] = 0;
00941         return s;
00942 }
00943 
00944 io::input& io::input::operator>> (bool& val) {
00945         if (fmt.bin()) {
00946                 read((char*)&val, sizeof(bool), 1);
00947                 return *this;
00948         }
00949         char s[8];
00950         char t[24];
00951         if (fmt.btoa()) {
00952                 scanf(in_fmt(t, 's', 0), s);
00953                 if (!fmt.deaf()) {
00954                         if (!strcmp(s, "true")) val = true;
00955                         else val = false;
00956                 }
00957         } else {
00958                 scanf(in_fmt(t, 'd', 'b'), &val);
00959         }
00960         return *this;
00961 }
00962 io::input& io::input::operator>> (short& val) {
00963         if (fmt.bin()) {
00964                 read((char*)&val, sizeof(short), 1);
00965                 return *this;
00966         }
00967         char s[24];
00968         scanf(in_fmt(s, 'd', 'h'), &val);
00969         return *this;
00970 }
00971 io::input& io::input::operator>> (unsigned short &val) {
00972         if (fmt.bin()) {
00973                 read((char*)&val, sizeof(unsigned short), 1);
00974                 return *this;
00975         }
00976         char s[24];
00977         scanf(in_fmt(s, 'D', 'h'), &val);
00978         return *this;
00979 }
00980 io::input& io::input::operator>> (int& val) {
00981         if (fmt.bin()) {
00982                 read((char*)&val, sizeof(int), 1);
00983                 return *this;
00984         }
00985         char s[24];
00986         scanf(in_fmt(s, 'd', 0), &val);
00987         return *this;
00988 }
00989 io::input& io::input::operator>> (unsigned int& val) {
00990         if (fmt.bin()) {
00991                 read((char*)&val, sizeof(unsigned int), 1);
00992                 return *this;
00993         }
00994         char s[24];
00995         scanf(in_fmt(s, 'D', 0), &val);
00996         return *this;
00997 }
00998 io::input& io::input::operator>> (long& val) {
00999         if (fmt.bin()) {
01000                 read((char*)&val, sizeof(long), 1);
01001                 return *this;
01002         }
01003         char s[24];
01004         scanf(in_fmt(s, 'd', 'w'), &val);
01005         return *this;
01006 }
01007 io::input& io::input::operator>> (unsigned long& val) {
01008         if (fmt.bin()) {
01009                 read((char*)&val, sizeof(unsigned long), 1);
01010                 return *this;
01011         }
01012         char s[24];
01013         scanf(in_fmt(s, 'D', 'w'), &val);
01014         return *this;
01015 }
01016 io::input& io::input::operator>> (long long& val) {
01017         if (fmt.bin()) {
01018                 read((char*)&val, sizeof(long long), 1);
01019                 return *this;
01020         }
01021         char s[24];
01022         scanf(in_fmt(s, 'd', 'l'), &val);
01023         return *this;
01024 }
01025 io::input& io::input::operator>> (unsigned long long& val) {
01026         if (fmt.bin()) {
01027                 read((char*)&val, sizeof(unsigned long long), 1);
01028                 return *this;
01029         }
01030         char s[24];
01031         scanf(in_fmt(s, 'D', 'l'), &val);
01032         return *this;
01033 }
01034 io::input& io::input::operator>> (float& val) {
01035         if (fmt.bin()) {
01036                 read((char*)&val, sizeof(float), 1);
01037                 return *this;
01038         }
01039         char s[24];
01040         scanf(in_fmt(s, 'f', 0), &val);
01041         return *this;
01042 }
01043 io::input& io::input::operator>> (double& val) {
01044         if (fmt.bin()) {
01045                 read((char*)&val, sizeof(double), 1);
01046                 return *this;
01047         }
01048         char s[24];
01049         scanf(in_fmt(s, 'f', 'w'), &val);
01050         return *this;
01051 }
01052 io::input& io::input::operator>> (long double& val) {
01053         if (fmt.bin()) {
01054                 read((char*)&val, sizeof(long double), 1);
01055                 return *this;
01056         }
01057         char s[24];
01058         scanf(in_fmt(s, 'f', 'l'), &val);
01059         return *this;
01060 }
01061 io::input& io::input::operator>> (void*& val) {
01062         if (fmt.bin()) {
01063                 read((char*)&val, sizeof(void*), 1);
01064                 return *this;
01065         }
01066         char s[24];
01067         scanf(in_fmt(s, 'X', 'w'), &val);
01068         return *this;
01069 }
01070 io::input& io::input::operator>> (char& c) {
01071         if (fmt.bin()) {
01072                 read(&c, sizeof(char), 1);
01073                 return *this;
01074         }
01075         char s[24];
01076         scanf(in_fmt(s, 'c', 0), &c);
01077         return *this;
01078 }
01079 io::input& io::input::operator>> (char* s) {
01080         if (fmt.bin()) {
01081                 register int i;
01082                 int j;
01083                 for (i = 0, j = getc(); j; j = getc(), i++) {
01084                         if (j == -1) break;
01085                         s[i] = j;
01086                 }
01087                 s[i] = 0;
01088                 return *this;
01089         }
01090         char t[24];
01091         scanf(in_fmt(t, 's', 0), s);
01092         return *this;
01093 }
01094 
01101 int io::output::puts(const char* s) {
01102         register const char* t = s;
01103         for (; *t; t++)
01104                 if (putc(*t) == EOF)
01105                         return EOF;
01106         return t - s;
01107 }
01108 
01118 size_t io::output::write(const char* ptr, size_t size, size_t nmemb) {
01119         size_t i, j;
01120         for (i = 0; i < nmemb; i++)
01121                 for (j = 0; j < size; j++) {
01122                         putc(ptr[size * i + j]);
01123                         if (!ok()) return i;
01124                 }
01125         return i;
01126 }
01127 
01137 int io::output::printf(const char* format, ...) {
01138         char* s;
01139         va_list v;
01140         size_t i;
01141         int ret = 0;
01142         i = 32;
01143         va_start(v, format);
01144         s = (char*)malloc(i);
01145 #ifndef _WIN32
01146         while ((ret = vsnprintf(s, i, format, v)) >= i) {
01147                 i *= 2;
01148                 s = (char*)::realloc(s, i);
01149         }
01150 #else 
01151         for (;;) {
01152                 ret = vsnprintf(s, i, format, v);
01153                 if (ret != -1 && ret < i) break;
01154                 i *= 2;
01155                 s = (char*)::realloc(s, i);
01156         }
01157 #endif
01158         if (ret == -1) { hit(); free(s); va_end(v); return -1; }
01159         puts(s);
01160         free(s);
01161         va_end(v);
01162         return ret;
01163 }
01164 
01165 char* io::output::out_fmt(char* s, char t, const char* m) {
01166         int i = 0;
01167         switch (t) {
01168         case 'd': case 'i': case 'o': case 'u':
01169         case 'x': case 'X': 
01170         if (fmt.hex()) {
01171                 if (isupper(t)) t = 'X';
01172                 else t = 'x';
01173         } else if (fmt.oct()) {
01174                 if (isupper(t)) t = 'O';
01175                 else t = 'o';
01176         }
01177         default: ;
01178         }
01179         if (t == 'G')
01180                 if (fmt.fix()) t = 'F';
01181                 else if (fmt.sci()) t = 'E';
01182         s[i++] = '%';
01183         if (fmt.base()) s[i++] = '#';
01184         if (fmt.zpad()) s[i++] = '0';
01185         if (fmt.left()) s[i++] = '-';
01186         if (fmt.sign()) s[i++] = '+';
01187         if (fmt.width) i += sprintf(&(s[i]), "%d", fmt.width);
01188         if (fmt.precis) {
01189                 s[i++] = '.';
01190                 i += sprintf(&(s[i]), "%d", fmt.precis);
01191         }
01192         if (m) { strcpy(s + i, m); i += strlen(m); }
01193         s[i++] = t;
01194         s[i] = 0;
01195         return s;
01196 }
01197 io::output& io::output::operator<< (bool val) {
01198         if (fmt.bin()) {
01199                 write((const char*)&val, sizeof(bool), 1);
01200                 return *this;
01201         }
01202         if (fmt.btoa()) {
01203                 if (val) puts("true");
01204                 else puts("false");
01205         } else printf("%hhd", val);
01206         return *this;
01207 }
01208 io::output& io::output::operator<< (short val) {
01209         if (fmt.bin()) {
01210                 write((const char*)&val, sizeof(short), 1);
01211                 return *this;
01212         }
01213         char s[24];
01214         printf(out_fmt(s, 'd', "h"), val);
01215         return *this;
01216 }
01217 io::output& io::output::operator<< (unsigned short val) {
01218         if (fmt.bin()) {
01219                 write((const char*)&val, sizeof(unsigned short), 1);
01220                 return *this;
01221         }
01222         char s[24];
01223         printf(out_fmt(s, 'u', "h"), val);
01224         return *this;
01225 }
01226 io::output& io::output::operator<< (int val) {
01227         if (fmt.bin()) {
01228                 write((const char*)&val, sizeof(int), 1);
01229                 return *this;
01230         }
01231         char s[24];
01232         printf(out_fmt(s, 'd', 0), val);
01233         return *this;
01234 }
01235 io::output& io::output::operator<< (unsigned int val) {
01236         if (fmt.bin()) {
01237                 write((const char*)&val, sizeof(unsigned int), 1);
01238                 return *this;
01239         }
01240         char s[24];
01241         printf(out_fmt(s, 'u', 0), val);
01242         return *this;
01243 }
01244 io::output& io::output::operator<< (long val) {
01245         if (fmt.bin()) {
01246                 write((const char*)&val, sizeof(long), 1);
01247                 return *this;
01248         }
01249         char s[24];
01250         printf(out_fmt(s, 'd', "l"), val);
01251         return *this;
01252 }
01253 io::output& io::output::operator<< (unsigned long val) {
01254         if (fmt.bin()) {
01255                 write((const char*)&val, sizeof(unsigned long), 1);
01256                 return *this;
01257         }
01258         char s[24];
01259         printf(out_fmt(s, 'u', "l"), val);
01260         return *this;
01261 }
01262 io::output& io::output::operator<< (float val) {
01263         if (fmt.bin()) {
01264                 write((const char*)&val, sizeof(float), 1);
01265                 return *this;
01266         }
01267         char s[24];
01268         printf(out_fmt(s, 'G', 0), val);
01269         return *this;
01270 }
01271 io::output& io::output::operator<< (double val) {
01272         if (fmt.bin()) {
01273                 write((const char*)&val, sizeof(double), 1);
01274                 return *this;
01275         }
01276         char s[24];
01277         printf(out_fmt(s, 'G', 0), val);
01278         return *this;
01279 }
01280 io::output& io::output::operator<< (long double val) {
01281         if (fmt.bin()) {
01282                 write((const char*)&val, sizeof(long double), 1);
01283                 return *this;
01284         }
01285         char s[24];
01286         printf(out_fmt(s, 'G', "L"), val);
01287         return *this;
01288 }
01289 io::output& io::output::operator<< (const void* val) {
01290         if (fmt.bin()) {
01291                 write((const char*)&val, sizeof(const void*), 1);
01292                 return *this;
01293         }
01294         char s[24];
01295         printf(out_fmt(s, 'p', 0), val);
01296         return *this;
01297 }
01298 io::output& io::output::operator<< (char c) {
01299         if (fmt.bin()) {
01300                 write((const char*)&c, sizeof(char), 1);
01301                 return *this;
01302         }
01303         char s[24];
01304         printf(out_fmt(s, 'c', 0), c);
01305         return *this;
01306 }
01307 io::output& io::output::operator<< (signed char c) {
01308         if (fmt.bin()) {
01309                 write((const char*)&c, sizeof(signed char), 1);
01310                 return *this;
01311         }
01312         char s[24];
01313         printf(out_fmt(s, 'c', 0), c);
01314         return *this;
01315 }
01316 io::output& io::output::operator<< (unsigned char c) {
01317         if (fmt.bin()) {
01318                 write((const char*)&c, sizeof(unsigned char), 1);
01319                 return *this;
01320         }
01321         char s[24];
01322         printf(out_fmt(s, 'c', 0), c);
01323         return *this;
01324 }
01325 io::output& io::output::operator<< (const char* s) {
01326         if (fmt.bin()) {
01327                 register int i;
01328                 for (i = 0; s[i]; i++);
01329                 write((const char*)&s, sizeof(char), ++i);
01330                 return *this;
01331         }
01332         char t[24];
01333         printf(out_fmt(t, 's', 0), s);
01334         return *this;
01335 }
01336 /*io::output& io::output::echo(string s) {
01337         operator<<(s.buf);
01338         putc('\n');
01339         return *this;
01340 }
01341 io::output& io::output::put(string s) {
01342         operator<<(s.buf);
01343         return *this;
01344 }
01345 io::output& io::output::echo(timer c) {
01346         operator<<(c.str().buf);
01347         putc('\n');
01348         return *this;
01349 }
01350 io::output& io::output::put(timer c) {
01351         operator<<(c.str().buf);
01352         return *this;
01353 }*/
01354 
01355 string net::dgram::type() { return string("net::dgram"); }
01356 net::dgram::operator string () { string s; s << ip << '/' << port; return s; }
01357 
01358 data fs::fbread(const char* fname, size_t len) {
01359         FILE* f;
01360         data d;
01361         if (!len) len = fsize(fname);
01362         if ((f = fopen(fname, "rb")) == NULL) return d;
01363         d.realloc(len);
01364         fread(d.buf, 1, len, f);
01365         return d;
01366 }
01367 
01368 size_t fs::fbwrite(const char* fname, data d, size_t len) {
01369         FILE* f;
01370         if ((f = fopen(fname, "w+b")) == NULL) return 0;
01371         if (!len) len = d.len();
01372         register size_t i = fwrite(d.buf, 1, len, f);
01373         return i;
01374 }
01375 
01376 string data::type() { return string("data"); }
01377 data::operator string() {
01378         string s;
01379         register size_t i;
01380         for (i = 0; i < slen; i++)
01381                 s.printf("%02x ", ((unsigned char*)buf)[i]);
01382         return s;
01383 }
01384 size_t data::len() const { return slen; }
01385 bool data::operator== (data d) { if (len() != d.len()) return false; return !memcmp(buf, d.buf, len()); }
01386 bool data::operator!= (data d) { return !memcmp(buf, d.buf, len()); }
01387 data::data(const data& d) {
01388         fmt.bin(1);
01389         buf = 0; pos = 0; mlen = 0; slen = 0;
01390         realloc(d.len());
01391         memmove(buf, d.buf, d.len());
01392 }
01393 char& data::operator [](int i) { realloc(i + 1); return buf[i]; }
01394 data& data::operator= (data d) {
01395         if (buf) free(buf);
01396         rewind();
01397         buf = d.buf;
01398         slen = d.len();
01399         d.buf = 0;
01400         return *this;
01401 }
01402 
01403 void data::realloc(size_t i) {
01404         slen = i;
01405         register size_t n = i;
01406         while (n & (n - 1)) n++;
01407         if (mlen < n) {
01408                 if (buf) buf = (char*)::realloc(buf, n);
01409                 else { buf = (char*)malloc(n); buf[0] = 0; }
01410                 mlen = n;
01411                 buf[i - 1] = 0;
01412         }
01413 }
01414 data::data() { fmt.bin(1); buf = 0; pos = 0; mlen = 0; slen = 0; }
01415 data::~data() { if (buf) free(buf); }
01416 int string::getc() {
01417         if (pos > mlen) { kill(); return -1; }
01418         unsigned char c = buf[pos++];
01419         if (!c) { drain(); return -1; }
01420         else { heal(); return c; }
01421 }
01422 
01423 int data::getc() {
01424         if (pos > mlen) { drain(); return -1; }
01425         unsigned char c = buf[pos++];
01426         heal();
01427         return c;
01428 }
01429 int data::putc(int c) {
01430         (this->operator[] (pos++)) = c;
01431         heal(); return c;
01432 }
01433 bool data::seek(long offset, int whence) {
01434         if (whence == SEEK_SET) pos = offset;
01435         else if (whence == SEEK_END) pos = len() + offset;
01436         else if (whence == SEEK_CUR) pos += offset;
01437         else pos = offset + whence;
01438         if (pos > len()) return false;
01439         return true;
01440 }
01441 size_t data::tell() { return pos; }
01442 void data::rewind() { pos = 0; }
01443 void data::unwind() { pos = len(); }
01444 bool data::ffwd(size_t offset) {
01445         pos += offset;
01446         if (pos > len()) return false;
01447         return true;
01448 }
01449 bool data::prev(size_t offset) {
01450         pos -= offset;
01451         if (pos > len()) return false;
01452         return true;
01453 }
01454 
01455 string::string() { fmt.bin(0); buf = 0; pos = 0; mlen = 0; }
01456 
01457 string::string(const char* s) { 
01458         fmt.bin(0);
01459         buf = 0; pos = 0; mlen = 0;
01460         if (s) {
01461                 size_t i = strlen(s) + 1;
01462                 while (i & (i - 1)) i++;
01463                 buf = (char*)malloc(i);
01464                 mlen = i;
01465                 strcpy(buf, s);
01466         }
01467 }
01468 
01469 string::string(size_t n) { fmt.bin(0); buf = 0; pos = 0; mlen = 0; realloc(n); buf[0] = 0; }
01470 
01471 string::string(const string& s) {
01472         fmt.bin(0);
01473         buf = 0; pos = 0; mlen = s.msize();
01474         if (s.buf) {
01475                 buf = (char*)malloc(mlen);
01476                 strcpy(buf, s.buf);
01477         }
01478 }
01479 
01480 string::~string() { if (buf) { free(buf); buf = 0; }}
01481 
01482 /*int string::getc() {
01483         unsigned char c = buf[pos++];
01484         if (!c) { drain(); return -1; }
01485         else { heal(); return c; }
01486 }*/
01487 
01488 int string::putc(int c) {
01489         if (!buf) realloc(2);
01490         if (buf[pos] == 0 || pos >= mlen) {
01491                 realloc(pos + 4);
01492                 buf[pos + 1] = 0;
01493         }
01494         buf[pos++] = c; heal(); return c;
01495 }
01496 /*
01497 bool string::seek(long offset, int whence) {
01498         if (whence == SEEK_SET) pos = offset;
01499         else if (whence == SEEK_END) pos = len() + offset;
01500         else if (whence == SEEK_CUR) pos += offset;
01501         else pos = offset + whence;
01502         if (pos > len()) return false;
01503         return true;
01504 }
01505 size_t string::tell() { return pos; }
01506 string& string::rewind() { pos = 0; return *this; }
01507 string& string::unwind() { pos = len(); return *this; }
01508 bool string::ffwd(size_t offset) {
01509         pos += offset;
01510         if (pos > len()) return false;
01511         return true;
01512 }
01513 bool string::prev(size_t offset) {
01514         pos -= offset;
01515         if (pos > len()) return false;
01516         return true;
01517 }*/
01518 
01538 string string::esc(const char* format, int (*charfilter)(int)) {
01539         if (empty()) return string();
01540         string s;
01541         size_t i = tell();
01542         register int c;
01543         char d;
01544         rewind();
01545         for (c = getc(); c != EOF; c = getc()) {
01546                 d = c;
01547                 if (charfilter == NULL) s.printf(format, d);
01548                 else if (charfilter(d)) s.printf(format, d);
01549                 else s.putc(d);
01550         }
01551         seek(i, SEEK_SET);
01552         return s;
01553 }
01554 
01569 string string::esc(const char* format, const char* chrs) {
01570         string s;
01571         size_t i = tell();
01572         register int c;
01573         char d;
01574         rewind();
01575         for (c = getc(); c != EOF; c = getc()) {
01576                 d = c;
01577                 if (strchr(chrs, d)) s.printf(format, d);
01578                 else s.putc(d);
01579         }
01580         seek(i, SEEK_SET);
01581         return s;
01582 }
01583 
01594 string string::uesc(const char* format, const char* chrs) {
01595         string s(buf);
01596         string t;
01597         char c[2];
01598         c[1] = 0;
01599         for (*c = 0; *c < CHAR_MAX; (*c)++) {
01600                 if (strchr(chrs, *c)) {
01601                         t.printf(format, *c);
01602                         s = s.rep(t, c);
01603                 }
01604                 t.clear();
01605         }
01606         t.clear();
01607         if (strchr(chrs, *c)) {
01608                 t.printf(format, *c);
01609                 s = s.rep(t, c);
01610         }
01611         return s;
01612 }
01613 
01624 string string::uesc(const char* format, int (*charfilter)(int)) {
01625         string s(buf);
01626         string t;
01627         char c[2];
01628         c[1] = 0;
01629         for (*c = 0; *c < CHAR_MAX; (*c)++) {
01630                 if (charfilter == NULL) {
01631                         t.printf(format, *c);
01632                         s = s.rep(t, c);
01633                 } else if (charfilter(*c)) {
01634                         t.printf(format, *c);
01635                         s = s.rep(t, c);
01636                 }
01637                 t.clear();
01638         }
01639         t.clear();
01640         if (charfilter == NULL) {
01641                 t.printf(format, *c);
01642                 s = s.rep(t, c);
01643         } else if (charfilter(*c)) {
01644                 t.printf(format, *c);
01645                 s = s.rep(t, c);
01646         }
01647         return s;
01648 }
01649 
01650 /*string string::gets(int size) {
01651         string s;
01652         int i = 32, j = 0;
01653         register int c;
01654         s.realloc(i);
01655         for (c = getc(); ; c = getc(), j++) {
01656                 if (size) if (j >= size) break;
01657                 if (j >= i - 4) { i *= 2; s.realloc(i); }
01658                 switch (c) {
01659                 case EOF: s.buf[0] = 0; return s;
01660                 case '\n': s.buf[j] = '\n'; s.buf[++j] = 0; return s;
01661                 default: s.buf[j] = c;
01662                 }
01663         }
01664         s.buf[j] = 0;
01665         return s;
01666 }*/
01667 
01671 string string::q() {
01672         register size_t i = strlen(buf);
01673         string s(i + 3);
01674         strcpy(s.buf + 1, buf);
01675         s.buf[0] = '\'';
01676         s.buf[++i] = '\'';
01677         s.buf[++i] = 0;
01678         return s;
01679 }
01680 
01684 string string::qq() {
01685         register size_t i = strlen(buf);
01686         string s(i + 3);
01687         strcpy(s.buf + 1, buf);
01688         s.buf[0] = '\"';
01689         s.buf[++i] = '\"';
01690         s.buf[++i] = 0;
01691         return s;
01692 }
01693 
01697 string string::qx() {
01698         string s;
01699         fs::file pipe;
01700         pipe.fd = popen(buf, "r");
01701         if (!pipe.fd) return s;
01702         until (pipe.eof()) s += pipe.getc();
01703         s = s.chop();
01704         pclose(pipe.fd);
01705         return s;
01706 }
01707 
01708 /*string string::htmlesc() {
01709         string s(buf);
01710         string t;
01711         register int i;
01712         for (i = 0; entnames[i].c; i++)
01713                 t.puts(entnames[i].c);
01714         t.putc(0);
01715         s = s.esc("&#%d;", t);
01716         return s;
01717 }
01718 string string::htmluesc() {
01719         string s(buf);
01720         string t;
01721         char b[2];
01722         register int i;
01723         b[1] = 0;
01724         for (i = 0; entnames[i].c; i++) {
01725                 t.putc(entnames[i].c);
01726                 b[0] = entnames[i].c;
01727                 s = s.rep(entnames[i].name, b);
01728         }
01729         t.putc(0);
01730         s = s.uesc("&#%d;", t);
01731         //s = s.uesc("&#%d;", "\"'&<> ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿×÷ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ");
01732         return s;
01733 }*/
01734 
01738 char& string::front() { return buf[0]; };
01739 
01743 char& string::back() { return buf[strlen(buf) - 1]; }
01744 
01748 string& string::clear() { realloc(2); pos = 0; buf[0] = 0; return *this; }
01749 
01753 bool string::empty() { if (buf) return buf[0] == 0; else return true; }
01754 
01758 size_t string::len() { if (buf) return strlen(buf); else return 0; }
01759 
01760 
01761 io::output& io::output::operator<< (string s) { return operator<<(s.buf); }
01762 
01770 /*string& string::realloc(size_t i) {
01771         register size_t n = i;
01772         while (n & (n - 1)) n++;
01773         if (mlen < n) {
01774                 if (buf) buf = (char*)::realloc(buf, n);
01775                 else { buf = (char*)malloc(n); buf[0] = 0; }
01776                 mlen = n;
01777                 buf[i - 1] = 0;
01778         }
01779         return *this;
01780 }*/
01781 
01785 size_t string::msize() const { return mlen; }
01786 
01792 string string::cat(const char* s, size_t n) {
01793         string t;
01794         register size_t i = this->len();
01795         if (!n) n = strlen(s) + 1;
01796         t.realloc(i + n);
01797         strcpy2(t.buf, buf);
01798         for (; n > 0; i++, n--, s++)
01799                 t.buf[i] = *s;
01800         t.buf[i] = 0;
01801         return t;
01802 }
01803 
01804 string string::wrap(size_t len, const char* eol) {
01805         string s;
01806         size_t i, j, k = strlen(buf);
01807         for (i = 0, j = 0; i < k; i++, j++) {
01808                 if (j == len) {
01809                         s << eol;
01810                         j = 0;
01811                 }
01812                 s << buf[i];
01813         }
01814         s.rewind();
01815         return s;
01816 }
01817 
01823 string string::cat(int c, size_t n) {
01824         string t;
01825         register size_t i;
01826         if (buf) i = strlen(buf);
01827         else i = 0;
01828         t.realloc(i + n + 1);
01829         if (buf) strcpy(t.buf, buf);
01830         for (; n > 0; n--, i++)
01831                 t.buf[i] = c;
01832         t.buf[i] = 0;
01833         return t;
01834 }
01835 
01841 string string::prep(const char* s, size_t n) {
01842         string t;
01843         if (!n) n = strlen(s);
01844         register size_t i;
01845         if (buf) i = strlen(buf);
01846         else i = 0;
01847         t.realloc(n + i + 1);
01848         strncpy(t.buf, s, n);
01849         t.buf[n] = 0;
01850         if (buf) strcat(t.buf, buf);
01851         return t;
01852 }
01853 
01859 string string::prep(int c, size_t n) {
01860         string t;
01861         register size_t i;
01862         if (buf) i = strlen(buf);
01863 
01864         else i = 0;
01865         t.realloc(i + n + 1);
01866         for (i = 0; i < n; i++) t.buf[0] = c;
01867         if (buf) strcpy(&(t.buf[i]), buf);
01868         t.buf[strlen(t.buf)] = 0;
01869         return t;
01870 }
01871 
01877 long string::chr(int c, size_t index) {
01878         if (len() == 0) return -1;
01879         register char* s = strchr(buf + index, c);
01880         if (s == NULL) return -1;
01881         return s - (buf + index);
01882 }
01883 
01888 long string::rchr(int c) {
01889         if (len() == 0) return -1;
01890         register char* s = strrchr(buf, c);
01891         if (s == NULL) return -1;
01892         return s - buf;
01893 }
01894 
01900 long string::str(const char* s, size_t index) {
01901         if (len() == 0) return -1;
01902         register char* t = strstr(buf + index, s);
01903         if (t == NULL) return -1;
01904         return t - (buf + index);
01905 }
01906 
01911 long string::rstr(const char* s) {
01912         if (len() == 0) return -1;
01913         char *t, *u;
01914         for(t = strstr(buf, s), u = t; t; t = strstr(u, s))
01915                 if (t) u = t;
01916         return u - buf;
01917 }
01918 
01923 size_t string::nchr(int ch) {
01924         if (len() == 0) return 0;
01925         register size_t i, j;
01926         for (i = 0, j = 0; buf[i]; i++)
01927                 if (buf[i] == ch) j++;
01928         return j;
01929 }
01930 
01935 size_t string::nstr(const char* str) {
01936         char* t = buf;
01937         register size_t i;
01938         size_t j = strlen(str);
01939         for (i = 0, t = strstr(t, str); t != NULL; i++, t = strstr(t, str))
01940                 t += j;
01941         return i;
01942 }
01943 
01948 bool string::starts(const char* s) { if (!buf) return false; return !strncmp(buf, s, strlen(s)); }
01949 
01954 bool string::starts(int c) { if (!buf) return false; return (buf[0] == c); }
01955 
01960 bool string::ends(const char* s) {
01961         if (!buf) return false;
01962         register size_t i = strlen(buf), j = strlen(s);
01963         return !strncmp(buf + i - j, s, j);
01964 }
01965 
01970 bool string::ends(int c) { if (!buf) return false; return (buf[strlen(buf) - 1] == c); }
01971 
01976 bool string::is(const char* s) { if (!buf) return false; return !strcmp(buf, s); }
01977 
01982 bool string::is(int c) { if (!buf) return false; return (buf[0] == c && buf[1] == 0); }
01983 
01988 string string::left(size_t n) {
01989         string s;
01990         s.realloc(n + 1);
01991         strncpy(s.buf, buf, n);
01992         s.buf[n] = 0;
01993         return s;
01994 }
01995 
02000 string string::right(size_t n) {
02001         string s;
02002         s.realloc(n + 1);
02003         strcpy(s.buf, buf + strlen(buf) - n);
02004         return s;
02005 }
02006 
02013 string string::cpy(const char* src, size_t index, size_t count) {
02014         if (!count) count = strlen(src);
02015         string t(index + count + 1);
02016         strncpy(t.buf, buf, index);
02017         strncpy(t.buf + index, src, count);
02018         t.buf[index + count] = 0;
02019         return t;
02020 }
02021 
02028 string string::cpy(int c, size_t index, size_t count) {
02029         string t(index + count + 1);
02030         strncpy(t.buf, buf, index);
02031         for (; count > 0; index++, count--) t.buf[index] = c;
02032         t.buf[index] = 0;
02033         return t;
02034 }
02035 
02036 /*
02037 string string::ncpy(const char* src, size_t n, size_t index) {
02038         if (!n) n = strlen(src);
02039         size_t i = strlen(buf);
02040         string t(i + n + 1);
02041         strcpy(t.buf, buf);
02042         strncpy(t.buf, src, n);
02043         return t;
02044 }*/
02045 
02051 size_t string::spn(const char* accept, size_t index) { if (len() == 0) return 0; return strspn(buf + index, accept); }
02052 
02058 size_t string::cspn(const char* reject, size_t index) { if (len() == 0) return 0; return strcspn(buf + index, reject); }
02059 
02065 size_t string::spn(int c, size_t index) {
02066         if (len() == 0) return 0;
02067         register size_t i;
02068         for (i = 0; buf[index] == c; index++) i++;
02069         return i;
02070 }
02071 
02077 size_t string::cspn(int c, size_t index) {
02078         if (len() == 0) return 0;
02079         register size_t i;
02080         for (i = 0; buf[index] != c; index++) i++;
02081         return i;
02082 }
02083 
02087 string string::fry() {
02088         string t(buf);
02089         if (!buf[1]) return t;
02090         static unsigned int seed;
02091         unsigned int ck = t.cksum();
02092         srand(seed ^ time(NULL));
02093         char *a, *b, c;
02094         int i, j = strlen(buf);
02095         for (i = 0; i < j; i++) {
02096                 a = &(t.buf[rand() % j]);
02097                 b = &(t.buf[rand() % j]);
02098                 c = *a;
02099                 *a = *b;
02100                 *b = c;
02101         }
02102         seed = rand();
02103         if (t.cksum() == ck) t = t.fry();
02104         return t;
02105 }
02106 
02114 long string::pbrk(const char* accept, size_t index) {
02115         if (len() == 0) return 0;
02116         register char* s = strpbrk(buf + index, accept);
02117         if (s == NULL) return -1;
02118         return s - (buf + index);
02119 }
02120 
02128 long string::rpbrk(const char* accept, size_t index) {
02129         if (len() == 0) return 0;
02130         char *s, *t;
02131         for(s = strpbrk(buf + index, accept), t = s; s; s = strpbrk(t + 1, accept))
02132                 if (s) t = s;
02133         return t - (buf + index);
02134 }
02135 
02141 string string::substr(size_t start, size_t count) {
02142         string t;
02143         if (len() == 0) return t;
02144         t.realloc(count + 1);
02145         strncpy(t.buf, buf + start, count);
02146         t.buf[count] = 0;
02147         return t;
02148 }
02149 
02158 string string::tok(size_t index, const char* delim) {
02159         if (empty()) return *this;
02160         string s(buf);
02161         char *u;
02162         s = s.squeeze(delim);
02163         while (s.pbrk(delim) == 0) s = s.shl(1);
02164         while (s.pbrk(delim) == s.len() - 1) s = s.shr(1);
02165         u = strtok(s.buf, delim);
02166         for (; index > 0 && u; index--)
02167                 u = strtok(NULL, delim);
02168         if (u) memmove(s.buf, u, strlen(u) + 1);
02169         else s.clear();
02170         return s;
02171 }
02172 
02181 string string::tok(size_t index, int delim) {
02182         char x[2];
02183         x[0] = delim;
02184         x[1] = 0;
02185         return tok(index, x);
02186 }
02187 
02195 size_t string::ntok(const char* delim) {
02196         if (empty()) return 0;
02197         size_t i;
02198         char *p, *tmp = (char*)malloc(strlen(buf) + 1);
02199         strcpy(tmp, buf);
02200         for (
02201                 p = strtok(tmp, delim), i = 0;
02202                 p; p = strtok(0, delim), i++
02203         );
02204         free(tmp);
02205         return i;
02206 }
02207 
02215 size_t string::ntok(int delim) {
02216         char s[2]; s[0] = delim; s[1] = 0;
02217         return this->ntok(s);
02218 }
02219 
02235 long string::itok(size_t index, const char* delim) {
02236         register long a;
02237         for (a = 0; buf[a] && index > 0; a++) {
02238                 if (strchr(delim, buf[a])) {
02239                         do {
02240                                 a++;
02241                         } while (strchr(delim, buf[a]));
02242                         a--;
02243                         index--;
02244                 }
02245         }
02246         if (buf[a] == 0) return -1;
02247         return a;
02248 }
02249 
02265 long string::itok(size_t index, int delim) {
02266         char x[2];
02267         x[0] = delim; x[1] = 0;
02268         return itok(index, x);
02269 }
02270 
02278 std::deque<axcel::string> string::split(const char* delim) {
02279         std::deque<axcel::string> d;
02280         char* s = (char*)malloc(strlen(buf) + 1);
02281         strcpy(s, buf);
02282         const char* t = strtok(s, delim);
02283         for (; t != NULL; t = strtok(NULL, delim))
02284                 d.push_back(string(t));
02285         free(s);
02286         return d;
02287 }
02288 
02296 std::deque<axcel::string> string::split(int delim) { char x[2]; x[0] = delim; x[1] = 0; return split(x); }
02297 
02303 string string::ins(size_t index, const char* str) {
02304         if (empty()) return string();
02305         size_t len1 = strlen(str), len2 = strlen(buf);
02306         string s(len1 + len2 + 1);
02307         strncpy(s.buf, buf, index);
02308         s.buf[index] = 0;
02309         strncat(s.buf, str, len1);
02310         strcpy(s.buf + index + len1, buf + index);
02311         return s;
02312 }
02313 
02319 string string::ins(size_t index, int c) {
02320         if (empty()) return string();
02321         char x[2]; x[0] = c; x[1] = 0;
02322         return ins(index, x);
02323 }
02324 
02330 string string::rm(size_t index, size_t n) {
02331         if (empty()) return string();
02332         size_t i = strlen(buf);
02333         string s(i - n + 1);
02334         strncpy(s.buf, buf, index);
02335         s.buf[index] = 0;
02336         strcat(s.buf, buf + index + n);
02337         return s;
02338 }
02339 
02345 string string::rev(size_t start, size_t count) {
02346         if (empty()) return string();
02347         if (!count) count = strlen(buf) - start;
02348         string s(strlen(buf) + 1);
02349         size_t i, j;
02350         for (i = 0, j = 0; ; i++, j++) {
02351                 if (j == start) {
02352                         for (j += count - 1; j > start; j--, i++)
02353                                 s.buf[i] = buf[j];
02354                         s.buf[i++] = buf[j];
02355                         j += count;
02356                 }
02357                 s.buf[i] = buf[j];
02358                 if (!s.buf[i]) break;
02359         }
02360         return s;
02361 }
02362 
02367 string string::dup(int i) {
02368         if (empty()) return string();
02369         size_t n = strlen(buf);
02370         string s(n * i + 1);
02371         strcpy(s.buf, buf);
02372         for (i--; i > 0; i--)
02373                 strcat(s.buf, buf);
02374         return s;
02375 }
02376 
02383 string string::rol(size_t i, size_t index, size_t count) {
02384         if (empty()) return string();
02385         if (!count) count = strlen(buf) - index;
02386         string s(strlen(buf) + 1);
02387         strncpy(s.buf, buf, index);
02388         strncpy(s.buf + index, buf + index + i, count - i);
02389         strncpy(s.buf + index + count - i, buf + index, i);
02390         s.buf[index + count] = 0;
02391         strcat(s.buf, buf + index + count);
02392         return s;
02393 }
02394 
02401 string string::ror(size_t i, size_t index, size_t count) {
02402         if (empty()) return string();
02403         if (!count) count = strlen(buf) - index;
02404         string s(strlen(buf) + 1);
02405         strncpy(s.buf, buf, index);
02406         strncpy(s.buf + index, buf + index + count - i, i);
02407         strncpy(s.buf + index + i, buf + index, count - i);
02408         s.buf[index + count] = 0;
02409         strcat(s.buf, buf + index + count);
02410         return s;
02411 }
02412 
02417 string string::shl(size_t n) {
02418         if (empty()) return string();
02419         string s(strlen(buf) - n + 1);
02420         strcpy(s.buf, buf + n);
02421         return s;
02422 }
02423 
02428 string string::shr(size_t n) {
02429         if (empty()) return string();
02430         register size_t i = strlen(buf) - n;
02431         string s(i + 1);
02432         strncpy(s.buf, buf, i);
02433         s.buf[i] = 0;
02434         return s;
02435 }
02436 
02442 string string::lc(size_t start, size_t count) {
02443         if (empty()) return string();
02444         if (!count) count = strlen(buf) - start;
02445         string s(strlen(buf) + 1);
02446         size_t i;
02447         for (i = 0; i < start; i++) s.buf[i] = buf[i];
02448         for (; count > 0; count--, i++) s.buf[i] = tolower(buf[i]);
02449         for (; buf[i]; i++) s.buf[i] = buf[i];
02450         s.buf[i] = 0;
02451         return s;
02452 }
02453 
02454 
02460 string string::uc(size_t start, size_t count) {
02461 
02462         if (empty()) return string();
02463         if (!count) count = strlen(buf) - start;
02464         string s(strlen(buf) + 1);
02465         size_t i;
02466         for (i = 0; i < start; i++) s.buf[i] = buf[i];
02467         for (; count > 0; count--, i++) s.buf[i] = toupper(buf[i]);
02468         for (; buf[i]; i++) s.buf[i] = buf[i];
02469         s.buf[i] = 0;
02470         return s;
02471 }
02472 
02473 
02477 string string::ltrim() {
02478         if (empty()) return string();
02479         size_t i = 0;
02480         for (; ::isspace(buf[i]); i++);
02481         string s(strlen(buf + i) + 1);
02482         strcpy(s.buf, buf + i);
02483         return s;
02484 }
02485 
02489 string string::rtrim() {
02490         if (empty()) return string();
02491         size_t i = strlen(buf) - 1;
02492         for (; ::isspace(buf[i]); i--);
02493         string s(i += 2);
02494         strncpy(s.buf, buf, --i);
02495         s.buf[i] = 0;
02496         return s;
02497 }  
02498 
02502 string string::strip() {
02503         if (empty()) return string();
02504         string s(buf);
02505         s = s.rtrim();
02506         s = s.ltrim();
02507         return s;
02508         /*size_t i = 0, j = strlen(buf) - 1, k = strlen(buf);
02509         for (; isspace(buf[i]); i++);
02510         if (i >= k) return string();
02511         for (; isspace(buf[j]); j--);
02512         string s(k - i - (k - j) + 1);
02513         strncpy(s.buf, buf + i, j - i + 1);
02514         s.buf[j - i + 1] = 0;
02515         return s;*/
02516 }
02517 
02521 string string::chop() {
02522         string s;
02523         if (empty()) return s;
02524         size_t i = strlen(buf);
02525         if (this->ends("\r\n")) {
02526                 s.realloc(--i); i--;
02527         } else s.realloc(i--);
02528         s.buf[i] = 0;
02529         strncpy(s.buf, buf, i);
02530         return s;
02531 }
02532 
02533 
02538 string string::chomp(const char* eat) {
02539         string s;
02540         if (empty()) return s;
02541         size_t i = strlen(buf);
02542         char* t;
02543         if (!strcmp(eat, "\r\n")) {
02544                 s = buf;
02545                 t = strrchr(s.buf, '\n');
02546                 if (t) *t = 0;
02547                 t = strrchr(s.buf, '\r');
02548                 if (t) *t = 0;
02549                 return s;
02550         }
02551         if (this->ends(eat)) {
02552                 i -= strlen(eat);
02553                 i++;
02554                 s.realloc(i); i--;
02555         } else s.realloc(i + 1);
02556         s.buf[i] = 0;
02557         strncpy(s.buf, buf, i);
02558         return s;
02559 }
02560 
02564 string string::cut() {
02565         string s;
02566         if (empty()) return s;
02567         size_t i = strlen(buf);
02568         if (this->starts("\r\n")) {
02569                 s.realloc(--i); i--;
02570         } else s.realloc(i--);
02571         s.buf[i] = 0;
02572         strncpy(s.buf, buf + (strlen(buf) - i), i);
02573         return s;
02574 }
02575 
02580 string string::munch(const char* eat) {
02581         string s;
02582         if (empty()) return s;
02583         if (this->starts(eat)) s = (buf + strlen(eat));
02584         else s = buf;
02585         return s;
02586 }
02587 
02588 
02593 string& string::swap(string& s) {
02594         size_t i = s.msize();
02595         char* t = s.buf;
02596         s.buf = buf;
02597         s.realloc(mlen);
02598         mlen = i;
02599         buf = t;
02600         return *this;
02601 }
02602 
02603 
02610 string string::center(size_t newlen, const char* left, const char* right) {
02611         string s(buf); 
02612         if (newlen <= strlen(s.buf) + 1) return s;
02613         size_t i = (newlen - strlen(s.buf)) / 2;
02614         s = s.rpad(i + strlen(s.buf), right);
02615         s = s.lpad(i + strlen(s.buf), left);
02616         return s;
02617 }
02618 
02625 string string::center(size_t newlen, int left, int right) {
02626         char a[2], b[2];
02627         a[0] = left; a[1] = 0;
02628         b[0] = right; b[1] = 0;
02629         return center(newlen, a, b);
02630 }
02631 
02637 string string::center(size_t newlen, const char* pad) {
02638         return center(newlen, pad, pad);
02639 }
02640 
02646 string string::center(size_t newlen, int pad) {
02647         char a[2];
02648         a[0] = pad; a[1] = 0;
02649         return center(newlen, a, a);
02650 }
02651 
02657 string string::lpad(size_t newlen, const char* pad) {
02658         if (newlen <= strlen(buf)) return *this;
02659         string s(newlen + 1);
02660         size_t i, j, len1 = strlen(pad), len2 = newlen - strlen(buf);
02661         strcpy(s.buf + len2, buf);
02662         for (i = 0, j = 0; i < len2; i++, j++) {
02663                 if (j == len1) j = 0;
02664                 s.buf[i] = pad[j];
02665         }
02666         return s;
02667 }
02668 
02674 string string::rpad(size_t newlen, const char* pad) {
02675         if (newlen <= strlen(buf)) return *this;
02676         string s(newlen + 1);
02677         size_t i, j, len1 = strlen(pad);
02678         strcpy(s.buf, buf);
02679         for (i = strlen(buf), j = 0; i < newlen; i++, j++) {
02680                 if (j == len1) j = 0;
02681                 s.buf[i] = pad[j];
02682         }
02683         s.buf[i] = 0;
02684         return s;
02685 }
02686 
02692 string string::lpad(size_t newlen, int pad) {
02693         char a[2];
02694         a[0] = pad; a[1] = 0;
02695         return lpad(newlen, a);
02696 }
02697 
02703 string string::rpad(size_t newlen, int pad) {
02704         char a[2];
02705         a[0] = pad; a[1] = 0;
02706         return rpad(newlen, a);
02707 }
02708 
02713 string string::squeeze(const char* chrs) {
02714         string s(strlen(buf) + 1);
02715         size_t i, k;
02716         if (!chrs) {
02717                 for (i = 0, k = 0; buf[i]; i++, k++) {
02718                         s.buf[k] = buf[i];
02719                         while (buf[i] == buf[i + 1]) i++;
02720                 }
02721         } else {
02722                 for (i = 0, k = 0; buf[i]; i++, k++) {
02723                         s.buf[k] = buf[i];
02724                         if (strchr(chrs, buf[i]))
02725                                 while (buf[i] == buf[i + 1]) i++;
02726                 }
02727         }
02728         s.buf[k] = 0;
02729         return s;
02730 }
02731 
02736 string string::squeeze(int chr) {
02737         char a[2];
02738         a[0] = chr; a[1] = 0;
02739         return squeeze(a);
02740 }
02741 
02746 string string::ctypes(int (*cfunc)(int)) {
02747         if (empty()) return *this;
02748         string s(strlen(buf) + 1);
02749         register size_t i, j;
02750         for (i = 0, j = 0; buf[i]; i++)
02751                 if (cfunc(buf[i])) s.buf[j++] = buf[i];
02752         s.buf[j] = 0;
02753         return s;
02754 }
02755 
02760 string string::ctypes(const char* chrs) {
02761         if (empty()) return *this;
02762         string s(strlen(buf) + 1);
02763         register size_t i, j;
02764         for (i = 0, j = 0; buf[i]; i++)
02765                 if (strchr(chrs, buf[i])) s.buf[j++] = buf[i];
02766         s.buf[j] = 0;
02767         return s;
02768 }
02769 
02774 bool string::isctype(int (*cfunc)(int)) {
02775         if (empty()) return false;
02776         register size_t i;
02777         for (i = 0; buf[i]; i++)
02778                 if (!cfunc(buf[i])) return false;
02779         return true;
02780 }
02781 
02786 bool string::isctype(const char* chrs) {
02787         if (empty()) return false;
02788         register size_t i;
02789         for (i = 0; buf[i]; i++)
02790                 if (!strchr(chrs, buf[i])) return false;
02791         return true;
02792 }
02793 
02797 string string::alnums() { return ctypes(::isalnum); }
02798 
02802 string string::alphas() { return ctypes(::isalpha); }
02803 
02807 string string::cntrls() { return ctypes(::iscntrl); }
02808 
02812 string string::digits() { return ctypes(::isdigit); }
02813 
02817 string string::graphs() { return ctypes(::isgraph); }
02818 
02822 string string::puncts() { return ctypes(::ispunct); }
02823 
02827 string string::lowers() { return ctypes(::islower); }
02828 
02832 string string::prints() { return ctypes(::isprint); }
02833 
02837 string string::spaces() { return ctypes(::isspace); }
02838 
02842 string string::uppers() { return ctypes(::isupper); }
02843 
02847 string string::xdigits() { return ctypes(::isxdigit); }
02848 
02852 bool string::isalnum() { return isctype(::isalnum); }
02853 
02857 bool string::isalpha() { return isctype(::isalpha); }
02858 
02862 bool string::iscntrl() { return isctype(::iscntrl); }
02863 
02867 bool string::isdigit() { return isctype(::isdigit); }
02868 
02872 bool string::isgraph() { return isctype(::isgraph); }
02873 
02877 bool string::islower() { return isctype(::islower); }
02878 
02882 bool string::isprint() { return isctype(::isprint); }
02883 
02887 bool string::ispunct() { return isctype(::ispunct); }
02888 
02892 bool string::isspace() { return isctype(::isspace); }
02893 
02897 bool string::isupper() { return isctype(::isupper); }
02898 
02902 bool string::isxdigit() { return isctype(::isxdigit); }
02903 
02913 string string::inc() {
02914         string s(buf); 
02915         register char carry = 0;
02916         size_t i = strlen(s.buf) - 1;
02917         long j;
02918         do {
02919                 if (s.buf[i] == 'z' || s.buf[i] == 'Z') {
02920                         carry = 1;
02921                         s.buf[i] = s.buf[i] - 25;
02922                 } else if (s.buf[i] == '9') {
02923                         carry = 1;
02924                         s.buf[i] = '0';
02925                 } else if (::isalnum(s.buf[i])) {
02926                         carry = 0;
02927                         s.buf[i] = s.buf[i] + 1;
02928                         break;
02929                 }
02930         } while (i--);
02931         if (carry) {
02932                 j = s.pbrk("Aa0");
02933                 if (s.buf[j] == '0')
02934                         s = s.ins(j, '1');
02935                 else if (s.buf[j] == 'a')
02936                         s = s.ins(j, 'a');
02937                 else if (s.buf[j] == 'A')
02938                         s = s.ins(j, 'A');
02939         }
02940         return s;
02941 }
02942 
02947 string string::add(int n) {
02948         register int i;
02949         string s(buf);
02950         for (i = 0; i < n; i++) s = s.inc();
02951         return s;
02952 }
02953 
02958 string string::sub(int n) {
02959         register int i;
02960         string s(buf);
02961         for (i = 0; i < n; i++) s = s.dec();
02962         return s;
02963 }
02964 
02968 string string::incn() {
02969         string s(buf); 
02970         register char carry = 0;
02971         size_t i = strlen(s.buf) - 1;
02972         long j;
02973         do {
02974                 if (s.buf[i] == '9') {
02975                         carry = 1;
02976                         s.buf[i] = '0';
02977                 } else if (::isdigit(s.buf[i])) {
02978                         carry = 0;
02979                         s.buf[i] = s.buf[i] + 1;
02980                         break;
02981                 }
02982         } while (i--);
02983         if (carry)
02984                         s = s.ins(s.chr('0'), '1');
02985         return s;
02986 }
02987 
02997 string string::dec() {
02998         string s(buf);
02999         register char borrow = 0;
03000         long last = -1;
03001         size_t i = strlen(s.buf) - 1;
03002         do {
03003                 if (s.buf[i] == 'a' || s.buf[i] == 'A') {
03004                         borrow = 1;
03005                         s.buf[i] = s.buf[i] + 25;
03006                 }       else if (s.buf[i] == '0') {
03007                         borrow = 1;
03008                         s.buf[i] = '9';
03009                 } else if (::isalnum(s.buf[i])) {
03010                         borrow = 0;
03011                         s.buf[i] = s.buf[i] - 1;
03012                         if (s.buf[i] == '0'/* || buf [i] == 'a' || buf[i] == 'A'*/)
03013                                 last = i;
03014                         break;
03015                 }
03016         } while (i--);
03017         if (borrow)
03018                 if (s.pbrk("9zZ") != s.rpbrk("9zZ"))
03019                         s = s.rm(s.pbrk("9zZ"), 1);
03020                 else {
03021                         long c = s.pbrk("9zZ");
03022                         if (::isalpha(s.buf[c])) s.buf[c] = s.buf[c] - 25;
03023                         else if (::isdigit(s.buf[c])) s.buf[c] = '0';
03024                 }
03025         if (last > -1)
03026                 if (s.pbrk("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") == last &&
03027                          s.rpbrk("1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") != last)
03028                         s = s.rm(last, 1);
03029         return s;
03030 }
03031 
03035 string string::decn() {
03036         string t(buf); 
03037         register char borrow = 0;
03038         long last = -1, s;
03039         size_t i = strlen(t.buf) - 1;
03040         do {
03041                 if (t.buf[i] == '0') {
03042                         borrow = 1;
03043                         t.buf[i] = '9';
03044                 } else if (::isdigit(t.buf[i])) {
03045                         borrow = 0;
03046                         t.buf[i] = t.buf[i] - 1;
03047                         if (t.buf[i] == '0')
03048                                 last = i;
03049                         break;
03050                 }
03051         } while (i--);
03052         if (borrow) {
03053                 s = t.chr('9');
03054                 if (s != t.rchr('9'))
03055                         t = t.rm(s, 1);
03056                 else t.buf[s] = '0';
03057         }
03058         if (last > -1)
03059                 if (t.pbrk("1234567890") == last &&
03060                          t.rpbrk("1234567890") != last)
03061                         t = t.rm(last, 1);
03062         return t;
03063 }
03064 
03065 string string::add(const char* s) {
03066         string t(s);
03067         string u(buf);
03068         t = t.alnums();
03069         if (t == 'a' || t == 'A' || t == '0') {
03070                 u = u.inc();
03071                 return u;
03072         } else if (u == 'a' || u == 'A' || u == '0') {
03073                 u = t;
03074                 u = u.inc();
03075                 return u;
03076         }
03077         do {
03078                 u = u.inc();
03079                 t = t.dec();
03080         } while (t != 'a' && t != 'A' && t != '0' && t.len());
03081         if (t == 'a' || t == 'A') u = u.inc();
03082         return u;
03083 }
03084 string string::sub(const char* s) {
03085         string t(s);
03086         string u(buf); 
03087         t = t.alnums();
03088         if (t == 'a' || t == 'A' || t == '0') {
03089                 u = u.dec();
03090                 return u;
03091         } else if (u == 'a' || u == 'A' || u == '0') {
03092                 u = t;
03093                 u = u.dec();
03094                 return u;
03095         }
03096         do {
03097                 u = u.dec();
03098                 t = t.dec();
03099         } while (t != 'a' && t != 'A' && t != '0' && t.len());
03100         if (t == 'a' || t == 'A') u = u.dec();
03101         return u;
03102 }
03103 
03108 string string::chomp(char c) {
03109         char x[2];
03110         x[0] = c; x[1] = 0;
03111         return chomp(x);
03112 }
03113 
03118 string string::munch(char c) {
03119         char x[2];
03120         x[0] = c; x[1] = 0;
03121         return munch(x);
03122 }
03123 
03128 string string::addn(int n) { string s(buf); for (; n; n--) s = s.incn(); return s; }
03129 string string::addn(const char* s) {
03130         string t(s);
03131         string u(buf);
03132         u = u.addn(atoi(t.digits()));
03133         return u;
03134 }
03135 
03140 string string::subn(int n) { string s(buf); for (; n; n--) s = s.decn(); return s; }
03141 string string::subn(const char* s) {
03142         string t(s);
03143         string u(buf);
03144         u = u.subn(atoi(t.digits()));
03145         return u;
03146 }
03147 
03151 unsigned short string::cksum() {
03152         size_t i;
03153         unsigned short sum = 0;
03154         for (i = 0; buf[i]; i++) {
03155                 sum = (sum >> 1) + ((sum & 1) << 15);
03156                 sum += buf[i];
03157                 sum &= 0xffff;
03158         }
03159         return sum;
03160 }
03161 
03162 string& string::operator =(string s) {
03163         if (s.empty()) { clear(); return *this; }
03164         if (buf) free(buf);
03165         buf = s.buf;
03166         mlen = s.msize();
03167         s.buf = 0;
03168         return *this;
03169 }
03170 
03171 string& string::operator =(const char* s) {
03172         if (s == 0) { clear(); return *this; }
03173         realloc(strlen(s) + 1);
03174         strcpy2(buf, s);
03175         return *this;
03176 }
03177 /*string& string::operator =(char c) {
03178         ::puts("char");
03179         this->realloc(2);
03180         buf[0] = c; buf[1] = 0;
03181         return *this;
03182 }*/
03183 
03188 string string::operator +(const char* str) { return this->cat(str); }
03189 
03194 string string::operator +(char c) { return this->cat(c); }
03195 
03200 string& string::operator +=(const char* str) { *this = this->cat(str); return *this; }
03201 
03206 string& string::operator +=(char c) { *this = this->cat(c); return *this; }
03207 
03212 string string::operator -(const char* str) { return this->prep(str); }
03213 
03218 string string::operator -(char c) { return this->prep(c); }
03219 
03224 string& string::operator -=(const char* str) { *this = this->prep(str); return *this; }
03225 
03230 string& string::operator -=(char c) { *this = this->prep(c); return *this; }
03231 
03236 bool string::operator ==(const char* str) { if (!buf) return false; return !strcmp(buf, str); }
03237 
03242 bool string::operator ==(char c) { if (!buf) return false; if (buf[0] == c && buf[1] == 0) return true; return false; }
03243 
03248 bool string::operator !=(const char* str) { if (!buf) return true; return strcmp(buf, str); }
03249 
03254 bool string::operator != (char c) { if (!buf) return true; if (buf[0] != c) return true; return false; }
03255 
03260 char& string::operator [](int i) { realloc(i + 1); return this->buf[i]; }
03261 
03266 string string::operator *(int i) {
03267         string s(strlen(buf) * i + 1);
03268         strcpy(s.buf, buf);
03269         for (i--; i > 0; i--)
03270                 strcat(s.buf, buf);
03271         return s;
03272 }
03273 
03278 string& string::operator *=(int i) {
03279         *this = this->operator*(i);
03280         return *this;
03281 }
03282 
03286 string string::operator ()() { return this->qx(); }
03287 
03291 string& string::operator ++() { *this = this->incn(); return *this; }
03292 
03296 string string::operator ++(int foo) { string s(buf); *this = this->incn(); return s; }
03297 
03301 string& string::operator --() { *this = this->decn(); return *this; }
03302 
03306 string string::operator --(int foo) { string s(buf); *this = this->decn(); return s; }
03307 
03308 //io::output& operator<< (io::output& o, string s) { o.operator<<(s.buf); return o; }
03309 //io::input& operator>> (io::input& o, string& s) { o.operator>>(s.buf); return o; }
03310 
03311 io::input& io::input::operator>> (string& s) { return operator>>(s.buf); }
03312 
03316 int string::cmpstr(const char* s, ...) {
03317         va_list v;
03318         va_start(v, s);
03319         const char* c;
03320         int i = 0;
03321         for (c = s; c != NULL; c = va_arg(v, const char*), i++)
03322                 if (!strcmp(buf, c)) break;
03323         va_end(v);
03324         if (c == NULL) return -1;
03325         return i;
03326 }
03327 
03331 int string::cmpinstr(const char* s, ...) {
03332         va_list v;
03333         va_start(v, s);
03334         const char* c;
03335         int i = 0;
03336         for (c = s; c != NULL; c = va_arg(v, const char*), i++)
03337                 if (strstr(buf, c)) break;
03338         va_end(v);
03339         if (c == NULL) return -1;
03340         return i;
03341 }
03342 
03346 int string::cmpleft(const char* s, ...) {
03347         va_list v;
03348         va_start(v, s);
03349         register const char* c;
03350         int i = 0;
03351         for (c = s; c != NULL; c = va_arg(v, const char*), i++)
03352                 if (!strncmp(buf, c, strlen(c))) break;
03353         va_end(v);
03354         if (c == NULL) return -1;
03355         return i;
03356 }
03357 
03361 int string::cmpright(const char* s, ...) {
03362         va_list v;
03363         va_start(v, s);
03364         const char* c;
03365         register size_t k = strlen(buf);
03366         int i = 0;
03367         for (c = s; c != NULL; c = va_arg(v, const char*), i++)
03368                 if (!strncmp(buf + k - strlen(c), c, strlen(c))) break;
03369         va_end(v);
03370         if (c == NULL) return -1;
03371         return i;
03372 }
03373 
03374 int fs::file::putc(int c) {
03375         register int i = fputc(c, fd);
03376         if (i == EOF) {
03377                 errnum = errno;
03378                 if (feof(fd)) drain(); 
03379                 else if (ferror(fd)) kill();
03380                 return EOF;
03381         } else { heal(); return i; }
03382 }
03383 
03384 int fs::file::getc() {
03385         register int i = fgetc(fd);
03386         if (i == EOF) {
03387                 errnum = errno;
03388                 if (feof(fd)) drain();
03389                 else if (ferror(fd)) kill();
03390                 else hurt();
03391                 return EOF;
03392         } else { heal(); return i; }
03393 }
03394 
03395 /*string fs::file::gets(int size) {
03396         string s;
03397         int i = 32, j = 0;
03398         register int c;
03399         s.realloc(i);
03400         for (c = getc(); ; c = getc(), j++) {
03401                 if (size) if (j >= size) break;
03402                 if (j >= i - 4) { i *= 2; s.realloc(i); }
03403                 switch (c) {
03404                 case EOF: s.buf[0] = 0; return s;
03405                 case '\n': s.buf[j] = '\n'; s.buf[++j] = 0; return s;
03406                 default: s.buf[j] = c;
03407                 }
03408         }
03409         s.buf[j] = 0;
03410         return s;
03411 }*/
03412 
03435 FILE* fs::file::open(const char* fname, const char* mode) {
03436         filename = fname;
03437         if ((fd = fopen(fname, mode)) == NULL) {
03438                 errnum = errno;
03439                 kill();
03440         } else heal();
03441         return fd;
03442 }
03443 
03456 FILE* fs::file::dopen(int fh, const char* mode) {
03457         filename.clear();
03458         filename.printf("%ld", fd);
03459         if ((fd = fdopen(fh, mode)) == NULL) {
03460                 errnum = errno;
03461                 kill();
03462         } else heal();
03463         return fd;
03464 }
03465 
03475 FILE* fs::file::reopen(const char* fname, const char* mode) {
03476         filename = fname;
03477         if (freopen(fname, mode, fd) == NULL) {
03478                 errnum = errno;
03479                 kill();
03480                 return NULL;
03481         }
03482         heal();
03483         return fd;
03484 }
03485 
03491 bool fs::file::close() {
03492         if (fclose(fd) == EOF) {
03493                 errnum = errno;
03494                 kill();
03495                 return false;
03496         } else return true;
03497         drain();
03498 }
03499 
03507 bool fs::file::flush() {
03508         if (fflush(fd) == EOF) {
03509                 errnum = errno;
03510                 kill();
03511                 return false;
03512         } else { heal(); return true; }
03513 }
03514 
03529 bool fs::file::seek(long offset, int whence) {
03530 
03531         if (!fseek(fd, offset, whence)) {
03532                 heal();
03533                 return true;
03534         } else {
03535                 errnum = errno;
03536                 hit();
03537                 return false;
03538         }
03539 }
03540 
03546 long fs::file::tell() {
03547         register long i = ftell(fd);
03548         if (i == -1) {
03549                 errnum = errno;
03550                 hit();
03551                 return -1;
03552         } else {
03553                 heal();
03554                 return i;
03555         }
03556 }
03557 
03563 bool fs::file::rewind() { return seek(0L, SEEK_SET); }
03564 
03570 bool fs::file::unwind() { return seek(0L, SEEK_END); }
03571 
03578 bool fs::file::ffwd(long offset) { return seek(offset, SEEK_CUR); }
03579 
03585 bool fs::file::prev(long offset) { return seek(offset * -1, SEEK_CUR); }
03586 
03593 bool fs::file::nobuf() {
03594         if (!setvbuf(fd, NULL, _IONBF, 0)) {
03595                 heal(); return true;
03596         } else { errnum = errno; hit(); return false; }
03597 }
03598 
03606 bool fs::file::lbuf() {
03607         if (!setvbuf(fd, (char*)NULL, _IOLBF, 0)) {
03608                 heal(); return true;
03609         } else { errnum = errno; hit(); return false; }
03610 }
03611 
03622 bool fs::file::fbuf(char* buf, size_t size) {
03623         if (!setvbuf(fd, buf, _IOFBF, size)) {
03624                 heal(); return true;
03625         } else { errnum = errno; hit(); return false; }
03626 }
03627 
03636 int fs::file::ungetc(int c) {
03637         register int i = ::ungetc(c, fd);
03638         if (i == EOF) { hit(); return EOF; }
03639         else { errnum = errno; heal(); return i; }
03640 }
03641 
03643 fs::file::file(const char* name, const char* mode) { open(name, mode); }
03645 fs::file::file(FILE* f) { fd = f; }
03647 fs::file::file(int fh, const char* mode) { dopen(fh, mode); }
03648 
03649 int net::socket::tcp::putc(int c) {
03650         char t = c;
03651         switch (::send(fd, &t, 1, 0)) {
03652         case 0: errnum = errno; hurt(); return EOF;
03653         case -1: errnum = errno; kill(); return EOF;
03654         default: heal(); return c;
03655         }
03656 }
03657 
03658 int net::socket::tcp::getc() {
03659         int a;
03660         char c;
03661         switch (::recv(fd, &c, 1, 0)) {
03662         case 0: errnum = errno; drain();  return EOF;
03663 #ifdef _WIN32
03664         case SOCKET_ERROR: errnum = errno; kill(); return EOF;
03665 #else
03666         case -1: errnum = errno; kill(); return EOF;
03667 #endif
03668         default: heal(); a = c; return a;
03669         }
03670 }
03671 
03681 string io::input::gets(int size) {
03682         string s;
03683         int i;
03684         register int c;
03685         for (i = 0; ; i++) {
03686                 if (size) if (i >= size) return s;
03687                 c = getc();
03688                 switch (c) {
03689                         case EOF: return s;
03690                         case '\n': s += '\n'; return s;
03691                         default:  s += c;
03692                 }
03693         }
03694         return s;
03695 }
03696 
03697 /*string net::socket::tcp::gets(int size) {
03698         string s;
03699         int i;
03700         register int c;
03701         for (i = 0; ; i++) {
03702                 if (size) if (i >= size) break;
03703                 c = getc();     
03704                 switch (c) {
03705                         case EOF: return s;
03706                         case '\n': s += '\n'; return s;
03707                         default: s += c;
03708                 }
03709         }
03710         return s;
03711 }*/
03712 /*string net::socket::tcp::gets(int size) {
03713         string s;
03714         int i = 32, j = 0;
03715         register int c;
03716         s.realloc(i);
03717         for (c = getc(); ; c = getc(), j++) {
03718                 if (size) if (j >= size) break;
03719                 if (j >= i - 4) { i *= 2; s.realloc(i); }
03720                 switch (c) {
03721                 case EOF: s.buf[0] = 0; return s;
03722                 case '\n': s.buf[j] = '\n'; s.buf[++j] = 0; return s;
03723                 default: s.buf[j] = c;
03724                 }
03725         }
03726         s.buf[j] = 0;
03727         return s;
03728 }*/
03729 
03735 int net::socket::tcp::send(const char* buf, size_t len) {
03736         register int i = ::send(fd, buf, len, 0);
03737         if (i == -1) { errnum = errno; kill(); return EOF; }
03738         else if (i == 0) { errnum = errno; hurt(); return EOF; }
03739         else { heal(); return i; }
03740 }
03741 
03751 int net::socket::tcp::recv(char* buf, size_t len) {
03752         register int i = ::recv(fd, buf, len, 0);
03753         if (i == -1) { errnum = errno; kill(); return EOF; }
03754         else if (i == 0) { errnum = errno; drain(); return EOF; }
03755         else { heal(); return i; }
03756 }
03757 
03763 bool net::socket::tcp::connect(const char* host, const char* port) {
03764         struct addrinfo hints, *ai;
03765         memset(&hints, 0, sizeof(struct addrinfo));
03766         hints.ai_protocol = IPPROTO_TCP;
03767         hints.ai_socktype = SOCK_STREAM;
03768         hints.ai_family = AF_UNSPEC;
03769         if (getaddrinfo(host, port, &hints, &ai)) {
03770 #ifndef _WIN32
03771                 errnum = errno;
03772 #else
03773                 errnum = wsatoerr(WSAGetLastError());
03774 #endif
03775                 kill();
03776                 return false;
03777         }
03778         if (ai->ai_family != af) {
03779                 bool b = blocking();
03780                 fd = ::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
03781 #ifdef _WIN32
03782                 if (fd == INVALID_SOCKET) {
03783                         errnum = wsatoerr(WSAGetLastError());
03784 #else
03785                 if (fd == -1) {
03786                         errnum = errno;
03787 #endif
03788                         kill();
03789                         return false;
03790                 }
03791                 blocking(b);
03792                 af = ai->ai_family;
03793         }
03794         if (::connect(fd, ai->ai_addr, ai->ai_addrlen)) {
03795 #ifndef _WIN32
03796                 errnum = errno;
03797 #else
03798                 errnum = wsatoerr(WSAGetLastError());
03799 #endif
03800                 kill();
03801                 return false;
03802         }
03803         heal();
03804         freeaddrinfo(ai);
03805         return true;
03806 }
03807 
03813 bool net::socket::tcp::listen(const char* port, int backlog) {
03814         struct addrinfo hints, *ai;
03815         memset(&hints, 0, sizeof(struct addrinfo));
03816         hints.ai_family = AF_UNSPEC;
03817         hints.ai_socktype = SOCK_STREAM;
03818         hints.ai_protocol = IPPROTO_TCP;
03819         hints.ai_flags = AI_PASSIVE;
03820         if (getaddrinfo(0, port, &hints, &ai)) {
03821 #ifndef _WIN32
03822                 errnum = errno;
03823 #else
03824                 errnum = wsatoerr(WSAGetLastError());
03825 #endif
03826                 kill();
03827                 return false;
03828         }
03829         if (ai->ai_family != af) {
03830                 bool b = blocking();
03831                 fd = ::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
03832 #ifdef _WIN32
03833                 if (fd == INVALID_SOCKET) {
03834                         errnum = wsatoerr(WSAGetLastError());
03835 #else
03836                 if (fd == -1) {
03837                         errnum = errno;
03838 #endif
03839                         kill();
03840                         return false;
03841                 }
03842                 blocking(b);
03843                 af = ai->ai_family;
03844         }
03845         if (bind(fd, ai->ai_addr, ai->ai_addrlen)) {
03846 #ifndef _WIN32
03847                 errnum = errno; 
03848 #else
03849                 errnum = wsatoerr(WSAGetLastError());
03850 #endif
03851                 freeaddrinfo(ai); return false;
03852         }
03853         freeaddrinfo(ai);
03854         if (::listen(fd, backlog) == -1) {
03855 #ifndef _WIN32
03856                 errnum = errno;
03857 #else
03858                 errnum = wsatoerr(WSAGetLastError());
03859 #endif
03860                 kill();
03861                 return false;
03862         }
03863         heal();
03864         return true;
03865 }
03866 
03867 
03878 bool net::socket::tcp::accept(net::socket::tcp& f) {
03879         if ((f.fd = ::accept(fd, NULL, NULL)) == -1) {
03880 #ifndef _WIN32
03881                 errnum = errno; 
03882 #else
03883                 errnum = wsatoerr(WSAGetLastError());
03884 #endif
03885                 hurt();
03886                 return false;
03887         } else return true;
03888 }
03889 
03890 string::string(const data& s) {
03891         fmt.bin(0);
03892         buf = 0; pos = 0; mlen = s.len();
03893         if (s.buf) {
03894                 buf = (char*)malloc(mlen);
03895                 strcpy(buf, s.buf);
03896         }
03897 }
03898 
03899 string& string::operator= (const data& d) {
03900         return this->operator= (d.buf);
03901 }
03902 
03903 data net::http::download(const char* url, const char* port) {
03904         data d;
03905         net::socket::tcp sock;
03906         string s = url;
03907         s = s.munch("http://");
03908         unless (sock.connect(s.burn('/'), port)) return d;
03909         sock << "GET /" << s.slurp('/') << " HTTP/1.1\r\nHost: " << s.burn('/') << "\r\n\r\n";
03910         s = sock.drink("\r\n\r\n");
03911         unless (s.slurp("Content-Length: ").burn('\r').empty())
03912                 d = sock.read(1, stoi<size_t>(s.slurp("Content-Length: ").burn('\r')));
03913         else d = sock.dump();
03914         sock.close();
03915         return d;
03916 }
03917 
03921 bool net::socket::tcp::close() {
03922         drain();
03923 #ifdef _WIN32
03924         if (!closesocket(fd))
03925                 { tcp(); return true; }
03926         else { errnum = wsatoerr(WSAGetLastError()); tcp();return false; }
03927 #else
03928         if (::close(fd) == -1) {
03929                 errnum = errno; 
03930                 tcp();
03931                 return false;
03932         } else { tcp();return true;}
03933 #endif
03934 }
03935 
03943 bool net::socket::tcp::blocking(int i) {
03944 #ifndef _WIN32
03945         if (i == -1)
03946                 return fcntl(fd, F_GETFD) & O_NONBLOCK;
03947         else if (i == 0)
03948                 return !fcntl(fd, fcntl(fd, F_GETFD) | O_NONBLOCK);
03949         else if (i)
03950                 return !fcntl(fd, fcntl(fd, F_GETFD) & ~O_NONBLOCK);
03951 #else
03952         unsigned long t;
03953         if (i == -1) return blking;
03954         else if (i == 1) {
03955                 t = 1;
03956                 return !ioctlsocket(fd, FIONBIO, &t);
03957         } else if (i == 0) {
03958                 t = 0;
03959                 return !ioctlsocket(fd, FIONBIO, &t);
03960         }
03961 #endif
03962         return true;
03963 }
03964 
03965 net::socket::tcp::tcp() {
03966 #ifdef _WIN32
03967         struct WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData));
03968         int i;
03969         if (i = WSAStartup(MAKEWORD(2, 0), wd)) {
03970                 errnum = wsatoerr(i);
03971                 kill();
03972                 free(wd);
03973                 return;
03974         }
03975         free(wd);
03976         blking = true;
03977 #endif
03978         af = AF_INET;
03979         fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
03980 #ifdef _WIN32
03981         if (fd == INVALID_SOCKET) {
03982                 errnum = wsatoerr(WSAGetLastError());
03983                 kill();
03984                 return;
03985         }
03986 #else
03987         if (fd == -1) { errnum = errno; kill(); return; }
03988 #endif
03989         
03990         drain();
03991 }
03992 #ifdef _WIN32
03993 net::socket::tcp::~tcp() {
03994                 WSACleanup();
03995 }
03996 #endif
03997 
04001 bool net::socket::tcp::connected() { return !ip().empty(); }
04002 
04006 string net::socket::tcp::ip() {
04007         string s;
04008 #ifdef _WIN32
04009         DWORD d = 40;
04010 #endif
04011         s.realloc(40);
04012         s.clear();
04013         struct sockaddr_storage ss;
04014         socklen_t sslen = sizeof(struct sockaddr_storage);
04015         if (::getpeername(this->fd, (struct sockaddr*)&ss, &sslen)) return s;
04016         if (ss.ss_family == AF_INET)
04017 #ifndef _WIN32
04018                 inet_ntop(ss.ss_family, &((struct sockaddr_in*)&ss)->sin_addr, s.buf, 40);
04019 #else
04020                 WSAAddressToStringA((struct sockaddr*)&ss, sizeof(struct sockaddr_storage), 0, s.buf, &d);
04021 #endif
04022         else if (ss.ss_family == AF_INET6)
04023 #ifndef _WIN32
04024                 inet_ntop(ss.ss_family, &((struct sockaddr_in6*)&ss)->sin6_addr, s.buf, 40);
04025 #else
04026                 WSAAddressToStringA((struct sockaddr*)&ss, sizeof(struct sockaddr_storage), 0, s.buf, &d);
04027 #endif
04028         return s;
04029 }
04030 
04034 string net::socket::tcp::name() {
04035         string s;
04036         s.realloc(256);
04037         s.clear();
04038         struct sockaddr sa;
04039         socklen_t slen = sizeof(struct sockaddr);
04040         ::getpeername(this->fd, &sa, &slen);
04041         getnameinfo(&sa, slen, s.buf, 256, 0, 0, 0);
04042         return s;
04043 }
04044 
04045 string object::type() { return string("object"); }
04046 object::operator string () { return string("(null)"); }
04047 
04048 string net::ipaddr::type() { return string("net::ipaddr"); }
04049 net::ipaddr::operator string () {
04050         string s(42);
04051 #ifndef _WIN32
04052         inet_ntop(this->af, &(this->addr4), s.buf, 42);
04053 #else
04054         DWORD d = 42;
04055         struct sockaddr_in si;
04056         struct sockaddr_in6 sj;
04057         memset(&si, 0, sizeof(struct sockaddr_in));
04058         memset(&sj, 0, sizeof(struct sockaddr_in6));
04059         if (af == AF_INET) {
04060                 si.sin_family = AF_INET;
04061                 memmove(&(si.sin_addr), &(this->addr4), sizeof(struct in_addr));
04062                 WSAAddressToStringA(
04063                         (struct sockaddr*)&si,
04064                         sizeof(struct sockaddr_in),
04065                         NULL,
04066                         s.buf,
04067                         &d
04068                 );
04069         } else if (af == AF_INET6) {
04070                 sj.sin6_family = AF_INET6;
04071                 sj.sin6_port = 0;
04072                 memmove(&(sj.sin6_addr), &(this->addr6), sizeof(struct in6_addr));
04073                 WSAAddressToStringA(
04074                         (struct sockaddr*)&sj,
04075                         sizeof(struct sockaddr_in6),
04076                         NULL,
04077                         s.buf,
04078                         &d
04079                 );
04080         }
04081                         
04082 #endif
04083         return s;
04084 }
04085 #ifdef _WIN32
04086 void net::ipaddr::initwsa() {
04087         WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData));
04088         WSAStartup(MAKEWORD(2, 0), wd);
04089         free(wd);
04090 }
04091 #endif
04092 net::ipaddr::ipaddr(const char* s) {
04093 #ifdef _WIN32
04094         initwsa();
04095 #endif
04096         this->operator=(s); }
04097 net::ipaddr::ipaddr(struct in_addr* s) {
04098 #ifdef _WIN32
04099         initwsa();
04100 #endif
04101 this->operator=(s); }
04102 net::ipaddr::ipaddr(struct in6_addr* s) {
04103 #ifdef _WIN32
04104         initwsa();
04105 #endif
04106 this->operator=(s); }
04107 
04108 bool net::ipaddr::cmp(const char* s, struct in_addr * ia4, struct in6_addr * ia6, int op) {
04109         net::ipaddr ip;
04110         register size_t t;
04111         if (s) ip = s;
04112         else if (ia4) ip = ia4;
04113         else if (ia6) ip = ia6;
04114         if (af == AF_INET) t = sizeof(struct in_addr);
04115         else if (af == AF_INET6) t = sizeof(struct in6_addr);
04116         if (ip.af != af) return false;
04117         switch (op) {
04118         case 0: /* == */
04119                 return !memcmp(&addr4, &(ip.addr4), t);
04120         case 1: /* != */
04121                 return memcmp(&addr4, &(ip.addr4), t);
04122         case 2: /* > */
04123                 return memcmp(&addr4, &(ip.addr4), t) > 0;
04124         case 3: /* >= */
04125                 return memcmp(&addr4, &(ip.addr4), t) >= 0;
04126         case 4: /* < */
04127                 return memcmp(&addr4, &(ip.addr4), t) < 0;
04128         case 5: /* <= */
04129                 return memcmp(&addr4, &(ip.addr4), t) <= 0;
04130         }
04131         return false;
04132 }
04133 
04134 bool net::ipaddr::operator== (const char* s) { return this->cmp(s, 0, 0, 0); }
04135 bool net::ipaddr::operator!= (const char* s) { return this->cmp(s, 0, 0, 1); }
04136 bool net::ipaddr::operator> (const char* s) { return this->cmp(s, 0, 0, 2); }
04137 bool net::ipaddr::operator>= (const char* s) { return this->cmp(s, 0, 0, 3); }
04138 bool net::ipaddr::operator< (const char* s) { return this->cmp(s, 0, 0, 4); }
04139 bool net::ipaddr::operator<= (const char* s) { return this->cmp(s, 0, 0, 5); }
04140 bool net::ipaddr::operator== (struct in_addr * s) { return this->cmp(0, s, 0, 0); }
04141 bool net::ipaddr::operator!= (struct in_addr * s) { return this->cmp(0, s, 0, 1); }
04142 bool net::ipaddr::operator> (struct in_addr * s) { return this->cmp(0, s, 0, 2); }
04143 bool net::ipaddr::operator>= (struct in_addr * s) { return this->cmp(0, s, 0, 3); }
04144 bool net::ipaddr::operator< (struct in_addr * s) { return this->cmp(0, s, 0, 4); }
04145 bool net::ipaddr::operator<= (struct in_addr * s) { return this->cmp(0, s, 0, 5); }
04146 bool net::ipaddr::operator== (struct in6_addr * s) { return this->cmp(0, 0, s, 0); }
04147 bool net::ipaddr::operator!= (struct in6_addr * s) { return this->cmp(0, 0, s, 1); }
04148 bool net::ipaddr::operator> (struct in6_addr * s) { return this->cmp(0, 0, s, 2); }
04149 bool net::ipaddr::operator>= (struct in6_addr * s) { return this->cmp(0, 0, s, 3); }
04150 bool net::ipaddr::operator< (struct in6_addr * s) { return this->cmp(0, 0, s, 4); }
04151 bool net::ipaddr::operator<= (struct in6_addr * s) { return this->cmp(0, 0, s, 5); }
04152 
04159 net::ipaddr& net::ipaddr::operator= (const char* s) {
04160         int f;
04161         string t = s;
04162         union { struct in_addr ia; struct in6_addr ia6; } a;
04163         if (t.chr(':') > -1) f = AF_INET6;
04164         else if (t.isctype(".0123456789")) f = AF_INET;
04165         else {
04166                 struct addrinfo *ai;
04167                 if (getaddrinfo(s, 0, 0, &ai)) return *this;
04168                 af = ai->ai_family;
04169                 if (af == AF_INET)
04170                         memmove(&addr4, &((struct sockaddr_in*)ai->ai_addr)->sin_addr, sizeof(struct sockaddr));
04171                 else if (af == AF_INET6)
04172                         memmove(&addr6, &((struct sockaddr_in6*)ai->ai_addr)->sin6_addr, sizeof(struct sockaddr));
04173                 freeaddrinfo(ai);
04174                 return *this;
04175         }
04176 #ifndef _WIN32
04177         if (inet_pton(f, s, &a) < 1) return *this;
04178 #else
04179         DWORD d = 42;
04180         int z = 42, foobar;
04181         char* crap = (char*)malloc(strlen(s) + 1);
04182         strcpy(crap, s);
04183         struct sockaddr_in sa4;
04184         struct sockaddr_in6 sa6;
04185         sa4.sin_family = AF_INET;
04186         sa6.sin6_family = AF_INET6;
04187         if (f == AF_INET) {
04188                 foobar = sizeof(struct sockaddr_in);
04189                 z = WSAStringToAddressA(
04190                         crap,
04191                         f,
04192                         NULL,
04193                         (struct sockaddr*)&sa4,
04194                         &foobar
04195                 );
04196                 memmove(&(a.ia), &(sa4.sin_addr), sizeof(struct in_addr));
04197         } else if (f == AF_INET6) {
04198                 foobar = sizeof(struct sockaddr_in6);
04199                 z = WSAStringToAddressA(
04200                         crap,
04201                         f,
04202                         NULL,
04203                         (struct sockaddr*)&sa6,
04204                         &foobar
04205                 );
04206                 memmove(&(a.ia6), &(sa6.sin6_addr), sizeof(struct in6_addr));
04207         }
04208         free(crap);
04209         if (z) return *this;
04210 #endif
04211         af = f;
04212         if (f == AF_INET) this->operator=(&(a.ia));
04213         else if (f == AF_INET6) this->operator=(&(a.ia6));
04214         return *this;
04215 }
04216 net::ipaddr& net::ipaddr::operator=(struct in_addr* s) {
04217         af = AF_INET;
04218         memmove(&addr4, s, sizeof(struct in_addr));
04219         return *this;
04220 }
04221 net::ipaddr& net::ipaddr::operator=(struct in6_addr* s) {
04222         af = AF_INET6;
04223         memmove(&addr6, s, sizeof(struct in6_addr));
04224         return *this;
04225 }
04226 
04227 net::ipaddr net::ipaddr::operator+ (int i) {
04228         int m;
04229         if (af == AF_INET) {
04230                 unsigned int j = ntohl(this->addr4.s_addr);
04231                 unsigned char* k = (unsigned char*)&j;
04232                 struct in_addr ia;
04233                 for (m = 0; m < i; m++) {
04234                         k[0]++;
04235                         if (k[0] == 0) {
04236                                 k[1]++;
04237                                 if (k[1] == 0) {
04238                                         k[2]++;
04239                                         if (k[2] == 0) {
04240                                                 k[3]++;
04241                                         }
04242                                 }
04243                         }
04244                 }
04245                 ia.s_addr = htonl(j);
04246                 return net::ipaddr(&ia);
04247         } else if (af == AF_INET6) {
04248                 struct in6_addr ia;
04249                 memmove(&ia, &addr6, sizeof(struct in6_addr));
04250                 unsigned short* us = (unsigned short*)&(ia.s6_addr);
04251                 int j;
04252                 /* --------------- LIKE A BOSS --------------- */
04253                 for (j = 0; j < i; j++) {
04254                         us[7] = htons(ntohs(us[7]) + 1);
04255                         if (!ntohs(us[7])) {
04256                                 us[6] = htons(ntohs(us[6]) + 1);
04257                                 if (!ntohs(us[6])) {
04258                                         us[5] = htons(ntohs(us[6]) + 1);
04259                                         if (!ntohs(us[5])) {
04260                                                 us[4] = htons(ntohs(us[4]) + 1);
04261                                                 if (!ntohs(us[4])) {
04262                                                         us[3] = htons(ntohs(us[3]) + 1);
04263                                                         if (!ntohs(us[3])) {
04264                                                                 us[2] = htons(ntohs(us[2]) + 1);
04265                                                                 if (!ntohs(us[2])) {
04266                                                                         us[1] = htons(ntohs(us[1]) + 1);
04267                                                                         if (!ntohs(us[1])) {
04268                                                                                 us[0] = htons(ntohs(us[0]) + 1);
04269                                                                         }
04270                                                                 }
04271                                                         }
04272                                                 }
04273                                         }
04274                                 }
04275                         }
04276                 }
04277                 return net::ipaddr(&ia);
04278         }
04279 }
04280 net::ipaddr net::ipaddr::operator- (int i) {
04281         int m;
04282         if (af == AF_INET) {
04283                 unsigned int j = ntohl(this->addr4.s_addr);
04284                 unsigned char* k = (unsigned char*)&j;
04285                 struct in_addr ia;
04286                 for (m = 0; m < i; m++) {
04287                         k[0]--;
04288                         if (k[0] == 0xff) {
04289                                 k[1]--;
04290                                 if (k[1] == 0xff) {
04291                                         k[2]--;
04292                                         if (k[2] == 0xff) {
04293                                                 k[3]--;
04294                                         }
04295                                 }
04296                         }
04297                 }
04298                 ia.s_addr = htonl(j);
04299                 return net::ipaddr(&ia);
04300         } else if (af == AF_INET6) {
04301                 struct in6_addr ia;
04302                 memmove(&ia, &addr6, sizeof(struct in6_addr));
04303                 unsigned short* us = (unsigned short*)&(ia.s6_addr);
04304                 int j;
04305                 /* --------------- LIKE A BOSS --------------- */
04306                 for (j = 0; j < i; j++) {
04307                         us[7] = htons(ntohs(us[7]) - 1);
04308                         if (ntohs(us[7]) == 0xffff) {
04309                                 us[6] = htons(ntohs(us[6]) - 1);
04310                                 if (ntohs(us[6]) == 0xffff) {
04311                                         us[5] = htons(ntohs(us[5]) - 1);
04312                                         if (ntohs(us[5]) == 0xffff) {
04313                                                 us[4] = htons(ntohs(us[4]) - 1);
04314                                                 if (ntohs(us[4]) == 0xffff) {
04315                                                         us[3] = htons(ntohs(us[3]) - 1);
04316                                                         if (ntohs(us[3]) == 0xffff) {
04317                                                                 us[2] = htons(ntohs(us[2]) - 1);
04318                                                                 if (ntohs(us[2]) == 0xffff) {
04319                                                                         us[1] = htons(ntohs(us[1]) - 1);
04320                                                                         if (ntohs(us[1]) == 0xffff) {
04321                                                                                 us[0] = htons(ntohs(us[0]) - 1);
04322                                                                         }
04323                                                                 }
04324                                                         }
04325                                                 }
04326                                         }
04327                                 }
04328                         }
04329                 }
04330                 return net::ipaddr(&ia);
04331         }
04332 }
04333 net::ipaddr& net::ipaddr::operator+= (int i) { *this = this->operator+(i); return *this; }
04334 net::ipaddr& net::ipaddr::operator-= (int i) { *this = this->operator-(i); return *this; }
04335 net::ipaddr& net::ipaddr::operator++ () { *this = this->operator+(1); return *this; }
04336 net::ipaddr net::ipaddr::operator++ (int foo) { net::ipaddr i = *this; *this = this->operator+(1); return i; }
04337 net::ipaddr& net::ipaddr::operator-- () { *this = this->operator-(1); return *this; }
04338 net::ipaddr net::ipaddr::operator-- (int foo) { net::ipaddr i = *this; *this = this->operator-(1); return i; }
04339 
04340 
04349 bool net::socket::udp::bind(const char* port) {
04350         struct addrinfo hints, *ai;
04351         memset(&hints, 0, sizeof(struct addrinfo));
04352         hints.ai_family = AF_INET;
04353         hints.ai_socktype = SOCK_DGRAM;
04354         hints.ai_protocol = IPPROTO_UDP;
04355         hints.ai_flags = AI_PASSIVE;
04356         if (getaddrinfo(0, port, &hints, &ai)) return false;
04357         if (::bind(fd, ai->ai_addr, ai->ai_addrlen)) return false;
04358         freeaddrinfo(ai);
04359         return true;
04360 }
04361 
04367 void net::socket::udp::unbind() {
04368 #ifdef _WIN32
04369         closesocket(fd);
04370 #else
04371         close(fd);
04372 #endif
04373         fd = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
04374 }
04375 
04382 int net::socket::udp::post(net::dgram dg) {
04383         struct sockaddr_in sa;
04384         sa.sin_family = AF_INET;
04385         sa.sin_port = htons(dg.port);
04386         memmove(&(sa.sin_addr), &(dg.ip.addr4), sizeof(struct in_addr));
04387         return ::sendto(fd, dg.msg.buf, dg.msg.len(), 0, (struct sockaddr*)&sa, sizeof(struct sockaddr_in));
04388 }
04389 
04397 net::dgram net::socket::udp::get() {
04398         net::dgram dg;
04399         struct sockaddr_in sa;
04400         socklen_t sl = sizeof(struct sockaddr_in);
04401         until (this->check() > -1);
04402         dg.msg.realloc(this->check() + 1);
04403         ::recvfrom(fd, dg.msg.buf, dg.msg.len(), 0, (struct sockaddr*)&sa, &sl);
04404         dg.ip = &(sa.sin_addr);
04405         dg.port = ntohs(sa.sin_port);
04406         return dg;
04407 }
04408 
04416 /*int net::socket::udp::send(const char* buf, size_t len) {
04417         struct sockaddr_in sa;
04418         sa.sin_family = AF_INET;
04419         sa.sin_port = htons(port);
04420         memmove(&(sa.sin_addr), &(peer.addr4), sizeof(struct in_addr));
04421         return ::sendto(fd, buf, len, 0, (struct sockaddr*)&sa, sizeof(struct sockaddr_in));
04422 }*/
04423 
04431 /*int net::socket::udp::recv(char* buf, size_t len) {
04432         struct sockaddr_in sa;
04433         socklen_t sl = sizeof(struct sockaddr_in);
04434         register int i = ::recvfrom(fd, buf, len, 0, (struct sockaddr*)&sa, &sl);
04435         peer = &(sa.sin_addr);
04436         return i;
04437 }*/
04438 
04439 /*int net::socket::udp::puts(const char* s) {
04440         struct sockaddr_in sa;
04441         sa.sin_family = AF_INET;
04442         sa.sin_port = htons(port);
04443         memmove(&(sa.sin_addr), &(peer.addr4), sizeof(struct in_addr));
04444         register int i = ::sendto(fd, s, strlen(s), 0, (struct sockaddr*)&sa, sizeof(struct sockaddr_in));
04445         switch (i) {
04446         case 0: hurt(); return EOF;
04447         case -1: kill(); return EOF;
04448         default: heal(); return i;
04449         }
04450 }*/
04451 
04452 int net::socket::tcp::puts(const char* s) {
04453         register int i = ::send(fd, s, strlen(s), 0);
04454         switch (i) {
04455         case 0: hurt(); return EOF;
04456         case -1: kill(); return EOF;
04457         default: heal(); return i;
04458         }
04459 }
04460 
04461 net::socket::udp::udp() {
04462 #ifdef _WIN32
04463         struct WSAData* wd = (struct WSAData*)malloc(sizeof(struct WSAData));
04464         WSAStartup(MAKEWORD(2, 0), wd);
04465         free(wd);
04466 #endif
04467         fd = ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
04468 }
04469 net::socket::udp::~udp() {
04470 #ifdef _WIN32
04471                 closesocket(fd);
04472                 WSACleanup();
04473 #else
04474                 close(fd);
04475 #endif
04476 }
04477 
04478 bool net::socket::tcp::ready() {
04479         fd_set rfd;
04480 #ifndef _WIN32
04481         struct timeval tv = {0, 0};
04482 #else
04483         TIMEVAL tv = {0, 0};
04484 #endif
04485         FD_ZERO(&rfd);
04486         FD_SET(fd, &rfd);
04487         select(fd + 1, &rfd, 0, 0, &tv);
04488         return FD_ISSET(fd, &rfd);
04489 }
04490 
04494 int net::socket::udp::check() {
04495         int i = -1;
04496 #ifndef _WIN32
04497         ioctl(fd, FIONREAD, &i);
04498 #else
04499         ioctlsocket(fd, FIONREAD, (unsigned long*)&i);
04500 #endif
04501         if (i == 0) {
04502 #ifndef _WIN32
04503                 struct pollfd pf;
04504                 pf.fd = fd;
04505                 pf.events = POLLIN;
04506                 pf.revents = 0;
04507                 poll(&pf, 1, 0);
04508                 if (pf.revents & POLLIN) return 0;
04509                 else return -1;
04510 #else
04511                 fd_set pf;
04512                 pf.fd_count = 1;
04513                 pf.fd_array[0] = fd;
04514                 TIMEVAL tv = {0, 0};
04515                 select(0, &pf, 0, 0, &tv); 
04516                 if (FD_ISSET(fd, &pf)) return 0;
04517                 else return -1;
04518 #endif
04519         } else return i;
04520 }
04521 
04522 string net::socket::udp::type() { return string("net::socket::udp"); }
04523 net::socket::udp::operator string () { string s; s << fd; return s;}
04524 
04526 //net::socket::udp& net::socket::udp::to(const char* ip) { peer = ip; return *this; }
04528 //net::socket::udp& net::socket::udp::on(unsigned short p) { p = htons(p); return *this; }
04529 
04530 /*net::socket::udp& net::socket::udp::operator= (const char* endpoint) {
04531         string s = endpoint;
04532         if (s[0] != '*')
04533                 peer = s.burn('/');
04534         if (!s.ends('*')) port = atoi(s.slurp('/'));
04535         return *this;
04536 }*/
04537 
04538 /*int net::socket::udp::getc() {
04539         int a;
04540         char c;
04541         struct sockaddr_in sa;
04542         socklen_t sl = sizeof(struct sockaddr_in);
04543         switch (::recvfrom(fd, &c, 1, 0, (struct sockaddr*)&sa, &sl)) {
04544         case 0: drain();  a = EOF; break;
04545 #ifdef _WIN32
04546         case SOCKET_ERROR: a = EOF; break;
04547 #else
04548         case -1: kill(); a = EOF; break;
04549 #endif
04550         default: heal(); a = c; break;
04551         }
04552         peer = &(sa.sin_addr);
04553         return a;
04554 }
04555 
04556 int net::socket::udp::putc(int c) {
04557         register char d = c;
04558         struct sockaddr_in sa;
04559         sa.sin_family = AF_INET;
04560         sa.sin_port = htons(port);
04561         memmove(&(sa.sin_addr), &(peer.addr4), sizeof(struct in_addr));
04562         switch (::sendto(fd, &d, 1, 0, (struct sockaddr*)&sa, sizeof(struct sockaddr_in))) {
04563         case 0: hurt(); return EOF;
04564         case -1: kill(); return EOF;
04565         default: heal(); return c;
04566         }
04567 }*/
04568 
04569 int console::putc(int c) {
04570         register int i = fputc(c, out);
04571         if (i == EOF) {
04572                 if (feof(out)) drain();
04573                 else if (ferror(out)) kill();
04574                 return EOF;
04575         } else { heal(); return i; }
04576 }
04577 
04578 int console::getc() {
04579         register int i = fgetc(in);
04580         if (i == EOF) {
04581                 if (feof(in)) drain();
04582                 else if (ferror(in)) kill();
04583                 return EOF;
04584         } else { heal(); return i; }
04585 }
04586 /*string console::gets(int size) {
04587         string s;
04588         int i = 32, j = 0;
04589         register int c;
04590         s.realloc(i);
04591         for (c = getc(); ; c = getc(), j++) {
04592                 if (size) if (j >= size) break;
04593                 if (j >= i - 4) { i *= 2; s.realloc(i); }
04594                 switch (c) {
04595                 case EOF: s.buf[0] = 0; return s;
04596                 case '\n': s.buf[j] = '\n'; s.buf[++j] = 0; return s;
04597                 default: s.buf[j] = c;
04598                 }
04599         }
04600         s.buf[j] = 0;
04601         return s;
04602 }*/
04603 
04620 #ifndef _WIN32
04621 int console::getch() {
04622         int i = ::fileno(in);
04623         struct termios oldt, newt;
04624         int ch;
04625         tcgetattr(i, &oldt);
04626         newt = oldt;
04627         newt.c_lflag &= ~(ICANON | ECHO);
04628         tcsetattr(i, TCSANOW, &newt);
04629         ch = getchar();
04630         tcsetattr(i, TCSANOW, &oldt);
04631         return ch;
04632 }
04633 int console::getche() {
04634         int i = ::fileno(in);
04635         struct termios oldt, newt;
04636         int ch;
04637         tcgetattr(i, &oldt);
04638         newt = oldt;
04639         newt.c_lflag &= ~ICANON;
04640         newt.c_lflag &= ECHO;
04641         tcsetattr(i, TCSANOW, &newt);
04642         ch = getchar();
04643         tcsetattr(i, TCSANOW, &oldt);
04644         return ch;
04645 }
04646 bool console::kbhit() {
04647         int i = ::fileno(in);
04648         struct termios oldt, newt;
04649         struct timeval tv;
04650         fd_set fds;
04651         int ret;
04652         tcgetattr(i, &oldt);
04653         newt = oldt;
04654         newt.c_lflag &= ~(ICANON | ECHO);
04655         tcsetattr(i, TCSANOW, &newt);
04656         tv.tv_sec = 0;
04657         tv.tv_usec = 0;
04658         FD_ZERO(&fds);
04659         FD_SET(i, &fds);
04660         select(i + 1, &fds, 0, 0, &tv);
04661         ret = FD_ISSET(i, &fds);
04662         tcsetattr(i, TCSANOW, &oldt);
04663         return ret;
04664 }
04665 console& console::putcr() { fputc('\r', out); fflush(out); return *this; }
04666 console& console::putbs() { fputc('\b', out); fflush(out); return *this; }
04667 console& console::cls() { fputs("\x1B[2J", out); return *this; }
04668 console& console::bel() { fputc('\a', out); fflush(out); return *this; }
04669 console& console::setxy(int x, int y) { sprintf(s, "\x1B[%d;%df", y, x); fputs(s, out); return *this; }
04670 console& console::setx(int x) { sprintf(s, "\x1B[%dd", x); fputs(s, out); return *this; }
04671 console& console::sety(int y) { sprintf(s, "\x1B%dG", y); fputs(s, out); return *this; }
04672 console& console::up(int n) { sprintf(s, "\x1B[%dA", n); fputs(s, out); return *this; }
04673 console& console::dn(int n) { sprintf(s, "\x1B[%dB", n); fputs(s, out); return *this; }
04674 console& console::rt(int n) { sprintf(s, "\x1B[%dC", n); fputs(s, out); return *this; }
04675 console& console::lt(int n) { sprintf(s, "\x1B[%dD", n); fputs(s, out); return *this; }
04676 console& console::rmln() { fputs("\x1B[1K", out); return *this; }
04677 console& console::fglite() { fputs("\x1B[1m", out); return *this; }
04678 console& console::fgdark() { fputs("\x1B[22m", out); return *this; }
04679 console& console::fgcol(short color) { sprintf(s, "\x1B[%dm", color + 30); fputs(s, out); return *this; }
04680 console& console::bgcol(short color) { sprintf(s, "\x1B[%dm", color + 40); fputs(s, out); return *this; }
04681 #else
04682 HANDLE console::coninfo(HANDLE* h, CONSOLE_SCREEN_BUFFER_INFO* bi) {
04683         if (h != NULL) {
04684                 *h = GetStdHandle(STD_OUTPUT_HANDLE);
04685                 if (bi != NULL) GetConsoleScreenBufferInfo(*h, bi);
04686                 return *h;
04687         }
04688         return NULL;
04689 }
04690 console& console::bel() { MessageBeep(0xffffffff); return *this; }
04691 console& console::setxy(int x, int y) {
04692         HANDLE h;
04693         COORD c;
04694         c.X = x;
04695         c.Y = y;
04696         SetConsoleCursorPosition(coninfo(&h, 0), c);
04697         return *this;
04698 }
04699 console& console::setx(int x) {
04700         HANDLE h;
04701         CONSOLE_SCREEN_BUFFER_INFO bi;
04702         coninfo(&h, &bi);
04703         bi.dwCursorPosition.X = x;
04704         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04705         return *this;
04706 }
04707 console& console::sety(int y) {
04708         HANDLE h;
04709         CONSOLE_SCREEN_BUFFER_INFO bi;
04710         coninfo(&h, &bi);
04711         bi.dwCursorPosition.Y = y;
04712         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04713         return *this;
04714 }
04715 console& console::up(int n) {
04716         HANDLE h;
04717         CONSOLE_SCREEN_BUFFER_INFO bi;
04718         coninfo(&h, &bi);
04719         bi.dwCursorPosition.Y -= n;
04720         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04721         return *this;
04722 }
04723 console& console::dn(int n) {
04724         HANDLE h;
04725         CONSOLE_SCREEN_BUFFER_INFO bi;
04726         coninfo(&h, &bi);
04727         bi.dwCursorPosition.Y += n;
04728         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04729         return *this;
04730 }
04731 console& console::lt(int n) {
04732         HANDLE h;
04733         CONSOLE_SCREEN_BUFFER_INFO bi;
04734         coninfo(&h, &bi);
04735         bi.dwCursorPosition.X -= n;
04736         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04737         return *this;
04738 }
04739 console& console::rt(int n) {
04740         HANDLE h;
04741         CONSOLE_SCREEN_BUFFER_INFO bi;
04742         coninfo(&h, &bi);
04743         bi.dwCursorPosition.X += n;
04744         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04745         return *this;
04746 }
04747 console& console::rmln() {
04748         HANDLE h;
04749         CONSOLE_SCREEN_BUFFER_INFO bi;
04750         COORD c;
04751         coninfo(&h, &bi);
04752         c = bi.dwCursorPosition;
04753         c.X = 0;
04754         FillConsoleOutputCharacterA(h, ' ', bi.dwCursorPosition.X, c, 0);
04755         return *this;
04756 }
04757 console& console::fglite() {
04758         HANDLE h;
04759         CONSOLE_SCREEN_BUFFER_INFO bi;
04760         coninfo(&h, &bi);
04761         bi.wAttributes |= FOREGROUND_INTENSITY;
04762         SetConsoleTextAttribute(h, bi.wAttributes);
04763         return *this;
04764 }
04765 console& console::fgdark() {
04766         HANDLE h;
04767 
04768         CONSOLE_SCREEN_BUFFER_INFO bi;
04769         coninfo(&h, &bi);
04770         bi.wAttributes &= ~FOREGROUND_INTENSITY;
04771 
04772         SetConsoleTextAttribute(h, bi.wAttributes);
04773         return *this;
04774 }
04775 console& console::fgcol(short color) {
04776         HANDLE h;
04777         coninfo(&h, 0);
04778         SetConsoleTextAttribute(h, color);
04779         return *this;
04780 }
04781 console& console::bgcol(short color) {
04782         HANDLE h;
04783         CONSOLE_SCREEN_BUFFER_INFO bi;
04784         coninfo(&h, &bi);
04785         switch (color) {
04786         case color::black:
04787                 bi.wAttributes &= ~(BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_GREEN);
04788                 color = bi.wAttributes;
04789                 break;
04790         case color::blue: color = BACKGROUND_BLUE; break;
04791         case color::green: color = BACKGROUND_GREEN; break;
04792         case color::red: color = BACKGROUND_RED; break;
04793         case color::aqua: color = BACKGROUND_BLUE | BACKGROUND_GREEN; break;
04794         case color::purple: color = BACKGROUND_BLUE | BACKGROUND_RED; break;
04795         case color::yellow: color = BACKGROUND_GREEN | BACKGROUND_RED; break;
04796         case color::white: color = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE; break;
04797         }
04798         SetConsoleTextAttribute(h, color);
04799         return *this;
04800 }
04801 console& console::cls() {
04802         HANDLE h;
04803         coninfo(&h, 0);
04804         COORD ab, xy;
04805         xy = GetLargestConsoleWindowSize(h);
04806         ab.X = 0;
04807         ab.Y = 0;
04808         FillConsoleOutputCharacterA(h, ' ', xy.X * xy.Y, ab, 0);
04809         SetConsoleCursorPosition(h, ab);
04810         return *this;
04811 }
04812 int console::getch() { return _getch(); }
04813 int console::getche() { return _getche(); }
04814 bool console::kbhit() { return _kbhit(); }
04815 console& console::putcr() {
04816         HANDLE h;
04817         CONSOLE_SCREEN_BUFFER_INFO bi;
04818         coninfo(&h, &bi);
04819         bi.dwCursorPosition.X = 0;
04820         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04821         return *this;
04822 }
04823 console& console::putbs() {
04824         HANDLE h;
04825         CONSOLE_SCREEN_BUFFER_INFO bi;
04826         coninfo(&h, &bi);
04827         bi.dwCursorPosition.X -= 1;
04828         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04829         fputc(0, out);
04830         bi.dwCursorPosition.X -= 1;
04831         SetConsoleCursorPosition(h, bi.dwCursorPosition);
04832         return *this;
04833 }
04834 #endif
04835 
04836 console con;
04837 
04838 void die(const char* format, ...) {
04839         va_list v;
04840         va_start(v, format);
04841         vfprintf(stderr, format, v);
04842         exit(1);
04843 }
04844 
04845 unsigned short cksum(const char* buf) {
04846         size_t i;
04847         unsigned short sum = 0;
04848         for (i = 0; buf[i]; i++) {
04849                 sum = (sum >> 1) + ((sum & 1) << 15);
04850                 sum += buf[i];
04851                 sum &= 0xffff;
04852         }
04853         return sum;
04854 }
04855 
04856 int rand(int min, int max) {
04857         srand(time(NULL));
04858         if (min == 0 && max == 0) return ::rand();
04859         return (::rand() % (max - min)) + min;
04860 }
04861 int rands(unsigned int seed, int min, int max) {
04862         srand(seed);
04863         if (min == 0 && max == 0) return ::rand();
04864         return (::rand() % (max - min)) + min;
04865 }
04866 
04867 char* memrev(char* s, size_t size, size_t n) {
04868         char *a = s, *b = s + size * --n, *c = (char*)malloc(size);
04869         for (; a < b; a = a + size, b = b - size) {
04870                 memmove(c, a, size);
04871                 memmove(a, b, size);
04872                 memmove(b, c, size);
04873         }
04874         free(c);
04875         return s;
04876 }
04877 
04878 char* memrol(char* s, size_t size, size_t n) {
04879         size_t i = size * --n;  
04880         char* a = (char*)malloc(size);
04881         memmove(a, s + i, size);
04882         memmove(s + size, s, i);
04883         memmove(s, a, size);
04884         free(a);
04885         return s; 
04886 }
04887 
04888 char* memror(char* s, size_t size, size_t n) {
04889         size_t i = size * --n;
04890         char* a = (char*)malloc(size);
04891         memmove(a, s, size);
04892         memmove(s, s + size, i);
04893         memmove(s + i, a, size);
04894         free(a);
04895         return s;
04896 }
04897 char* memshr(char* s, size_t size, size_t n) {
04898         memmove(s + size, s, (n - 1) * size);
04899         return s + size;
04900 }
04901 char* memshl(char* s, size_t size, size_t n) {
04902         memmove(s, s + size, (n - 1) * size);
04903         return s;
04904 }
04905 
04906 string chop(const char* str) {
04907         string s(str);
04908         s = s.chop();
04909         return s;
04910 }
04911 string chomp(const char* str, const char* eat) {
04912         string s(str);
04913         s = s.chomp(eat);
04914         return s;
04915 }
04916 string cut(const char* str) {
04917         string s(str);
04918         s = s.cut();
04919         return s;
04920 }
04921 string munch(const char* str, const char* eat) {
04922         string s(str);
04923         s = s.munch(eat);
04924         return s;
04925 }
04926 string ltrim(const char* str) {
04927         string s(str);
04928         s = s.ltrim();
04929         return s;
04930 }
04931 string rtrim(const char* str) {
04932         string s(str);
04933         s = s.rtrim();
04934         return s;
04935 }
04936 string strip(const char* str) {
04937         string s(str);
04938         s = s.strip();
04939         return s;
04940 }
04941 string substr(const char* str, size_t offset, size_t length) {
04942         string s(str);
04943         return s.substr(offset, length);
04944 }
04945 string lc(const char* str) {
04946         string s(str);
04947         return s.lc();
04948 }
04949 string lcfirst(const char* str) {
04950         string s(str);
04951         s[0] = tolower(s[0]);
04952         return s;
04953 }
04954 string uc(const char* str) {
04955         string s(str);
04956         return s.uc();
04957 }
04958 string ucfirst(const char* str) {
04959         string s(str);
04960         s[0] = toupper(s[0]);
04961         return s;
04962 }
04963 long rindex(const char* str, const char* find) {
04964         const char *t, *u;
04965         for (t = strstr(str, find), u = t; t; t = strstr(u, find))
04966                 if (t) u = t;
04967         return u - str;
04968 }
04969 long rindex(const char* str, int find) {
04970         char a[2];
04971         a[0] = find; a[1] = 0;
04972         return rindex(str, a);
04973 }
04974 string q(const char* str) {
04975         string s(str);
04976         return s.q();
04977 }
04978 string qq(const char* str) {
04979         string s(str);
04980         return s.qq();
04981 }
04982 string qx(const char* exec) {
04983         string s(exec);
04984         return s.qx();
04985 }
04986 string scat(const char* s1, const char* s2) {
04987         string s(s1);
04988         s = s.cat(s2);
04989         return s;
04990 }
04991 string sdup(const char* str, int x) {
04992         string s(str);
04993         return s * x;
04994 }
04995 string tok(size_t index, const char* str, const char* delim) {
04996         string s(str);
04997         return s.tok(index, delim);
04998 }
04999 string tok(size_t index, const char* str, int delim) {
05000         char a[2];
05001         a[0] = delim; a[1] = 0;
05002         return tok(index, str, a);
05003 }
05004 long ntok(const char* str, const char* delim) {
05005         string s(str);
05006         return s.ntok(delim);
05007 }
05008 long ntok(const char* str, int delim) {
05009         char a[2];
05010         a[0] = delim; a[1] = 0;
05011         return ntok(str, a);
05012 }
05013 long itok(size_t index, const char* str, const char* delim) {
05014         string s(str);
05015         return s.itok(index, delim);
05016 }
05017 long itok(size_t index, const char* str, int delim) {
05018         char a[2];
05019         a[0] = delim; a[1] = 0;
05020         return itok(index, str, a);
05021 }
05022 std::deque<axcel::string> split(const char* str, const char* delim) {
05023         axcel::string s(str);
05024         return s.split(delim);
05025 }
05026 std::deque<axcel::string> split(const char* str, int delim) {
05027         char a[2];
05028         a[0] = delim; a[1] = 0;
05029         return split(str, a);
05030 }
05031 string join(std::deque<axcel::string> v, const char* delim) {
05032         axcel::string s;
05033         while (!v.empty()) {
05034                 s += v.front();
05035                 s += delim;
05036                 v.pop_front();
05037         }
05038         s = s.chomp(delim);
05039         return s;
05040 }
05041 string join(std::deque<axcel::string> v, int delim) {
05042         axcel::string s;
05043         while (!v.empty()) {
05044                 s += v.front();
05045                 s += delim;
05046                 v.pop_front();
05047         }
05048         char a[2];
05049         a[0] = delim; a[1] = 0;
05050         s = s.chomp(a);
05051         return s;
05052 }
05053 
05059 string string::rep(const char* oldstr, const char* newstr) {
05060         string s(buf);
05061         if (s.str(oldstr) == -1) return s;
05062         long i = 0, k = -1, p;
05063         size_t j = strlen(oldstr), o = strlen(newstr);
05064         for (;;) {
05065                 if (i > s.len()) break;
05066                 p = s.shl(i).str(oldstr);
05067                 if (p == -1) break;
05068                 i = p + i;
05069                 s = s.rm(i, j);
05070                 s = s.ins(i, newstr);
05071                 i += o;
05072         }
05073         return s;
05074 }
05075 
05081 string string::rep(int oldc, int newc) {
05082         char a[2], b[2];
05083         a[0] = oldc; a[1] = 0;
05084         b[0] = newc; b[1] = 0;
05085         return rep(a, b);
05086 }
05087 
05092 string string::prefix(const char* str) {
05093         string s(buf);
05094         unless (s.starts(str)) s -= str;
05095         return s;
05096 }
05097 
05102 string string::suffix(const char* str) {
05103         string s(buf);
05104         unless (s.ends(str)) s += str;
05105         return s;
05106 }
05107 
05113 string string::untag(int opentag, int closetag) {
05114         string s;
05115         if (empty()) return s;
05116         size_t p = tell();
05117         rewind();
05118         int c;
05119         bool b = false;
05120         for (;;) {
05121                 c = getc();
05122                 if (c == EOF) break;
05123                 if (c == opentag) { b = true; continue; }
05124                 else if (c == closetag) { b = false; continue; }
05125                 else if (!b) s.putc(c);
05126         }
05127         seek(p, SEEK_SET);
05128         return s;
05129 }
05130 
05131 
05132 
05133 
05134 #ifdef _WIN32
05135 struct tm * localtime_r (const time_t *timer, struct tm *result)
05136 
05137 
05138 {
05139    struct tm *local_result;
05140    local_result = localtime (timer);
05141 
05142    if (local_result == NULL || result == NULL)
05143      return NULL;
05144 
05145    memmove (result, local_result, sizeof (struct tm));
05146    return result;
05147 }
05148 
05149 struct tm * gmtime_r (const time_t *timer, struct tm *result)
05150 {
05151    struct tm *local_result;
05152    local_result = gmtime (timer);
05153 
05154    if (local_result == NULL || result == NULL)
05155      return NULL;
05156 
05157    memmove (result, local_result, sizeof (struct tm));
05158    return result;
05159 } 
05160 #endif
05161 
05162 time_t axcel_timegm(struct tm* tm) {
05163         time_t ret;
05164         string tz;
05165         tz = proc::envget("TZ");
05166         proc::envset("TZ", "");
05167         tzset();
05168         ret = mktime(tm);
05169         unless (tz.empty())
05170                 proc::envset("TZ", tz);
05171         tzset();
05172         return ret;
05173 }
05174 
05175 timer::timer() { memset(&t, 0, sizeof(struct tm)); UTC = false; }
05176 timer::timer(const char* s) { UTC = false; this->operator=((const char*)s); }
05180 int timer::sec() { return t.tm_sec; }
05181 
05185 int timer::min() { return t.tm_min; }
05186 
05190 int timer::hour() { return t.tm_hour; }
05191 
05195 int timer::mday() { return t.tm_mday; }
05196 
05200 int timer::mon() { return t.tm_mon; }
05201 
05205 int timer::year() { return t.tm_year; }
05206 
05210 int timer::wday() { return t.tm_wday; }
05211 
05215 string timer::str() {
05216         string s;
05217         s.realloc(32);
05218         string fmt;
05219         if (t.tm_wday != -1) fmt += "%a ";
05220         if (t.tm_mon != -1) fmt += "%b ";
05221 #ifndef _WIN32
05222         if (t.tm_mday != -1) fmt += "%e ";
05223 #else
05224         if (t.tm_mday != -1) fmt += "%d ";
05225 #endif
05226         if (t.tm_hour != -1) {
05227                 fmt += "%H:";
05228                 if (t.tm_min != -1) fmt += "%M";
05229                 else fmt += "00";
05230                 if (t.tm_sec != -1) fmt += ":%S ";
05231         }
05232         if (t.tm_year != -1) fmt += "%Y";
05233         strftime(s.buf, 32, fmt, &t);
05234         return s;
05235 }
05236 
05267 timer& timer::operator= (const char* s) {
05268         int i;
05269         const char* c;
05270         t.tm_sec = 0;
05271         t.tm_min = 0;
05272         t.tm_hour = 0;
05273         t.tm_mday = 1;
05274         t.tm_mon = 0;
05275         t.tm_year = 0;
05276         t.tm_wday = 0;
05277         t.tm_isdst = 0;
05278         if (strstr(s, "Sun")) t.tm_wday = 0;
05279         else if (strstr(s, "Mon")) t.tm_wday = 1;
05280         else if (strstr(s, "Tue")) t.tm_wday = 2;
05281         else if (strstr(s, "Wed")) t.tm_wday = 3;
05282         else if (strstr(s, "Thu")) t.tm_wday = 4;
05283         else if (strstr(s, "Fri")) t.tm_wday = 5;
05284         else if (strstr(s, "Sat")) t.tm_wday = 6;
05285         if (strstr(s, "Jan")) t.tm_mon = 0;
05286         else if (strstr(s, "Feb")) t.tm_mon = 1;
05287         else if (strstr(s, "Mar")) t.tm_mon = 2;
05288         else if (strstr(s, "Apr")) t.tm_mon = 3;
05289         else if (strstr(s, "May")) t.tm_mon = 4;
05290         else if (strstr(s, "Jun")) t.tm_mon = 5;
05291         else if (strstr(s, "Jul")) t.tm_mon = 6;
05292         else if (strstr(s, "Aug")) t.tm_mon = 7;
05293         else if (strstr(s, "Sep")) t.tm_mon = 8;
05294         else if (strstr(s, "Oct")) t.tm_mon = 9;
05295         else if (strstr(s, "Nov")) t.tm_mon = 10;
05296         else if (strstr(s, "Dec")) t.tm_mon = 11;
05297         for (c = strpbrk(s, "0123456789"); c != NULL; c = strpbrk(c, "0123456789")) {
05298                 i = atoi(c);
05299                 while (isdigit(*c)) c++;
05300                 if (*c == ':') {
05301                         t.tm_hour = i;
05302                         c++;
05303                         t.tm_min = atoi(c);
05304                         while (isdigit(*c)) c++;
05305                         if (*c == ':') t.tm_sec = atoi(++c);
05306                         while (isdigit(*c)) c++;
05307                         if (*c == ' ') c++;
05308                         if (
05309                                 !strncmp(c, "PM", 2) ||
05310                                 !strncmp(c, "pm", 2) ||
05311                                 !strncmp(c, "p.m.", 4)
05312                         ) { if (t.tm_hour != 12) t.tm_hour += 12;
05313                         } else if (
05314                                 !strncmp(c, "AM", 2) ||
05315                                 !strncmp(c, "am", 2) ||
05316                                 !strncmp(c, "a.m.", 4)
05317                         ) { if (t.tm_hour == 12) t.tm_hour = 0; }
05318                 } else {
05319                         if (i > 0 && i < 32) t.tm_mday = i;
05320                         else t.tm_year = i - 1900;
05321                 }
05322         }
05323         return *this;
05324 }
05325 
05326 
05337 bool timer::operator== (const char* s) { return op<int>(::eq, s); }
05338 
05339 const char* strstrs(const char* src, ...) {
05340         va_list v;
05341         va_start(v, src);
05342         const char *a, *b;
05343         for (a = va_arg(v, const char*); a != NULL; a = va_arg(v, const char*))
05344                 if ((b = strstr(src, a))) break;
05345         va_end(v);
05346         return b;
05347 }
05348 
05349 int strstrc(const char* src, ...) {
05350         va_list v;
05351         va_start(v, src);
05352         int i = 0;
05353         const char* a;
05354         for (a = va_arg(v, const char*); a != NULL; a = va_arg(v, const char*), i++)
05355                 if (strstr(src, a)) break;
05356         va_end(v);
05357         if (a == NULL) return -1; else return i;
05358 }
05359 
05360 bool timer::operator> (const char* s) { return op<int>(::gt, s); }
05361 bool timer::operator< (const char* s) { return op<int>(::lt, s); }
05362 bool timer::operator<= (const char* s) { return op<int>(::lte, s); }
05363 bool timer::operator>= (const char* s) { return op<int>(::gte, s); }
05364 bool timer::operator!= (const char* s) { return op<int>(::neq, s); }
05365 
05375 timer timer::operator+ (const char* s) {
05376         time_t tm;
05377         timer c;
05378         string p = s;
05379         char u[12];
05380         if (UTC) tm = axcel_timegm(&t);
05381         else tm = mktime(&t);
05382         while (p.pbrk("0123456789") > -1) {
05383                 p = p.shl(p.pbrk("0123456789"));
05384                 strcpy(u, p.tok(1, ' '));
05385                 if (sfront(u, "second")) tm += atoi(p.tok(0, ' '));
05386                 else if (sfront(u, "minute"))tm += atoi(p.tok(0, ' ')) * 60;
05387                 else if (sfront(u, "hour")) tm += atoi(p.tok(0, ' ')) * 60 * 60;
05388                 else if (sfront(u, "day")) tm += atoi(p.tok(0, ' ')) * 60 * 60 * 24;
05389                 else if (sfront(u, "week")) tm += atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 7;
05390                 else if (sfront(u, "month")) tm += atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 30;
05391                 else if (sfront(u, "year")) tm += atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 365;
05392                 p = p.slurp(' ');
05393         }
05394         if (UTC) gmtime_r(&tm, &(c.t));
05395         else localtime_r(&tm, &(c.t));
05396         return c;
05397 }
05398 
05405 timer timer::operator- (const char* s) {
05406         time_t tm;
05407         timer c;
05408         string p = s;
05409         char u[12];
05410         if (UTC) tm = axcel_timegm(&t);
05411         else tm = mktime(&t);
05412         while (p.pbrk("0123456789") > -1) {
05413                 p = p.shl(p.pbrk("0123456789"));
05414                 strcpy(u, p.tok(1, ' '));
05415                 if (sfront(u, "second")) tm -= atoi(p.tok(0, ' '));
05416                 else if (sfront(u, "minute")) tm -= atoi(p.tok(0, ' ')) * 60;
05417                 else if (sfront(u, "hour")) tm -= atoi(p.tok(0, ' ')) * 60 * 60;
05418                 else if (sfront(u, "day")) tm -= atoi(p.tok(0, ' ')) * 60 * 60 * 24;
05419                 else if (sfront(u, "week")) tm -= atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 7;
05420                 else if (sfront(u, "month")) tm -= atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 30;
05421                 else if (sfront(u, "year")) tm -= atoi(p.tok(0, ' ')) * 60 * 60 * 24 * 365;
05422                 p = p.slurp(' ');
05423         }
05424         if (UTC) gmtime_r(&tm, &(c.t));
05425         else localtime_r(&tm, &(c.t));
05426         return c;
05427 }
05428 
05429 timer& timer::operator+= (const char* s) { *this = this->operator+(s); return *this; }
05430 timer& timer::operator-= (const char* s) { *this = this->operator-(s); return *this; }
05431 timer& timer::operator= (time_t raw) {
05432         if (UTC) gmtime_r(&raw, &t);
05433         else localtime_r(&raw, &t);
05434         return *this;
05435 }
05436 string timer::ltime() {
05437         string s;
05438         time_t foo;
05439         struct tm bar;
05440         foo = time(NULL);
05441         localtime_r(&foo, &bar);
05442         s.realloc(32);
05443 #ifndef _WIN32
05444         strftime(s.buf, 32, "%a %b %e %H:%M:%S %Y", &bar);
05445 #else
05446         strftime(s.buf, 32, "%a %b %d %H:%M:%S %Y", &bar);
05447 #endif
05448         return s;
05449 }
05450 
05451 string timer::utime() {
05452         string s;
05453         time_t foo;
05454         struct tm bar;
05455         foo = time(NULL);
05456         gmtime_r(&foo, &bar);
05457         s.realloc(32);
05458 #ifndef _WIN32
05459         strftime(s.buf, 32, "%a %b %e %H:%M:%S %Y", &bar);
05460 #else
05461         strftime(s.buf, 32, "%a %b %d %H:%M:%S %Y", &bar);
05462 #endif
05463         return s;
05464 }
05465 
05466 
05467 timer& timer::operator= (struct tm* tm) {
05468         memmove(&t, tm, sizeof(struct tm));
05469         return *this;
05470 }
05471 
05472 namespace fs {
05473 
05474 #ifndef _WIN32
05475 timer fatime(const char* fname) {
05476         timer c;
05477         struct stat buf;
05478         if (stat(fname, &buf) == -1) return c;
05479         c = buf.st_atime;
05480         return c;
05481 }
05482 timer fmtime(const char* fname) {
05483         timer c;
05484         struct stat buf;
05485         if (stat(fname, &buf) == -1) return c;
05486         c = buf.st_mtime;
05487         return c;
05488 }
05489 #else
05490 timer fatime(const char* fname) {
05491         HANDLE h;
05492         FILETIME ft; SYSTEMTIME z; SYSTEMTIME r;
05493         timer c;
05494         h = CreateFile(fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
05495         if (h == INVALID_HANDLE_VALUE) return c;
05496         if (!GetFileTime(h, NULL, &ft, NULL)) return c;
05497         FileTimeToSystemTime(&ft, &z);
05498         SystemTimeToTzSpecificLocalTime(NULL, &z, &r);
05499         struct tm t;
05500         t.tm_year = r.wYear - 1900;
05501         t.tm_mon = r.wMonth - 1;
05502         t.tm_wday = r.wDayOfWeek;
05503         t.tm_mday = r.wDay;
05504         t.tm_hour = r.wHour;
05505         t.tm_min = r.wMinute;
05506         t.tm_sec = r.wSecond;
05507         memmove(&c.t, &t, sizeof(struct tm));
05508         return c;
05509 }
05510 
05511 timer fmtime(const char* fname) {
05512         HANDLE h;
05513         FILETIME ft; SYSTEMTIME z; SYSTEMTIME r;
05514         timer c;
05515         h = CreateFile(fname, GENERIC_READ, 0, NULL, OPEN_EXISTING, NULL, NULL);
05516         if (h == INVALID_HANDLE_VALUE) return c;
05517         if (!GetFileTime(h, NULL, NULL, &ft)) return c;
05518         FileTimeToSystemTime(&ft, &z);
05519         SystemTimeToTzSpecificLocalTime(NULL, &z, &r);
05520         struct tm t;
05521         t.tm_year = r.wYear - 1900;
05522         t.tm_mon = r.wMonth - 1;
05523         t.tm_wday = r.wDayOfWeek;
05524         t.tm_mday = r.wDay;
05525         t.tm_hour = r.wHour;
05526         t.tm_min = r.wMinute;
05527         t.tm_sec = r.wSecond;
05528         memmove(&c.t, &t, sizeof(struct tm));
05529         return c;
05530 }
05531 #endif
05532 
05533 /*
05534 #ifndef _WIN32
05535 bool mkfifo(const char* fname) { return !mknod(fname, S_IFIFO | 0666, 0); }
05536 bool mkhlnk(const char* ofname, const char* lfname) { return !link(ofname, lfname); }
05537 bool mkslnk(const char* ofname, const char* lfname) { return !symlink(ofname, lfname); }
05538 string rdlnk(const char* lfname) {
05539         string s(256);
05540         ssize_t t = readlink(lfname, s, 256);
05541         if (t == -1) { s[0] = 0; return s; }
05542         else { s[t] = 0; return s; }
05543 }
05544 #endif
05545 */
05546 
05547 bool mv(const char* src, const char* dst) { return (cp(src, dst) && rm(src)); }
05548 
05549 bool cp(const char* src, const char* dst) {
05550         FILE *f, *g;
05551         if (!(f = fopen(src, "rb"))) return 0;
05552         if (fisdir(dst)) {
05553                 char* p = (char*)malloc(4);
05554                 if (strchr(src, '/')) {
05555                         p = (char*)realloc(p, strlen(dst) + strlen(strrchr(src, '/') + 1));
05556                         strcpy(p, dst);
05557                         if (p[strlen(p) - 1] == '/') p[strlen(p) -1] = 0;
05558                         strcat(p, strrchr(src, '/'));                   
05559                         if (!(g = fopen(strrchr(p, '/') + 1, "wb"))){
05560                                 free(p); fclose(f); return 0;
05561                         }
05562                 } else {
05563                         p = (char*)realloc(p, strlen(dst) + strlen(src) + 2);
05564                         strcpy(p, dst);
05565                         if (p[strlen(p) - 1] == '/') p[strlen(p) - 1] = 0;
05566                         strcat(p, "/");
05567                         strcat(p, src);
05568                         if (!(g = fopen(p, "wb"))) {
05569                                 free(p);
05570                                 fclose(f);
05571                                 return 0;
05572                         }
05573                 }
05574                 free(p);
05575         } else {
05576                 if (!(g = fopen(dst, "wb"))) {
05577                         fclose(f);
05578                         return 0;
05579                 }
05580         }
05581         int c;
05582         while (!feof(f)) {
05583                 c = fgetc(f);
05584                 if (c == EOF) break;
05585                 fputc(c, g);
05586         }
05587         fclose(f);
05588         fclose(g);
05589         return 1; 
05590 }
05591 
05592 string gcd() {
05593         string s;
05594         size_t i;
05595         s.realloc(32);
05596 #ifndef _WIN32
05597         while (getcwd(s, s.msize()) == NULL)
05598                 s.realloc(s.msize() * 2);
05599 #else
05600         i = GetCurrentDirectoryA(0, NULL);
05601         s.realloc(i);
05602         GetCurrentDirectoryA(i, s);
05603 #endif
05604         return s;
05605 }
05606 
05607 string ls(const char* dir) {
05608         string s, t;
05609         s.clear();
05610 #ifndef _WIN32
05611         DIR* d;
05612         struct dirent* f;
05613         if (!dir) d = opendir(gcd());
05614         else d = opendir(dir);
05615         if (d == NULL) return s;
05616         while ((f = readdir(d))) { s.realloc(s.len() + strlen(f->d_name) + 2); strcat(s.buf, f->d_name); strcat(s.buf, "\n"); }
05617         closedir(d);
05618 #else
05619         WIN32_FIND_DATA f;
05620         if (!dir) t = t.cat(gcd()).cat("\\*");
05621         HANDLE d = FindFirstFileA(t, &f);
05622         if (d == INVALID_HANDLE_VALUE) return s;
05623         do {
05624                 s.realloc(s.len() + strlen(f.cFileName) + 2);
05625                 strcat(s.buf, f.cFileName);
05626                 strcat(s.buf, "\n");
05627         } while (FindNextFileA(d, &f));
05628         FindClose(d);
05629 #endif
05630         return s;
05631 }
05632 
05633 size_t fread(const char* fname, char* buf, size_t size) {
05634         size_t i;
05635         FILE* f;
05636         if (!(f = fopen(fname, "rb"))) return 0;
05637         for (i = 0; !feof(f) && (i < size || !size); i++) {
05638                 buf[i] = fgetc(f);
05639                 if (buf[i] == -1) { buf[i] = 0; break; }
05640         }
05641         fclose(f);
05642         return i;
05643 }
05644 
05645 string fread(const char* fname, size_t size) {
05646         size_t i;
05647         int j;
05648         FILE* f;
05649         string s;
05650         if (!(f = fopen(fname, "rb"))) return s;
05651         for (i = 0; !feof(f) && (i < size || !size); i++) {
05652                 j = fgetc(f);
05653                 if (j == EOF) break;
05654                 s += (char)j;
05655         }
05656         fclose(f);
05657         return s;
05658 }
05659 
05660 size_t fwrite(const char* fname, const char* buf, size_t size) {
05661         FILE* f;
05662         if (!(f = fopen(fname, "wb"))) return 0;
05663         if (!size) size = strlen(buf);
05664         size_t i = fwrite(buf, 1, size, f);
05665         fclose(f);
05666         return i;
05667 }
05668 
05669 size_t fcat(const char* fname, const char* buf, size_t len) {
05670         FILE* f;
05671         if (!(f = fopen(fname, "ab"))) return 0;
05672         if (!len) len = strlen(buf);
05673         size_t i = fwrite(buf, 1, len, f);
05674         fclose(f);
05675         return i;
05676 }
05677 
05678 bool fcmp(const char* src, const char* dst) {
05679         FILE *f, *g;
05680         register char a, b;
05681         if (!(f = fopen(src, "rb"))) return 0;
05682         if (!(g = fopen(dst, "rb"))) return 0;
05683         while (!feof(f) && !feof(g)) {
05684                 a = fgetc(f);
05685                 b = fgetc(g);
05686                 if (a != b) {
05687                         fclose(f);
05688                         fclose(g);
05689                         return 0;
05690                 }
05691         }
05692         if (feof(f) && feof(g)) {
05693                 fclose(f);
05694                 fclose(g);
05695                 return 1;
05696         }
05697         fclose(f);
05698         fclose(g);
05699         return 0;
05700 }
05701 
05702 #ifndef _WIN32
05703 bool md(const char* path) { if (::mkdir(path, 00744) == -1) return 0; else return 1; }
05704 bool cd(const char* path) { if (::chdir(path) == -1) return 0; else return 1; }
05705 bool creat(const char* fname) {
05706         int f = ::open(fname, O_CREAT | O_TRUNC | O_RDWR, 00644);
05707         if (f == -1) return 0;
05708         ::close(f);
05709         return 1;
05710 }
05711 bool trunc(const char* fname, unsigned long len) {
05712         if (truncate(fname, len) == -1) return 0;
05713         else return 1;
05714 }
05715 bool rm(const char* fname) { if (remove(fname) == -1) return 0; else return 1; }
05716 
05717 bool rd(const char* dir, bool rmsub) {
05718         if (!rmsub)
05719                 return !rmdir(dir);
05720         bool ret = true;
05721         unsigned long i = 0;
05722         string s = ls(dir), t;
05723         for (;;) {
05724                 t = s.tok(i++, "\n");
05725                 if (t.empty()) break;
05726                 if (t == ".." || t == ".") continue;
05727                 if (!sback(dir, "/")) t = t.prep('/');
05728                 t = t.prep(dir);
05729                 if (fisdir(t)) rd(t);
05730                 rm(t);
05731         }
05732         if (rmdir(dir)) ret = false;
05733         return ret;
05734 }
05735 
05736 size_t fsize(const char* fname) {
05737         struct stat buf;
05738         if (stat(fname, &buf) == -1) return 0;
05739         return buf.st_size;
05740 }
05741 bool fexist(const char* fname) {
05742         int i;
05743         struct stat buf;
05744         i = stat(fname, &buf);
05745         if (i == -1) return 0;
05746         return 1;
05747 }
05748 bool fisdir(const char* fname) {
05749         struct stat buf;
05750         if (stat(fname, &buf) == -1) return 0;
05751         return S_ISDIR(buf.st_mode);
05752 }
05753 bool fisreg(const char* fname) {
05754         struct stat buf;
05755         if (stat(fname, &buf) == -1) return 0;
05756         return S_ISREG(buf.st_mode);
05757 }
05758 #else
05759 bool rd(const char* dir, bool rmsub) {
05760         if (!rmsub)
05761                 return (bool)RemoveDirectory(dir);
05762         bool ret = true;
05763         unsigned long i = 0;
05764         string s = ls(dir), t;
05765         for (;;) {
05766                 t = s.tok(i++, "\n");
05767                 if (t.empty()) break;
05768                 if (t == ".." || t == ".") continue;
05769                 if (!sback(dir, "/")) t = t.prep('/');
05770                 t = t.prep(dir);
05771                 if (fisdir(t)) rd(t);
05772                 rm(t);
05773         }
05774         if (!RemoveDirectory(dir)) ret = false;
05775         return ret;
05776 }
05777 
05778 bool fisdir(const char* fname) {
05779         DWORD i = GetFileAttributesA(fname);
05780         if (i == INVALID_FILE_ATTRIBUTES) return 0;
05781         else if (i & FILE_ATTRIBUTE_DIRECTORY) return 1;
05782         else return 0;
05783 }
05784 bool fisreg(const char* fname) {
05785         DWORD i = GetFileAttributesA(fname);
05786         if (i == INVALID_FILE_ATTRIBUTES) return 0;
05787         else if (!(i & FILE_ATTRIBUTE_DIRECTORY)) return 1;
05788         else return 0;
05789 }
05790 bool fexist(const char* fname) {
05791         if (GetFileAttributesA(fname) == INVALID_FILE_ATTRIBUTES) return 0;
05792         return 1;
05793 }
05794 bool creat(const char* fname) {
05795         HANDLE f = CreateFileA(fname, 0, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
05796         if (f == INVALID_HANDLE_VALUE) return 0;
05797         CloseHandle(f);
05798         return 1;
05799 }
05800 bool trunc(const char* fname, unsigned long len) {
05801         HANDLE f = CreateFileA(fname, 0, 0, 0, OPEN_EXISTING, 0, 0);
05802         if (f == INVALID_HANDLE_VALUE) return 0;
05803         if (SetFilePointer(f, len, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) return 0;
05804         if (!SetEndOfFile(f)) return 0;
05805         CloseHandle(f);
05806         return 1;
05807 }
05808 size_t fsize(const char* fname) {
05809         HANDLE f = CreateFileA(fname, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
05810         if (f == INVALID_HANDLE_VALUE) return -1;
05811         long int i = GetFileSize(f, 0);
05812         CloseHandle(f);
05813         return i;
05814 }
05815 #endif
05816 
05817 };
05818 
05819 proc::thread::thread() { tid = 0; sub = 0; stack = 0; }
05820 proc::thread::thread(void* (*tfunc)(void*)) { tid = 0; sub = tfunc; stack = 0; }
05821 proc::thread& proc::thread::operator= (void* (*tfunc)(void*)) { sub = tfunc; return *this; }
05822 proc::thread& proc::thread::operator= (proc::thread t) { sub = t.sub; tid = t.tid; return *this; }
05823 bool proc::thread::operator== (proc::thread t) { return (sub == t.sub && tid == t.tid); }
05824 bool proc::thread::operator== (void* (*tfunc)(void*)) { return sub == tfunc; }
05825 bool proc::thread::operator!= (proc::thread t) { return !(sub == t.sub && tid == t.tid); }
05826 bool proc::thread::operator!= (void* (*tfunc)(void*)) { return sub != tfunc; }
05827 
05828 #ifdef _WIN32
05829 proc::thread::~thread() { CloseHandle(fd); }
05830 bool proc::thread::start(void* param) {
05831         if (!sub) return false;
05832         DWORD t;
05833         HANDLE tmp = CreateThread(0, stack, (LPTHREAD_START_ROUTINE)sub, param, 0, &t);
05834         if (!tmp) return false;
05835         else { fd = tmp; tid = t; return true; } 
05836 }
05837 bool proc::thread::stop() { return TerminateThread(fd, 0); }
05838 bool proc::thread::join(void ** ret) {
05839         WaitForSingleObject(fd, INFINITE);
05840         return getret(ret);
05841 }
05842 bool proc::thread::tjoin(size_t ms, void ** ret) {
05843         WaitForSingleObject(fd, ms);
05844         return getret(ret);
05845 }
05846 bool proc::thread::getret(void ** retval) {
05847         void* r;
05848         if (GetExitCodeThread(fd, (LPDWORD)&r)) {
05849                 memmove(*retval, r, sizeof(void*));
05850                 return true;
05851         } else return false;
05852 }
05853 
05854 void proc::thread::exit(void* retval) { ExitThread((DWORD)retval); }
05855 proc::thread proc::thread::self() { proc::thread t; t.tid = GetCurrentThreadId(); return t; }
05856 #else
05857 proc::thread::~thread() { pthread_attr_destroy(&attr); }
05858 bool proc::thread::start(void* param) {
05859         register int err;
05860         if (err = pthread_attr_init(&attr)) { errnum = err; return false; }
05861         if (stack)
05862                 if (err = pthread_attr_setstacksize(&attr, stack)) {
05863                         errnum = err; return false;
05864                 }
05865         if (err = pthread_create(&tid, &attr, sub, param)) {
05866                 errnum = err; return false;
05867         }
05868         
05869         return true;
05870 }
05871 bool proc::thread::stop() {
05872         register int err;
05873         if (err = pthread_cancel(tid)) {
05874                 errnum = err; return false;
05875         }
05876         
05877         return true;
05878 }
05879 bool proc::thread::join(void ** ret) {
05880         void* r;
05881         register int err;
05882         if (ret) {
05883                 if (err = pthread_join(tid, ret)) {
05884                         errnum = err;
05885                         return false;
05886                 }
05887         } else {
05888                 if (err = pthread_join(tid, &r)) {
05889                         errnum = err;
05890                         return false;
05891                 }
05892         }
05893         
05894         return true;
05895 }
05896 bool proc::thread::tjoin(size_t ms, void ** ret) {
05897         void* r;
05898         struct timespec t;
05899         register int err;
05900         t.tv_sec = ms / 1000;
05901         t.tv_nsec = (ms % 1000) * (1000 * 1000);
05902         if (ret) {
05903                 if (err = pthread_timedjoin_np(tid, ret, &t)) { errnum = err; return false; }
05904         } else {
05905                 if (err = pthread_timedjoin_np(tid, &r, &t)) {
05906                         errnum = err; return false;
05907                 }
05908         }
05909         
05910         return true;
05911 }
05912 bool proc::thread::getret(void ** retval) {
05913         void* r;
05914         register int err;
05915         if (retval == 0) err = pthread_tryjoin_np(tid, &r);
05916         else err = pthread_tryjoin_np(tid, retval);
05917         if (!err) {  return true; }
05918         errnum = err;
05919         return false;
05920 }
05921 void proc::thread::exit(void* retval) { pthread_exit(retval); }
05922 proc::thread proc::thread::self() { proc::thread t; t.tid = pthread_self(); return t; }
05923 #endif
05924 
05925 string proc::environment::type() { return string("proc::environ"); }
05926 proc::environment::operator string () {
05927         string s;
05928         std::deque<p>::iterator it;
05929         for (it = e.begin(); it != e.end(); it++)
05930                 if (it->v.empty()) {
05931                         e.erase(it--);
05932                         continue;
05933                 } else
05934                         s << it->k << '=' << it->v << '\n';
05935         return s;
05936 }
05937 string proc::environment::vars() {
05938         string v;
05939         std::deque<p>::iterator it;
05940         for (it = e.begin(); it != e.end(); it++)
05941                 if (it->v.empty()) {
05942                         e.erase(it--);
05943                         continue;
05944                 } else
05945                         v << it->k << '\n';
05946         return v;
05947 }
05948 string& proc::environment::operator[] (const char* s) {
05949         std::deque<p>::iterator it;
05950         struct p pair;
05951         for (it = e.begin(); it != e.end(); it++)
05952                 if (it->k == s) break;
05953         if (it == e.end()) { pair.k = s; e.push_back(pair); }
05954         return it->v;
05955 }
05956 string& proc::environment::at(size_t i) {
05957         return e[i].v;
05958 }
05959 size_t proc::environment::len() {
05960         std::deque<p>::iterator it;
05961         for (it = e.begin(); it != e.end(); it++)
05962                 if (it->v.empty()) {
05963                         e.erase(it--);
05964                         continue;
05965                 }
05966         return e.size();
05967 }
05968 proc::environment& proc::environment::clear() {
05969         e.clear();
05970         return *this;
05971 }
05972 bool proc::environment::empty() {
05973         return e.empty();
05974 }
05975 
05976 data proc::environment::bake() {
05977         data d;
05978         size_t i = 0, j = 0, k = 0;
05979         char *c, **b;
05980         std::deque<p>::iterator it;
05981         for (it = e.begin(); it != e.end(); it++) {
05982                 if (it->v.empty()) {
05983                         e.erase(it--);
05984                         continue;
05985                 }
05986                 i++;
05987                 j += it->k.len() + it->v.len() + 2;
05988         }
05989         i++;
05990         d.realloc(sizeof(char*) * i + j);
05991         c = d.buf + sizeof(char*) * i;
05992         b = (char**)d.buf;
05993         for (it = e.begin(); it != e.end(); it++, k++) {
05994                 strcpy(c, it->k);
05995                 strcat(c, "=");
05996                 strcat(c, it->v);
05997                 b[k] = c;
05998                 c += strlen(c) + 1;
05999         }
06000         b[k] = (char*)0;
06001         return d;
06002 }
06003 
06004 namespace proc {
06005 
06006 #ifndef _WIN32
06007 
06008 string lsproc() {
06009         string s, t, u;
06010         fs::file f;
06011         size_t pid;
06012         std::deque<string> d = fs::ls("/proc").split('\n');
06013         std::deque<string>::iterator it;
06014         for (it = d.begin(); it < d.end(); it++) {
06015                 if ((*it)[0] == '.') continue;
06016                 if (!it->isdigit()) continue;
06017                 f.open(it->prep("/proc/").cat("/status"), "rb");
06018                 if (f.dead()) continue;
06019                 until (f.eof()) {
06020                         t = f.gets();
06021                         if (t.starts("Name:")) u = t.slurp(':').ltrim();
06022                         else if (t.starts("Pid:"))
06023                                 pid = stoi<size_t>(t.slurp(':').ltrim());
06024                 }
06025                 f.close();
06026                 s << pid << ':' << u;
06027         }
06028         return s;
06029 }
06030 
06031 pid_t run(const char* program, const char* argv, void* envp) {
06032         if (!fs::fexist(program)) return false;
06033         pid_t p;
06034         string gay = program;
06035         if (argv) gay = gay.cat(' ').cat(argv);
06036         wordexp_t we;
06037         char** w;
06038         wordexp(gay, &we, WRDE_NOCMD);
06039         w = we.we_wordv;
06040         char *const e[] = {NULL,NULL};
06041         p = fork();
06042         if (!p) {
06043                 setsid();
06044                 if (!envp) execve(program, w, e);
06045                 else execve(program, w, (char* *const)envp);
06046                 wordfree(&we);
06047         } else {
06048                 wordfree(&we);
06049         }
06050         return p;
06051 }
06052 
06053 bool killp(size_t pid) {
06054         if (kill(pid, SIGKILL) == -1) return false;
06055         else return true;
06056 }
06057 bool killp(const char* name) {
06058         pid_t p;
06059         size_t i;
06060         char* s = (char*)malloc(264);
06061         char buf[128];
06062         FILE* st;
06063         DIR* d = opendir("/proc");
06064         if (d == NULL) { free(s); return false; }
06065         struct dirent* f;
06066         while ((f = readdir(d)) != NULL) {
06067                 if (f->d_name[0] == '.') continue;
06068                 for (i = 0; isdigit(f->d_name[i]); i++);
06069                 if (i < strlen(f->d_name)) continue;
06070                 strcpy(s, "/proc/");
06071                 strcat(s, f->d_name);
06072                 strcat(s, "/status");
06073                 st = fopen(s, "r");
06074                 if (st == NULL) { closedir(d); free(s); return false; }
06075                 do {
06076                         if (fgets(buf, 128, st) == NULL) { fclose(st); closedir(d); free(s); return false; }
06077                 } while (strncmp(buf, "Name:", 5));
06078                 fclose(st);
06079                 for (i = 5; isspace(buf[i]); i++);
06080                 *strchr(buf, '\n') = 0;
06081                 if (!strcmp(&(buf[i]), name)) {
06082                         sscanf(&(s[6]), "%d", &p);
06083                         kill(p, SIGKILL);
06084                 }
06085         }
06086         closedir(d);
06087         free(s);
06088         return true;
06089 }
06090 bool freeze(size_t pid) { if (kill(pid, SIGSTOP) == -1) return false; else return true; }
06091 bool freeze(const char* name) {
06092         pid_t p;
06093         size_t i;
06094         char* s = (char*)malloc(264);
06095         char buf[128];
06096         FILE* st;
06097         DIR* d = opendir("/proc");
06098         if (d == NULL) { free(s); return false; }
06099         struct dirent* f;
06100         while ((f = readdir(d)) != NULL) {
06101                 if (f->d_name[0] == '.') continue;
06102                 for (i = 0; isdigit(f->d_name[i]); i++);
06103                 if (i < strlen(f->d_name)) continue;
06104                 strcpy(s, "/proc/");
06105                 strcat(s, f->d_name);
06106                 strcat(s, "/status");
06107                 st = fopen(s, "r");
06108                 if (st == NULL) { closedir(d); free(s); return false; }
06109                 do {
06110                         if (fgets(buf, 128, st) == NULL) { fclose(st); closedir(d); free(s); return false; }
06111                 } while (strncmp(buf, "Name:", 5));
06112                 fclose(st);
06113                 for (i = 5; isspace(buf[i]); i++);
06114                 *strchr(buf, '\n') = 0;
06115                 if (!strcmp(&(buf[i]), name)) {
06116                         sscanf(&(s[6]), "%d", &p);
06117                         kill(p, SIGSTOP);
06118                 }
06119         }
06120         closedir(d);
06121         free(s);
06122         return true;
06123 }
06124 bool cont(size_t pid) { if (kill(pid, SIGCONT) == -1) return false; else return true; }
06125 bool cont(const char* name) {
06126         pid_t p;
06127         size_t i;
06128         char* s = (char*)malloc(264);
06129         char buf[128];
06130         FILE* st;
06131         DIR* d = opendir("/proc");
06132         if (d == NULL) { free(s); return false; }
06133         struct dirent* f;
06134         while ((f = readdir(d)) != NULL) {
06135                 if (f->d_name[0] == '.') continue;
06136                 for (i = 0; isdigit(f->d_name[i]); i++);
06137                 if (i < strlen(f->d_name)) continue;
06138                 strcpy(s, "/proc/");
06139                 strcat(s, f->d_name);
06140                 strcat(s, "/status");
06141                 st = fopen(s, "r");
06142                 if (st == NULL) { closedir(d); free(s); return false; }
06143                 do {
06144                         if (fgets(buf, 128, st) == NULL) { fclose(st); closedir(d); free(s); return false; }
06145                 } while (strncmp(buf, "Name:", 5));
06146                 fclose(st);
06147                 for (i = 5; isspace(buf[i]); i++);
06148                 *strchr(buf, '\n') = 0;
06149                 if (!strcmp(&(buf[i]), name)) {
06150                         sscanf(&(s[6]), "%d", &p);
06151                         kill(p, SIGCONT);
06152                 }
06153         }
06154         closedir(d);
06155         free(s);
06156         return true;
06157 }
06158 void delay(size_t ms) {
06159         struct timespec t;
06160         t.tv_sec = ms / 1000;
06161         t.tv_nsec = (ms % 1000) * (1000 * 1000);
06162         nanosleep(&t, 0);
06163 }
06164 bool envset(const char* name, const char* value) {
06165         if (value) return !setenv(name, value, 1);
06166         else return !unsetenv(name);
06167 }
06168 string envget(const char* name) {
06169         string s;
06170         char* t = getenv(name);
06171         if (t == NULL) {
06172                 s.clear();
06173                 return s;
06174         }
06175         s = t;
06176         return s;
06177 }
06178 #else
06179 
06180 string lsproc() {
06181         string s;
06182         PROCESSENTRY32 proc;
06183         HANDLE images = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
06184         Process32First(images, &proc);
06185         while (GetLastError() != ERROR_NO_MORE_FILES) {
06186                 s << proc.th32ProcessID << ':' << proc.szExeFile << '\n';
06187                 Process32Next(images, &proc);
06188         }
06189         CloseHandle(images);
06190         return s;
06191 }
06192 
06193 DWORD run(const char* program, const char* argv, void* envp) {
06194         if (!fs::fexist(program)) return false;
06195         string pname = program;
06196         string args = program;
06197         fs::file f;
06198         string s;
06199         PROCESS_INFORMATION pi;
06200         STARTUPINFO si;
06201         memset(&si, 0, sizeof(STARTUPINFO));
06202         si.cb = sizeof(STARTUPINFO);
06203         f.open(program, "rb");
06204         if (f.getc() == '#')
06205                 if (f.getc() == '!') {
06206                         s = f.gets().strip();
06207                         pname = s;
06208                         if (pname.chr(' ') != -1) {
06209                                 pname = pname.burn(' ');
06210                                 args = pname;
06211                                 args += ' ';
06212                                 args += s.slurp(' ');
06213                                 args += ' ';
06214                                 args += program;
06215                         }
06216                 }
06217         f.close();
06218         if (argv) args = args.cat(' ').cat(argv);
06219         if (!CreateProcessA(pname, args, NULL, NULL, false, NORMAL_PRIORITY_CLASS, envp, NULL, &si, &pi)) return false;
06220         return pi.dwProcessId;
06221 }
06222 
06223 bool killp(size_t pid) { return TerminateProcess(OpenProcess(PROCESS_TERMINATE, false, pid), 1); }
06224 bool killp(const char* name) {
06225         PROCESSENTRY32 p;
06226         HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
06227         if (!Process32First(snap, &p)) { CloseHandle(snap); return false; }
06228         do {
06229                 if (!strcmp(name, p.szExeFile))
06230                         if (!killp(p.th32ProcessID)) { 
06231                                 CloseHandle(snap);
06232                                 return false;
06233                         }
06234         } while (Process32Next(snap, &p));
06235         CloseHandle(snap);
06236         return true;
06237 }
06238 bool freeze(size_t pid) {
06239         HANDLE snap;
06240         THREADENTRY32 t;
06241         HANDLE th;
06242         DWORD i;
06243         snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
06244         if (!Thread32First(snap, &t)) { CloseHandle(snap); return false; }
06245         do {
06246 
06247                 if (t.th32OwnerProcessID != pid) continue;
06248                 th = OpenThread(THREAD_SUSPEND_RESUME, false, t.th32ThreadID);
06249                 if (th == NULL) continue;
06250                 i = SuspendThread(th);
06251                 CloseHandle(th);
06252                 if (i == -1) { CloseHandle(snap); return false; }
06253         } while (Thread32Next(snap, &t));
06254         CloseHandle(snap);
06255         return true;
06256 }
06257 bool freeze(const char* name) {
06258         PROCESSENTRY32 p;
06259         HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
06260         if (!Process32First(snap, &p)) { CloseHandle(snap); return false; }
06261         do {
06262                 if (!strcmp(name, p.szExeFile))
06263                         if (!freeze(p.th32ProcessID)) { 
06264                                 CloseHandle(snap);
06265                                 return false;
06266                         }
06267         } while (Process32Next(snap, &p));
06268         CloseHandle(snap);
06269         return true;
06270 }
06271 
06272 bool cont(size_t pid) {
06273         HANDLE snap;
06274         THREADENTRY32 t;
06275         HANDLE th;
06276         DWORD i;
06277         snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
06278         if (!Thread32First(snap, &t)) { CloseHandle(snap); return false; }
06279         do {
06280                 if (t.th32OwnerProcessID != pid) continue;
06281                 th = OpenThread(THREAD_SUSPEND_RESUME, false, t.th32ThreadID);
06282                 if (th == NULL) continue;
06283                 i = ResumeThread(th);
06284                 CloseHandle(th);
06285                 if (i == -1) { CloseHandle(snap); return false; }
06286         } while (Thread32Next(snap, &t));
06287         CloseHandle(snap);
06288         return true;
06289 }
06290 
06291 bool cont(const char* name) {
06292         PROCESSENTRY32 p;
06293         HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
06294         if (!Process32First(snap, &p)) { CloseHandle(snap); return false; }
06295         do {
06296                 if (!strcmp(name, p.szExeFile))
06297                         if (!cont(p.th32ProcessID)) { 
06298                                 CloseHandle(snap);
06299                                 return false;
06300                         }
06301         } while (Process32Next(snap, &p));
06302         CloseHandle(snap);
06303         return true;
06304 }
06305 
06306 bool envset(const char* name, const char* value) { return SetEnvironmentVariableA(name, value); }
06307 string envget(const char* name) {
06308         DWORD i;
06309         string s;
06310         s.realloc(128);
06311         i = GetEnvironmentVariableA(name, s, 128);
06312         if (i > 128) {
06313                 s = (char*)realloc(s, i);
06314                 if (!GetEnvironmentVariableA(name, s, i)) {
06315                         s.clear();
06316                         return s;
06317                 }
06318         } else if (!i) {
06319                 s.clear();
06320                 return s;
06321         }
06322         return s;
06323 }
06324 #endif
06325 
06326 };
06327 
06328 proc::library::~library() {
06329         if (fd)
06330 #ifdef _WIN32
06331                 FreeLibrary(fd);
06332 #else
06333                 dlclose(fd);
06334 #endif
06335 }
06336 
06337 proc::library& proc::library::operator =(const char* libname) {
06338         libraryname = libname;
06339 #ifdef _WIN32
06340         fd = LoadLibraryA(libname);
06341 #else
06342         fd = dlopen(libname, RTLD_LAZY);
06343 #endif
06344         return *this;
06345 }
06346 
06347 proc::library& proc::library::operator= (library s) {
06348         if (fd)
06349 #ifdef _WIN32
06350                 FreeLibrary(fd);
06351 #else
06352                 dlclose(fd);
06353 #endif
06354         fd = s.fd;
06355         return *this;
06356 }
06357 bool proc::library::operator== (library s) { return fd == s.fd; }
06358 bool proc::library::operator!= (library s) { return fd != s.fd; }
06359 void* proc::library::operator[] (const char* name) {
06360 #ifdef _WIN32
06361         return (void*)GetProcAddress(fd, name);
06362 #else
06363         return dlsym(fd, name);
06364 #endif
06365 }
06366 namespace net {
06367 namespace irc {
06368 
06369 msg::msg(const char* line) { buf = line; }
06370 msg& msg::operator= (const char* line) { buf = line; return *this; }
06371 bool msg::operator== (const char* line) { return buf == line; }
06372 bool msg::operator!= (const char* line) { return buf != line; }
06373 string msg::server() {
06374         if (buf.chr(' ') == -1) return string();
06375         return buf.munch(':').burn(' ');
06376 }
06377 string msg::nick() {
06378         if (buf.chr('!') == -1 || buf.chr(' ') == -1)
06379                 return string();
06380         if (buf.chr('!') > buf.chr(' '))
06381                 return string();
06382         return buf.munch(':').burn('!');
06383 }
06384 string msg::user() {
06385         if (nick().empty()) return string();
06386         return buf.slurp('!').burn('@');
06387 }
06388 string msg::host() {
06389         if (nick().empty()) return string();
06390         return buf.slurp('@').burn(' ');
06391 }
06392 string msg::cmd() {
06393         if (buf.chr(' ') == -1) return string();
06394         return buf.tok(1, ' ');
06395 }
06396 string msg::param(int index) {
06397         if (buf.nchr(' ') < 2) return string();
06398         return buf.shl(buf.itok(2, ' ')).tok(index, ' ');
06399 }
06400 string msg::data() {
06401         if (buf.munch(':').chr(':') == -1 || buf.chr(' ') == -1) return string();
06402         return buf.munch(':').slurp(':');
06403 }/*
06404 :nick!user@host cmd param1 param2 :data
06405 :server cmd param param :data
06406 msg::msg(const char* line) {
06407         if (line) this->operator=(line);
06408         else this->operator=("Expecto_patronum");
06409 }
06410 
06411 msg& msg::operator= (const msg& s) {
06412         memcpy(buf, s.buf, 536);
06413         server = 0;
06414         nick = 0;
06415         user = 0;
06416         host = 0;
06417         cmd = 0;
06418         data = 0;
06419         if (s.server) {
06420                 server = buf;
06421                 cmd = s.cmd - s.server + buf;
06422                 data = s.data - s.server + buf;
06423         } else if (s.nick) {
06424                 nick = buf;
06425                 user = s.user - s.nick + buf;
06426                 host = s.host - s.nick + buf;
06427                 cmd = s.cmd - s.nick + buf;
06428                 data = s.data - s.nick + buf;
06429         }
06430         return *this;
06431 }
06432 
06433 bool msg::operator== (const char* line) {
06434         msg im(line);
06435         return *this == im;
06436 }
06437 bool msg::operator!= (const char* line) {
06438         msg im(line);
06439         return !(*this == im);
06440 }
06441 bool msg::operator== (msg im) {
06442         if (server == NULL) { if (im.server != NULL) return false; }
06443         else if (strcmp(server, im.server)) return false;
06444         if (nick == NULL) { if (im.nick != NULL) return false; }
06445         else if (strcmp(nick, im.nick)) return false;
06446         if (user == NULL) { if (im.user != NULL) return false; }
06447         else if (strcmp(user, im.user)) return false;
06448         if (host == NULL) { if (im.host != NULL) return false; }
06449         else if (strcmp(host, im.host)) return false;
06450         if (cmd == NULL) { if (im.cmd != NULL) return false; }
06451         else if (strcmp(cmd, im.cmd)) return false;
06452         if (data == NULL) { if (im.data != NULL) return false; }
06453         else if (strcmp(data, im.data)) return false;
06454         int i;
06455         const char* c = (const char*)1;
06456         for (i = 0, c = param(0); c; c = param(++i))
06457                 if (strcmp(c, im.param(i))) return false;
06458         return true;
06459 }
06460 bool msg::operator!= (msg im) { return !(this->operator==(im)); }
06461 
06462 const char* msg::param(int index) {
06463         const char* a = cmd + strlen(cmd) + 1;
06464         for (; index > 0; index--) {
06465                 a += strlen(a) + 1;
06466                 if (a[0] == 0) return 0;
06467         }
06468         return a;
06469 }
06470 
06471 msg& msg::operator= (const char* line) {
06472         int i = 0;
06473         const char *a, *b;
06474         server = 0;
06475         nick = 0;
06476         user = 0;
06477         host = 0;
06478         cmd = 0;
06479         data = 0;
06480         if (line[0] == ':') line++;
06481         a = strchr(line, '!');
06482         b = strchr(line, ' ');
06483         if (b == NULL) return *this;
06484         if (a != NULL && a < b) {
06485                 strncpy((char*)buf, line, a - line);
06486                 buf[a - line] = 0;
06487                 nick = buf;
06488                 line += strlen(buf) + 1;
06489                 
06490                 a = strchr(line, '@');
06491                 user = buf + strlen(buf) + 1;
06492                 strncpy((char*)user, line, a - line);
06493                 ((char*)user)[a - line] = 0;
06494                 line += strlen(user) + 1;
06495                 
06496                 a = strchr(line, ' ');
06497                 host = user + strlen(user) + 1;
06498                 strncpy((char*)host, line, a - line);
06499                 ((char*)host)[a - line] = 0;
06500                 line += strlen(host) + 1;
06501                 
06502                 a = strchr(line, ' ');
06503                 cmd = host + strlen(host) + 1;
06504                 strncpy((char*)cmd, line, a - line);
06505                 ((char*)cmd)[a - line] = 0;
06506                 line += strlen(cmd) + 1;
06507                 
06508         } else if (a == NULL || a > b) {
06509                 strncpy(buf, line, b - line);
06510                 buf[b - line] = 0;
06511                 server = buf;
06512                 line += strlen(server) + 1;
06513                 
06514                 a = strchr(line, ' ');
06515                 cmd = server + strlen(server) + 1;
06516                 strncpy((char*)cmd, line, a - line);
06517                 ((char*)cmd)[a - line] = 0;
06518                 line += strlen(cmd) + 1;
06519         }
06520         
06521         a = cmd + strlen(cmd) + 1;
06522         for (b = strchr(line, ' '); line[0] != ':' && (*line - 1 != '\r' && *line != '\n') && line[0]; b = strpbrk(line, " \r\n")) {
06523                 if (b == NULL) b = line + strlen(line);
06524                 strncpy((char*)a, line, b - line);
06525                 ((char*)a)[b - line] = 0;
06526                 line += strlen(a) + 1;
06527                 a += strlen(a) + 1;
06528         }
06529         ((char*)a)[0] = 0;
06530         a++;
06531         data = a;
06532         if (*line == '\r' || !(*line))
06533                 ((char*)data)[0] = 0;
06534         else strcpy((char*)data, ++line);
06535         ((char*)data)[strlen(data) + 1] = 0;
06536         char* x = strstr((char*)data, "\r\n");
06537         if (x) *x = 0;
06538         return *this;
06539 }*/
06540 
06541 };
06542 };
06543 
06544 #ifdef _WIN32
06545 
06546 proc::mutex::mutex() { InitializeCriticalSection(&id); }
06547 proc::mutex::~mutex() { DeleteCriticalSection(&id); }
06548 void proc::mutex::lock() { EnterCriticalSection(&id); }
06549 bool proc::mutex::trylock() { return TryEnterCriticalSection(&id); }
06550 void proc::mutex::unlock() { LeaveCriticalSection(&id); }
06551 
06552 #else
06553 proc::mutex::mutex() { pthread_mutex_init(&id, NULL); }
06554 proc::mutex::~mutex() { pthread_mutex_destroy(&id); }
06555 void proc::mutex::lock() { pthread_mutex_lock(&id); }
06556 bool proc::mutex::trylock() { return !pthread_mutex_trylock(&id); }
06557 void proc::mutex::unlock() { pthread_mutex_unlock(&id); }
06558 
06559 #endif
06560 
06561 #ifdef _WIN32
06562 
06563 proc::semaphore::semaphore(size_t count) { init(count); }
06564 proc::semaphore::semaphore(const char* name) { open(name); }
06565 proc::semaphore::~semaphore() { if (id) CloseHandle(id); }
06566 bool proc::semaphore::init(size_t count) {
06567         named = false;
06568         if ((id = CreateSemaphore(NULL, count, UINT_MAX, NULL)) == NULL)
06569                 return false;
06570         else return true;
06571 }
06572 bool proc::semaphore::die() { return !CloseHandle(id); }
06573 bool proc::semaphore::close() { return !CloseHandle(id); }
06574 bool proc::semaphore::open(const char* name) {
06575         named = true;
06576         string s = name;
06577         s -= "Global\\";
06578         if ((id = OpenSemaphore(SEMAPHORE_MODIFY_STATE, false, s)) == NULL)
06579                 return false;
06580         else return true;
06581 }
06582 bool proc::semaphore::get(size_t ms) {
06583         if (WaitForSingleObject(id, (ms ? ms : INFINITE)) == WAIT_FAILED)
06584                 return true;
06585         else return false;
06586 }
06587 bool proc::semaphore::tryget() { return !WaitForSingleObject(id, 0); }
06588 bool proc::semaphore::ret() { return ReleaseSemaphore(id, 1, 0); }
06589 
06590 HANDLE mksem(const char* name, size_t count) { string s = name; s -= "Global\\"; return CreateSemaphore(NULL, count, UINT_MAX, s); }
06591 
06592 #else
06593 
06594 
06595 proc::semaphore::semaphore(size_t count) { init(count); }
06596 proc::semaphore::semaphore(const char* name) { open(name); }
06597 proc::semaphore::~semaphore() { if (id) if (named) { sem_close(id); } else { sem_destroy(id); } }
06598 bool proc::semaphore::init(size_t count) { named = false; id = &s; return !sem_init(id, 0, count); }
06599 bool proc::semaphore::die() { return !sem_destroy(id); }
06600 bool proc::semaphore::close() { return !sem_close(id); }
06601 bool proc::semaphore::open(const char* name) {
06602         named = true;
06603         char* n = (char*)malloc(strlen(name) + 2);
06604         n[0] = '/';
06605         n[1] = 0;
06606         strcat(n, name);
06607         if ((id = sem_open(n, 0)) == SEM_FAILED) id = 0;
06608         free(n);
06609         if (!id) return false;
06610         else return true;
06611 }
06612 bool proc::semaphore::get(size_t ms) {
06613         struct timespec t;
06614         if (!ms) return !sem_wait(id);
06615         else {
06616                 t.tv_sec = ms / 1000;
06617                 t.tv_nsec = (ms % 1000) * (1000 * 1000);
06618                 return !sem_timedwait(id, &t);
06619         }
06620 }
06621 bool proc::semaphore::tryget() { return !sem_trywait(id); }
06622 bool proc::semaphore::ret() { return !sem_post(id); }
06623 
06624 sem_t* proc::mksem(const char* name, size_t count) {
06625         sem_t* s;
06626         char* n = (char*)malloc(strlen(name) + 2);
06627         n[0] = '/';
06628         n[1] = 0;
06629         strcat(n, name);
06630         if ((s = sem_open(n, O_CREAT, O_EXCL, 0666, count)) == SEM_FAILED) {
06631                 free(n);
06632                 return NULL;
06633         } else { free(n); return s; }
06634 }
06635 bool proc::rmsem(const char* name) { return !sem_unlink(name); }
06636 #endif
06637 
06641 string io::input::drink(const char* eol) {
06642         string s;
06643         if (!eol) eol = "\0";
06644         if (!strlen(eol)) {
06645                 register int i;
06646                 for (i = getc(); ok(); i = getc()) { if (!i) break; s += (char)i; }
06647                 return s;
06648         }
06649         until (s.ends(eol)) s += getc();
06650         return s;
06651 }
06652 
06656 data io::input::suck(const char* eol, size_t len) {
06657         if (!len) len = strlen(eol);
06658         data d;
06659         size_t i;
06660         for (i = 0; i < len; i++) d << getc();
06661         return d;
06662 }
06663 
06664 bool fs::file::operator! () {
06665         if (!fd) return true;
06666         if (eof() | dead()) return true;
06667         if (feof(fd)) { drain(); return true; }
06668         if (ferror(fd)) { kill(); return true; }
06669         return false;
06670 }
06674 data io::input::dump() {
06675         data d;
06676         int i;
06677         if (eof()) return d;
06678         size_t a;
06679         for (a = 0;; a++) {
06680                 i = getc();
06681                 if (!ok()) break;
06682                 d.putc(i);
06683         }
06684         return d;
06685 }
06686 
06691 size_t io::output::write(data d) { return write(d.buf, 1, d.len()); }
06692 
06693 //string proc::environment::type() { return string("proc::environ"); }
06694 
06695 bool proc::pstream::open(const char* program, const char* argv, environment envp) {
06696         data d = envp.bake();
06697         return open(program, argv, (void*)d.buf);
06698 }
06699 bool proc::pstream::open(const char* program, const char* argv, data d) {
06700         return open(program, argv, (void*)d.buf);
06701 }
06702 #ifndef _WIN32
06703 bool proc::pstream::open(const char* program, const char* argv, void* envp) {
06704         if (!fs::fexist(program)) { kill(); return false; }
06705         string gay = program;
06706         if (argv) gay = gay.cat(' ').cat(argv);
06707         wordexp_t we;
06708         char **w;
06709         wordexp(gay, &we, WRDE_NOCMD);
06710         w = we.we_wordv;
06711         char *const e[] = {NULL};
06712         pname = program;
06713         pipe(rpipe);
06714         pipe(wpipe);
06715         p = fork();
06716         if (!p) {
06717                 ::close(rpipe[0]);
06718                 ::close(wpipe[1]);
06719                 dup2(wpipe[0], 0); ::close(wpipe[0]);
06720                 dup2(rpipe[1], 1); ::close(rpipe[1]);
06721                 if (!envp) execve(program, w, e);
06722                 else execve(program, w, (char* *const)envp);
06723                 wordfree(&we);
06724         } else {
06725                 wordfree(&we);
06726                 ::close(wpipe[0]);
06727                 ::close(rpipe[1]);
06728                 return true;
06729         }
06730 }
06731 #else
06732 bool proc::pstream::open(const char* program, const char* argv, void* envp) {
06733         if (!fs::fexist(program)) { kill(); return false; }
06734         pname = program;
06735         string args = program;
06736         fs::file f;
06737         string s;
06738         f.open(program, "rb");
06739         if (f.getc() == '#')
06740                 if (f.getc() == '!') {
06741                         s = f.gets().strip();
06742                         pname = s;
06743                         if (pname.chr(' ') != -1) {
06744                                 pname = pname.burn(' ');
06745                                 args = pname;
06746                                 args += ' ';
06747                                 args += s.slurp(' ');
06748                                 args += ' ';
06749                                 args += program;
06750                         }
06751                 }
06752         f.close();
06753         if (argv) args = args.cat(' ').cat(argv);
06754         con << pname << ' ' << args << '\n';
06755         CreatePipe(&rin, &win, NULL, 0);
06756         CreatePipe(&rout, &wout, NULL, 0);
06757         CreatePipe(&rerr, &werr, NULL, 0);
06758         SetHandleInformation(rin, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
06759         SetHandleInformation(wout, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
06760         SetHandleInformation(werr, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
06761         STARTUPINFOA si;
06762         PROCESS_INFORMATION pi;
06763         memset(&si, 0, sizeof(STARTUPINFOA));
06764         si.cb = sizeof(STARTUPINFOA);
06765         si.dwFlags = STARTF_USESTDHANDLES;
06766         si.hStdInput = rin;
06767         si.hStdOutput = wout;
06768         si.hStdError = werr;
06769         if (!CreateProcessA(pname, args, NULL, NULL, true, NORMAL_PRIORITY_CLASS, envp, NULL, &si, &pi)) return false;
06770         p = pi.dwProcessId;
06771         ph = pi.hProcess;
06772         Sleep(200);
06773         return true;
06774 }
06775 #endif
06776 
06777 string proc::pstream::name() { return pname; }
06778 
06782 data io::input::read(size_t size, size_t nmemb) {
06783         data d;
06784         d.realloc(size * nmemb);
06785         read(d.buf, size, nmemb);
06786         return d;
06787 }
06788 
06789 data net::socket::tcp::dump() {
06790         data d;
06791         char c;
06792         if (eof()) return d;
06793         for (;;) {
06794                 if (ready()) {
06795                         switch (::recv(fd, &c, 1, 0)) {
06796                         case 0: drain(); return d;
06797                         case -1: kill(); return d;
06798                         case 1: d << c;
06799                         }
06800                 } else return d;
06801         }
06802 }
06803 
06804 void proc::pstream::close() {
06805         pname.clear();
06806 #ifndef _WIN32
06807         ::close(wpipe[0]); ::close(wpipe[1]);
06808         ::close(rpipe[0]); ::close(rpipe[1]);
06809         ::waitpid(p, NULL, 0);
06810 #else
06811         CloseHandle(rin); CloseHandle(rout);
06812         CloseHandle(win); CloseHandle(wout);
06813         DWORD d;
06814         GetExitCodeProcess(ph, &d);
06815 #endif
06816 }
06817 size_t proc::pstream::pid() { return p; }
06818 int proc::pstream::getc() {
06819         register int i;
06820         char c;
06821 #ifndef _WIN32
06822         struct pollfd pf;
06823 #else
06824         DWORD avail = 0, bleft, bread;
06825 #endif
06826 #ifndef _WIN32
06827         pf.fd = rpipe[0];
06828         pf.events = POLLIN;
06829         poll(&pf, 1, 0);
06830         if (pf.revents & POLLIN == 0) {
06831                 if (lsproc().str(this->operator string()) == -1) { kill(); return EOF; }
06832                 if (!blocking) { drain(); return EOF; }
06833         }
06834 #else
06835         PeekNamedPipe(rout, &c, 1, &bread, &avail, &bleft);
06836         if (avail <= 0) { 
06837                 if (lsproc().str(this->operator string()) == -1) { kill(); return EOF; }
06838                 if (!blocking) { drain(); return EOF; }
06839         }
06840 #endif
06841 #ifndef _WIN32
06842         switch (::read(rpipe[0], &c, 1)) {
06843         case 0: drain(); return EOF;
06844         case -1: kill(); return EOF;
06845         default: heal(); i = c; return i;
06846         }
06847 #else
06848         if (ReadFile(rout, &c, 1, &bread, 0) != 0) {
06849                 if (bread == 0) { drain(); return EOF; } heal(); i = c; return i;
06850         } else { kill(); return EOF; }
06851 #endif
06852 }
06853 
06854 proc::pstream::pstream() { blocking = true; }
06855 
06856 int proc::pstream::putc(int c) {
06857         register char i = c;
06858 #ifndef _WIN32
06859         switch (::write(wpipe[1], &i, 1)) {
06860         case 0: drain(); return EOF;
06861         case -1: kill(); return EOF;
06862         case 1: heal(); fsync(wpipe[1]); return i;
06863         }
06864 #else
06865         DWORD bwrite;
06866         if (WriteFile(win, &i, 1, &bwrite, 0) != 0) {
06867                 if (bwrite == 0) { drain(); return EOF; } heal(); FlushFileBuffers(win); return i;
06868         } else { kill(); return EOF; }
06869 #endif
06870 }
06871 
06872 string proc::pstream::type() { return string("proc::pstream"); }
06873 proc::pstream::operator string () { string s; s << p; s << ':'; s << pname; return s; }
06874 
06875 namespace net {
06876 namespace http {
06877 
06878 field::field(const char* s) { this->operator=(s); }
06879 string field::type() { return string("net::http::field"); }
06880 field::operator string () {
06881         string s = name;
06882         s += ": ";
06883         std::deque<svarpair>::iterator it;
06884         for (it = svars.begin(); it < svars.end(); it++) {
06885                 if (it->v.empty()) { svars.erase(it); it--; continue; }
06886                 if (it->n.len()) {
06887                         s += it->n;
06888                         s += '=';
06889                 }
06890                 s += it->v;
06891                 s += "; ";
06892         }
06893         s = s.chomp("; ");
06894         return s;
06895 }
06896 
06897 string& field::var(const char* s) {
06898         if (s == 0 && svars.size()) return svars[0].v;
06899         std::deque<svarpair>::iterator it;
06900         svarpair svp;
06901         for (it = svars.begin(); it < svars.end(); it++)
06902                 if (it->n == s) return it->v;
06903         if (it == svars.end()) {
06904                 if (s) svp.n = string(s);
06905                 else svp.n = string();
06906                 svp.v = string();
06907                 svars.push_back(svp);
06908                 return svars.back().v;
06909         }
06910 }
06911 
06912 string& field::operator[] (const char* v) {
06913         if (v == 0) return var();
06914         return var(v);
06915 }
06916 
06917 string field::vars() {
06918         string s;
06919         std::deque<svarpair>::iterator it;
06920         for (it = svars.begin() + 1; it < svars.end(); it++) {
06921                 s += it->n;
06922                 s += '\n';
06923         }
06924         return s;
06925 }
06926 
06927 field& field::operator= (const char* s) {
06928         if (strstr(s, ": ") != 0) {
06929                 name = s;
06930                 name = name.burn(": ");
06931                 s = strstr(s, ": ") + 2;
06932         }
06933         svars.clear();
06934         svarpair svp;
06935         if (strstr(s, "; ") == 0) {
06936                 svp.v = s;
06937                 svars.push_back(svp);
06938                 return *this;
06939         }
06940         std::deque<string> t = string(s).split(' ');
06941         std::deque<string>::iterator it;
06942         for (it = t.begin(); it < t.end(); it++)
06943                 if (it->chr('=') == -1) {
06944                         svp.v = it->burn(';').rtrim();
06945                         svars.push_back(svp);
06946                  } else {
06947                         svp.n = it->burn('=');
06948                         svp.v = it->slurp('=').burn(';').rtrim();
06949                         svars.push_back(svp);
06950                  }
06951         return *this;
06952 }
06953 
06954 string query::type() { return string("net::http::query"); }
06955 query::operator string() {
06956         string s;
06957         std::deque<svarpair>::iterator it;
06958         for (it = svars.begin(); it < svars.end(); it++) {
06959                 if (it->v.empty()) { svars.erase(it); it--; continue; }
06960                 s += it->n;
06961                 s += '=';
06962                 s += it->v;
06963                 s += '&';
06964         }
06965         s = s.chomp('&');
06966         return s;
06967 }
06968 string query::vars() {
06969         string s;
06970         std::deque<svarpair>::iterator it;
06971         for (it = svars.begin(); it < svars.end(); it++) {
06972                 s += it->n;
06973                 s += '\n';
06974         }
06975         return s;
06976 }
06977 string& query::var(const char* v) {
06978         svarpair svp;
06979         std::deque<svarpair>::iterator it;
06980         for (it = svars.begin(); it < svars.end(); it++)
06981                 if (it->n == v) return it->v;
06982         svp.n = v;
06983         svp.v = string();
06984         svars.push_back(svp);
06985         return svars.back().v;
06986 }
06987 string& query::operator[] (const char* s) { return var(s); }
06988 query& query::operator= (const char* s) {
06989         svars.clear();
06990         svarpair svp;
06991         std::deque<string> t = string(s).split('&');
06992         std::deque<string>::iterator it;
06993         for (it = t.begin(); it < t.end(); it++) {
06994                 svp.n = it->tok(0, '=');
06995                 svp.v = it->tok(1, '=');
06996                 svars.push_back(svp);
06997         }
06998         return *this;
06999 }
07000 query::query(const char* s) { this->operator=(s); }
07001 
07002 request& request::operator= (const char* s) {
07003         string t = s;
07004         t = t.chomp();
07005         method = t.tok(0, ' ').uc();
07006         file = t.tok(1, ' ').burn('?');
07007         if (t.tok(1, ' ').chr('?') == -1) qstr.clear();
07008         else qstr = t.tok(1, ' ').slurp('?');
07009         ver = atof(t.tok(2, ' ').slurp('/'));   
07010         return *this;
07011 }
07012 
07013 string request::type() { return string("net::http::request"); }
07014 request::operator string () {
07015         string s;
07016         s << method << ' ' << file;
07017         if (qstr.len()) s << '?' << qstr;
07018         s << " HTTP/" << ver;
07019         return s;
07020 }
07021 
07022 string response::type() { return string("net::http::response"); }
07023 response::operator string () {
07024         string s;
07025         s << "HTTP/" << ver << ' ' << code << ' ' << status << "\r\n";
07026         return s;
07027 }
07028 response& response::operator= (const char* s) {
07029         string t = s;
07030         ver = atof(t.slurp('/'));
07031         code = atoi(t.tok(1, ' '));
07032         status = t.shl(t.itok(2, ' ')).rtrim();
07033         return *this;
07034 }
07035 
07036 string header::type() { return string("net::http::header"); }
07037 field& header::at(size_t i) {
07038         return f[i];
07039 }
07040 header::operator string () {
07041         string s;
07042         std::deque<field>::iterator it;
07043         for (it = f.begin(); it < f.end(); it++) {
07044                 if (it->var().empty()) { f.erase(it); it--; continue; }
07045                 if (it->name.empty()) { f.erase(it); it--; continue; }
07046                 s = s.cat(it->operator string()).cat("\r\n");
07047         }
07048         s += "\r\n";
07049         return s;
07050 }
07051 string field::data() { return (this->operator string()).slurp(": ").rtrim(); }
07052 field& header::var(const char* s) {
07053         std::deque<field>::iterator it;
07054         for (it = f.begin(); it < f.end(); it++)
07055                 if (it->name == s) return *it;
07056         field t;
07057         t.name = s;
07058         f.push_back(t);
07059         return f.back();
07060 }
07061 size_t header::len() { return f.size(); }
07062 string header::vars() {
07063         string s;
07064         std::deque<field>::iterator it;
07065         for (it = f.begin(); it < f.end(); it++) {
07066                 if (it->name.empty()) { f.erase(it); it--; continue; }
07067                 s += it->name;
07068                 s += '\n';
07069         }
07070         return s;
07071 }
07072 field& header::operator[] (const char* s) { return var(s); }
07073 header::header(const char* s) { this->operator=(s); }
07074 header& header::clear() {
07075         f.clear();
07076         return *this;
07077 }
07078 header& header::operator= (const char* s) {
07079         f.clear();
07080         std::deque<string> t = string(s).rtrim().split('\n');
07081         std::deque<string>::iterator it;
07082         for (it = t.begin(); it < t.end(); it++) {
07083                 if (it->chr(':') != -1)
07084                         f.push_back(field(it->rtrim().buf));
07085         }
07086         return *this;
07087 }
07088 //header::operator const char* () { i = this->operator string (); return i.buf; }
07089 bool header::operator== (const char* s) { return this->operator string().operator==(s); }
07090 bool header::operator== (header h) { return this->operator string().operator==(h.operator string ()); }
07091 bool header::operator!= (const char* s) { return !this->operator==(s); }
07092 bool header::operator!= (header h) { return !this->operator==(h); }
07093 bool response::operator== (const char* s) { return this->operator string().operator==(s); }
07094 bool response::operator== (response h) { return this->operator string().operator==(h.operator string ()); }
07095 bool response::operator!= (const char* s) { return !this->operator==(s); }
07096 bool response::operator!= (response h) { return !this->operator==(h); }
07097 bool request::operator== (const char* s) { return this->operator string().operator==(s); }
07098 bool request::operator== (request h) { return this->operator string().operator==(h.operator string ()); }
07099 bool request::operator!= (const char* s) { return !this->operator==(s); }
07100 bool request::operator!= (request h) { return !this->operator==(h); }
07101 bool field::operator== (const char* s) { return this->operator string().operator==(s); }
07102 bool field::operator== (field h) { return this->operator string().operator==(h.operator string ()); }
07103 bool field::operator!= (const char* s) { return !this->operator==(s); }
07104 bool field::operator!= (field h) { return !this->operator==(h); }
07105 bool query::operator== (const char* s) { return this->operator string().operator==(s); }
07106 bool query::operator== (query h) { return this->operator string().operator==(h.operator string ()); }
07107 bool query::operator!= (const char* s) { return !this->operator==(s); }
07108 bool query::operator!= (query h) { return !this->operator==(h); }
07109 
07110 };
07111 };
07112 
07113 #ifdef _WIN32
07114 int net::socket::tcp::wsatoerr(int i) {
07115         switch (i) {
07116         case WSA_INVALID_HANDLE: return EINVAL;
07117         case WSA_NOT_ENOUGH_MEMORY: return ENOMEM;
07118         case WSA_INVALID_PARAMETER: return EINVAL;
07119         case WSA_OPERATION_ABORTED: return EINTR;
07120         case WSA_IO_INCOMPLETE: return EBUSY;
07121         case WSA_IO_PENDING: return EBUSY;
07122         case WSAEINTR: return EINTR;
07123         case WSAEBADF: return EBADF;
07124         case WSAEACCES: return EACCES;
07125         case WSAEFAULT: return EFAULT;
07126         case WSAEINVAL: return EINVAL;
07127         case WSAEMFILE: return EMFILE;
07128         case WSAEWOULDBLOCK: return EAGAIN;
07129         case WSAEINPROGRESS: return EINPROGRESS;
07130         case WSAEALREADY: return EALREADY;
07131         case WSAENOTSOCK: return ENOTSOCK;
07132         case WSAEDESTADDRREQ: return EDESTADDRREQ;
07133         case WSAEMSGSIZE: return EMSGSIZE;
07134         case WSAEPROTOTYPE: return EPROTOTYPE;
07135         case WSAENOPROTOOPT: return ENOPROTOOPT;
07136         case WSAEPROTONOSUPPORT: return EPROTONOSUPPORT;
07137         case WSAESOCKTNOSUPPORT: return ENOTSUP;
07138         case WSAEOPNOTSUPP: return ENOTSUP;
07139         case WSAEPFNOSUPPORT: return EAFNOSUPPORT;
07140         case WSAEAFNOSUPPORT: return EAFNOSUPPORT;
07141         case WSAEADDRINUSE: return EADDRINUSE;
07142         case WSAEADDRNOTAVAIL: return EADDRNOTAVAIL;
07143         case WSAENETDOWN: return ENETDOWN;
07144         case WSAENETUNREACH: return ENETUNREACH;
07145         case WSAENETRESET: return ENETRESET;
07146         case WSAECONNABORTED: return ECONNABORTED;
07147         case WSAECONNREFUSED: return ECONNREFUSED;
07148         case WSAENOBUFS: return ENOBUFS;
07149         case WSAENOTCONN: return ENOTCONN;
07150         case WSAESHUTDOWN: return EIO;
07151         case WSAETOOMANYREFS: return EMLINK;
07152         case WSAETIMEDOUT: return ETIMEDOUT;
07153         case WSAELOOP: return ELOOP;
07154         case WSAENAMETOOLONG: return ENAMETOOLONG;
07155         case WSAEHOSTUNREACH: return EHOSTUNREACH;
07156         case WSAENOTEMPTY: return ENOTEMPTY;
07157         case WSAEPROCLIM: return EMFILE;
07158         case WSAEUSERS: return ENOMEM;
07159         case WSAEDQUOT: return ENOMEM;
07160         case WSAESTALE: return EBADF;
07161         case WSAEREMOTE: return ENOENT;
07162         case WSASYSNOTREADY: return EBUSY;
07163         case WSAVERNOTSUPPORTED: return ENOTSUP;
07164         case WSANOTINITIALISED: return EPERM;
07165         case WSAEDISCON: return ECANCELED;
07166         case WSAENOMORE: return ENOENT;
07167         case WSAECANCELLED: return ECANCELED;
07168         case WSAEINVALIDPROCTABLE: return EINVAL;
07169         case WSAEINVALIDPROVIDER: return EINVAL;
07170         case WSAEPROVIDERFAILEDINIT: return EINTR;
07171         case WSASYSCALLFAILURE: return EINTR;
07172         case WSASERVICE_NOT_FOUND: return ENOENT;
07173         case WSATYPE_NOT_FOUND: return ENOENT;
07174         case WSA_E_NO_MORE: return ENOENT;
07175         case WSA_E_CANCELLED: return ECANCELED;
07176         case WSAEREFUSED: return ECONNREFUSED;
07177         case WSAHOST_NOT_FOUND: return EHOSTUNREACH;
07178         case WSATRY_AGAIN: return EAGAIN;
07179         case WSANO_RECOVERY: return ENOTRECOVERABLE;
07180         case WSANO_DATA: return ENODATA;
07181         default: return 0;
07182         }
07183 }
07184 #endif
07185 
07186 string object::tostr() { return this->operator string(); }
07187 
07188 };
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Defines