Index: libroar/error.c
===================================================================
--- libroar/error.c	(revision 5540)
+++ libroar/error.c	(revision 5544)
@@ -216,4 +216,9 @@
  } else if ( !roar_err_is_errno_clear() ) {
   roar_err_from_errno();
+#ifdef ROAR_TARGET_WIN32
+ } else {
+  roar_err_convert(err, ROAR_ERROR_TYPE_ROARAUDIO, WSAGetLastError(), ROAR_ERROR_TYPE_WINSOCK);
+  roar_err_to_errno();
+#endif
  }
 }
@@ -227,8 +232,8 @@
 }
 
-void   roar_err_from_errno(void) {
+static int   __errno_to_roar(int error) {
  int _roar_errno = ROAR_ERROR_NONE;
 
- switch (errno) {
+ switch (error) {
 #ifdef EACCES
   case EACCES:       _roar_errno = ROAR_ERROR_PERM; break;
@@ -455,101 +460,104 @@
  }
 
- roar_err_set(_roar_errno);
-}
-
-void   roar_err_to_errno(void) {
- int * err = roar_errno2();
- switch (*err) {
+ return _roar_errno;
+}
+
+void   roar_err_from_errno(void) {
+ roar_err_set(__errno_to_roar(errno));
+}
+
+static int   __roar_to_errno(int error) {
+ switch (error) {
   case ROAR_ERROR_NONE:
-    roar_err_clear_errno();
+    return CLEAN_ERRNO;
    break;
 #ifdef EPERM
   case ROAR_ERROR_PERM:
-    errno = EPERM;
+    return EPERM;
    break;
 #endif
 #ifdef ENOENT
   case ROAR_ERROR_NOENT:
-    errno = ENOENT;
+    return ENOENT;
    break;
 #endif
 #ifdef EBADMSG
   case ROAR_ERROR_BADMSG:
-    errno = EBADMSG;
+    return EBADMSG;
    break;
 #endif
 #ifdef EBUSY
   case ROAR_ERROR_BUSY:
-    errno = EBUSY;
+    return EBUSY;
    break;
 #endif
 #ifdef ECONNREFUSED
   case ROAR_ERROR_CONNREFUSED:
-    errno = ECONNREFUSED;
+    return ECONNREFUSED;
    break;
 #endif
 #ifdef ENOSYS
   case ROAR_ERROR_NOSYS:
-    errno = ENOSYS;
+    return ENOSYS;
    break;
 #endif
 #ifdef ENOTSUP
   case ROAR_ERROR_NOTSUP:
-    errno = ENOTSUP;
+    return ENOTSUP;
    break;
 #endif
 #ifdef EPIPE
   case ROAR_ERROR_PIPE:
-    errno = EPIPE;
+    return EPIPE;
    break;
 #endif
 #ifdef EPROTO
   case ROAR_ERROR_PROTO:
-    errno = EPROTO;
+    return EPROTO;
    break;
 #endif
 #ifdef ERANGE
   case ROAR_ERROR_RANGE:
-    errno = ERANGE;
+    return ERANGE;
    break;
 #endif
 #ifdef EMSGSIZE
   case ROAR_ERROR_MSGSIZE:
-    errno = EMSGSIZE;
+    return EMSGSIZE;
    break;
 #endif
 #ifdef ENOMEM
   case ROAR_ERROR_NOMEM:
-    errno = ENOMEM;
+    return ENOMEM;
    break;
 #endif
 #ifdef EINVAL
   case ROAR_ERROR_INVAL:
-    errno = EINVAL;
+    return EINVAL;
    break;
 #endif
 #ifdef EALREADY
   case ROAR_ERROR_ALREADY:
-    errno = EALREADY;
+    return EALREADY;
    break;
 #endif
 #ifdef EBADRQC
   case ROAR_ERROR_BADRQC:
-    errno = EBADRQC;
+    return EBADRQC;
    break;
 #endif
 #ifdef EDOM
   case ROAR_ERROR_DOM:
-    errno = EDOM;
+    return EDOM;
    break;
 #endif
 #ifdef EEXIST
   case ROAR_ERROR_EXIST:
-    errno = EEXIST;
+    return EEXIST;
    break;
 #endif
 #ifdef EFAULT
   case ROAR_ERROR_FAULT:
-    errno = EFAULT;
+    return EFAULT;
    break;
 #endif
@@ -557,7 +565,7 @@
   case ROAR_ERROR_RIO:
 #ifdef EREMOTEIO
-    errno = EREMOTEIO;
+    return EREMOTEIO;
 #else
-    errno = EIO;
+    return EIO;
 #endif
    break;
@@ -569,35 +577,35 @@
   case ROAR_ERROR_LOSTSYNC:
   case ROAR_ERROR_NOHORSE:
-    errno = EIO;
+    return EIO;
    break;
 #endif
 #ifdef EKEYEXPIRED
   case ROAR_ERROR_KEYEXPIRED:
-    errno = EKEYEXPIRED;
+    return EKEYEXPIRED;
    break;
 #endif
 #ifdef EKEYREJECTED
   case ROAR_ERROR_KEYREJECTED:
-    errno = EKEYREJECTED;
+    return EKEYREJECTED;
    break;
 #endif
 #ifdef ELOOP
   case ROAR_ERROR_LOOP:
-    errno = ELOOP;
+    return ELOOP;
    break;
 #endif
 #ifdef EMFILE
   case ROAR_ERROR_MFILE:
-    errno = EMFILE;
+    return EMFILE;
    break;
 #endif
 #ifdef ENAMETOOLONG
   case ROAR_ERROR_NAMETOOLONG:
-    errno = ENAMETOOLONG;
+    return ENAMETOOLONG;
    break;
 #endif
 #ifdef ENODATA
   case ROAR_ERROR_NODATA:
-    errno = ENODATA;
+    return ENODATA;
    break;
 #endif
@@ -605,85 +613,85 @@
   case ROAR_ERROR_NODEV:
   case ROAR_ERROR_NODRV:
-    errno = ENODEV;
+    return ENODEV;
    break;
 #endif
 #ifdef ENOSPC
   case ROAR_ERROR_NOSPC:
-    errno = ENOSPC;
+    return ENOSPC;
    break;
 #endif
 #ifdef EINVAL
   case ROAR_ERROR_TYPEMM:
-    errno = EINVAL;
+    return EINVAL;
    break;
 #endif
 #ifdef ENOSYS
   case ROAR_ERROR_NORSYS:
-    errno = ENOSYS;
+    return ENOSYS;
    break;
 #endif
 #ifdef ENOTCONN
   case ROAR_ERROR_NOTCONN:
-    errno = ENOTCONN;
+    return ENOTCONN;
    break;
 #endif
 #ifdef EPROTONOSUPPORT
   case ROAR_ERROR_PROTONOSUP:
-    errno = EPROTONOSUPPORT;
+    return EPROTONOSUPPORT;
    break;
 #endif
 #ifdef EROFS
   case ROAR_ERROR_RO:
-    errno = EROFS;
+    return EROFS;
    break;
 #endif
 #ifdef ETIMEDOUT
   case ROAR_ERROR_TIMEDOUT:
-    errno = ETIMEDOUT;
+    return ETIMEDOUT;
    break;
 #endif
 #ifdef EAGAIN
   case ROAR_ERROR_AGAIN:
-    errno = EAGAIN;
+    return EAGAIN;
    break;
 #endif
 #ifdef ENETDOWN
   case ROAR_ERROR_LINKDOWN:
-    errno = ENETDOWN;
+    return ENETDOWN;
    break;
 #endif
 #ifdef EINTR
   case ROAR_ERROR_INTERRUPTED:
-    errno = EINTR;
+    return EINTR;
    break;
 #endif
 #ifdef EDQUOT
   case ROAR_ERROR_QUOTA:
-    errno = EDQUOT;
+    return EDQUOT;
    break;
 #endif
 #ifdef ELIBBAD
   case ROAR_ERROR_BADLIB:
-    errno = ELIBBAD;
+    return ELIBBAD;
    break;
 #endif
 #ifdef ENOMEDIUM
   case ROAR_ERROR_NOMEDIUM:
-    errno = ENOMEDIUM;
+    return ENOMEDIUM;
    break;
 #endif
 #ifdef ENOTUNIQ
   case ROAR_ERROR_NOTUNIQ:
-    errno = ENOTUNIQ;
+    return ENOTUNIQ;
    break;
 #endif
 #ifdef EILSEQ
   case ROAR_ERROR_ILLSEQ:
-    errno = EILSEQ;
+    return EILSEQ;
    break;
 #endif
 #ifdef EADDRINUSE
   case ROAR_ERROR_ADDRINUSE:
-    errno = EADDRINUSE;
+    return EADDRINUSE;
    break;
 #endif
@@ -691,120 +699,120 @@
   case ROAR_ERROR_BADSEEK:
   case ROAR_ERROR_NOSEEK:
-    errno = ESPIPE;
+    return ESPIPE;
    break;
 #endif
 #ifdef ECHERNOBYL
   case ROAR_ERROR_CHERNOBYL:
-    errno = ECHERNOBYL;
+    return ECHERNOBYL;
    break;
 #endif
 #ifdef ECRAY
   case ROAR_ERROR_CAUSALITY:
-    errno = ECRAY;
+    return ECRAY;
    break;
 #endif
 #ifdef ENOHORSE
   case ROAR_ERROR_NOHORSE:
-    errno = ENOHORSE;
+    return ENOHORSE;
    break;
 #endif
 #ifdef ETXTBSY
   case ROAR_ERROR_TEXTBUSY:
-    errno = ETXTBSY;
+    return ETXTBSY;
    break;
 #endif
 #ifdef ENOTEMPTY
   case ROAR_ERROR_NOTEMPTY:
-    errno = ENOTEMPTY;
+    return ENOTEMPTY;
    break;
 #endif
 #ifdef EHOSTUNREACH
   case ROAR_ERROR_NODEUNREACH:
-    errno = EHOSTUNREACH;
+    return EHOSTUNREACH;
    break;
 #endif
 #ifdef EIDRM
   case ROAR_ERROR_IDREMOVED:
-    errno = EIDRM;
+    return EIDRM;
    break;
 #endif
 #ifdef EINPROGRESS
   case ROAR_ERROR_INPROGRESS:
-    errno = EINPROGRESS;
+    return EINPROGRESS;
    break;
 #endif
 #ifdef ECHILD
   case ROAR_ERROR_NOCHILD:
-    errno = ECHILD;
+    return ECHILD;
    break;
 #endif
 #ifdef ENETUNREACH
   case ROAR_ERROR_NETUNREACH:
-    errno = ENETUNREACH;
+    return ENETUNREACH;
    break;
 #endif
 #ifdef ECANCELED
   case ROAR_ERROR_CANCELED:
-    errno = ECANCELED;
+    return ECANCELED;
    break;
 #endif
 #ifdef EISDIR
   case ROAR_ERROR_ISDIR:
-    errno = EISDIR;
+    return EISDIR;
    break;
 #endif
 #ifdef ENOTDOR
   case ROAR_ERROR_NOTDIR:
-    errno = ENOTDIR;
+    return ENOTDIR;
    break;
 #endif
 #ifdef ENOEXEC
   case ROAR_ERROR_BADEXEC:
-    errno = ENOEXEC;
+    return ENOEXEC;
    break;
 #endif
 #ifdef EISCONN
   case ROAR_ERROR_ISCONN:
-    errno = EISCONN;
+    return EISCONN;
    break;
 #endif
 #ifdef EDEADLK
   case ROAR_ERROR_DEADLOCK:
-    errno = EDEADLK;
+    return EDEADLK;
    break;
 #endif
 #ifdef ECONNRESET
   case ROAR_ERROR_CONNRST:
-    errno = ECONNRESET;
+    return ECONNRESET;
    break;
 #endif
 #ifdef EBADF
   case ROAR_ERROR_BADFH:
-    errno = EBADF;
+    return EBADF;
    break;
 #endif
 #ifdef ENOTSOCK
   case ROAR_ERROR_NOTSOCK:
-    errno = ENOTSOCK;
+    return ENOTSOCK;
    break;
 #endif
 #ifdef E2BIG
   case ROAR_ERROR_TOOMANYARGS:
-    errno = E2BIG;
+    return E2BIG;
    break;
 #endif
 #ifdef EFBIG
   case ROAR_ERROR_TOOLARGE:
-    errno = EFBIG;
+    return EFBIG;
    break;
 #endif
 #ifdef EDESTADDRREQ
   case ROAR_ERROR_DESTADDRREQ:
-    errno = EDESTADDRREQ;
+    return EDESTADDRREQ;
    break;
 #endif
 #ifdef EAFNOSUPPORT
   case ROAR_ERROR_AFNOTSUP:
-    errno = EAFNOSUPPORT;
+    return EAFNOSUPPORT;
    break;
 #endif
@@ -812,10 +820,10 @@
 #ifdef ENOPOWER
   case ROAR_ERROR_NOPOWER:
-    errno = ENOPOWER;
+    return ENOPOWER;
    break;
 #endif
 #ifdef EUSER
   case ROAR_ERROR_USER:
-    errno = EUSER;
+    return EUSER;
    break;
 #endif
@@ -823,35 +831,35 @@
 #ifdef ENFILE
   case ROAR_ERROR_NFILE:
-    errno = ENFILE;
+    return ENFILE;
    break;
 #endif
 #ifdef ESTALE
   case ROAR_ERROR_STALE:
-    errno = ESTALE;
+    return ESTALE;
    break;
 #endif
 #ifdef EXDEV
   case ROAR_ERROR_XDEVLINK:
-    errno = EXDEV;
+    return EXDEV;
    break;
 #endif
 #ifdef EMLINK
   case ROAR_ERROR_MLINK:
-    errno = EMLINK;
+    return EMLINK;
    break;
 #endif
 #ifdef ENONET
   case ROAR_ERROR_NONET:
-    errno = ENONET;
+    return ENONET;
    break;
 #endif
 #ifdef ENETRESET
   case ROAR_ERROR_CONNRSTNET:
-    errno = ENETRESET;
+    return ENETRESET;
    break;
 #endif
 #ifdef ECONNABORTED
   case ROAR_ERROR_CONNABORTED:
-    errno = ECONNABORTED;
+    return ECONNABORTED;
    break;
 #endif
@@ -859,10 +867,271 @@
   default:
 #ifdef EINVAL
-    errno = EINVAL;
+    return EINVAL;
 #else
-    errno = -1; // just guess
-#endif
-   break;
- }
+    return -1; // just guess
+#endif
+   break;
+ }
+}
+
+void   roar_err_to_errno(void) {
+ errno = __roar_to_errno(roar_error);
+}
+
+static const struct error_table_entry {
+ const enum roar_error_type type;
+ const int error;
+ const int roarerror;
+} __libroar_error_table[] = {
+ {ROAR_ERROR_TYPE_HTTP, 200, ROAR_ERROR_NONE},
+ {ROAR_ERROR_TYPE_HTTP, 301, ROAR_ERROR_MOVEDPERM},
+ {ROAR_ERROR_TYPE_HTTP, 303, ROAR_ERROR_SEEOTHER},
+ {ROAR_ERROR_TYPE_HTTP, 305, ROAR_ERROR_USEPROXY},
+ {ROAR_ERROR_TYPE_HTTP, 307, ROAR_ERROR_MOVEDTEMP},
+ {ROAR_ERROR_TYPE_HTTP, 400, ROAR_ERROR_INVAL},
+ {ROAR_ERROR_TYPE_HTTP, 403, ROAR_ERROR_PERM},
+ {ROAR_ERROR_TYPE_HTTP, 404, ROAR_ERROR_NOENT},
+ {ROAR_ERROR_TYPE_HTTP, 408, ROAR_ERROR_TIMEDOUT},
+ {ROAR_ERROR_TYPE_HTTP, 410, ROAR_ERROR_GONE},
+ {ROAR_ERROR_TYPE_HTTP, 423, ROAR_ERROR_BUSY},
+ {ROAR_ERROR_TYPE_HTTP, 426, ROAR_ERROR_SWITCHPROTO},
+ {ROAR_ERROR_TYPE_HTTP, 501, ROAR_ERROR_NOSYS},
+ {ROAR_ERROR_TYPE_HTTP, 504, ROAR_ERROR_TIMEDOUT},
+ {ROAR_ERROR_TYPE_HTTP, 505, ROAR_ERROR_NSVERSION},
+ {ROAR_ERROR_TYPE_HTTP, 507, ROAR_ERROR_NOSPC},
+#ifdef NETDB_SUCCESS
+ {ROAR_ERROR_TYPE_HERROR, NETDB_SUCCESS, ROAR_ERROR_NONE},
+#endif
+#ifdef HOST_NOT_FOUND
+ {ROAR_ERROR_TYPE_HERROR, HOST_NOT_FOUND, ROAR_ERROR_NOENT},
+#endif
+#ifdef TRY_AGAIN
+ {ROAR_ERROR_TYPE_HERROR, TRY_AGAIN, ROAR_ERROR_AGAIN},
+#endif
+#ifdef NO_RECOVERY
+// {ROAR_ERROR_TYPE_HERROR, NO_RECOVERY, ROAR_ERROR_???},
+#endif
+#ifdef NO_DATA
+ {ROAR_ERROR_TYPE_HERROR, NO_DATA, ROAR_ERROR_NODATA},
+#endif
+#ifdef NO_ADDRESS
+ {ROAR_ERROR_TYPE_HERROR, NO_ADDRESS, ROAR_ERROR_NOENT},
+#endif
+#ifdef ROAR_TARGET_WIN32
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_HANDLE, ROAR_ERROR_BADFH},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_NOT_ENOUGH_MEMORY, ROAR_ERROR_NOMEM},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_INVALID_PARAMETER, ROAR_ERROR_INVAL},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_OPERATION_ABORTED, ROAR_ERROR_INTERRUPTED},
+// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_INCOMPLETE, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSA_IO_PENDING, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEINTR, ROAR_ERROR_INTERRUPTED},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEBADF, ROAR_ERROR_BADFH},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEACCES, ROAR_ERROR_PERM},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEFAULT, ROAR_ERROR_FAULT},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEINVAL, ROAR_ERROR_INVAL},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEMFILE, ROAR_ERROR_MFILE},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEWOULDBLOCK, ROAR_ERROR_AGAIN},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEINPROGRESS, ROAR_ERROR_INPROGRESS},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEALREADY, ROAR_ERROR_ALREADY},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAENOTSOCK, ROAR_ERROR_NOTSOCK},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEDESTADDRREQ, ROAR_ERROR_DESTADDRREQ},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEMSGSIZE, ROAR_ERROR_MSGSIZE},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTOTYPE, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAENOPROTOOPT, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEPROTONOSUPPORT, ROAR_ERROR_PROTONOSUP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAESOCKTNOSUPPORT, ROAR_ERROR_PROTONOSUP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEOPNOTSUPP, ROAR_ERROR_NOTSUP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEPFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEAFNOSUPPORT, ROAR_ERROR_AFNOTSUP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRINUSE, ROAR_ERROR_ADDRINUSE},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEADDRNOTAVAIL, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAENETDOWN, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAENETUNREACH, ROAR_ERROR_NETUNREACH},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAENETRESET, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNABORTED, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAECONNRESET, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAENOBUFS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEISCONN, ROAR_ERROR_ISCONN},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAENOTCONN, ROAR_ERROR_NOTCONN},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAESHUTDOWN, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAETOOMANYREFS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAETIMEDOUT, ROAR_ERROR_TIMEDOUT},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAECONNREFUSED, ROAR_ERROR_CONNREFUSED},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAELOOP, ROAR_ERROR_LOOP},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAENAMETOOLONG, ROAR_ERROR_NAMETOOLONG},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTDOWN, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAEHOSTUNREACH, ROAR_ERROR_NODEUNREACH},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAENOTEMPTY, ROAR_ERROR_NOTEMPTY},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROCLIM, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEUSERS, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEDQUOT, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAESTALE, ROAR_ERROR_STALE},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEREMOTE, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSASYSNOTREADY, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAVERNOTSUPPORTED, ROAR_ERROR_NSVERSION},
+// {ROAR_ERROR_TYPE_WINSOCK, WSANOTINITIALISED, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEDISCON, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAENOMORE, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAECANCELLED, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROCTABLE, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEINVALIDPROVIDER, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEPROVIDERFAILEDINIT, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSASYSCALLFAILURE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSASERVICE_NOT_FOUND, ROAR_ERROR_NOENT},
+ {ROAR_ERROR_TYPE_WINSOCK, WSATYPE_NOT_FOUND, ROAR_ERROR_NOENT},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_E_NO_MORE, ROAR_ERROR_NOENT},
+// {ROAR_ERROR_TYPE_WINSOCK, WSA_E_CANCELLED, ROAR_ERROR_???},
+// {ROAR_ERROR_TYPE_WINSOCK, WSAEREFUSED, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSAHOST_NOT_FOUND, ROAR_ERROR_NOENT},
+ {ROAR_ERROR_TYPE_WINSOCK, WSATRY_AGAIN, ROAR_ERROR_AGAIN},
+// {ROAR_ERROR_TYPE_WINSOCK, WSANO_RECOVERY, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSANO_DATA, ROAR_ERROR_NODATA},
+#if 0
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RECEIVERS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_SENDERS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_SENDERS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_NO_RECEIVERS, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_REQUEST_CONFIRMED, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ADMISSION_FAILURE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_POLICY_FAILURE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_STYLE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_BAD_OBJECT, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_TRAFFIC_CTRL_ERROR, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_GENERIC_ERROR, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESERVICETYPE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWSPEC, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPROVSPECBUF, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERSTYLE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERTYPE, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFILTERCOUNT, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EOBJLENGTH, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWCOUNT, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EUNKOWNPSOBJ, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPOLICYOBJ, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EFLOWDESC, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFLOWSPEC, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_EPSFILTERSPEC, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESDMODEOBJ, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_ESHAPERATEOBJ, ROAR_ERROR_???},
+ {ROAR_ERROR_TYPE_WINSOCK, WSA_QOS_RESERVED_PETYPE, ROAR_ERROR_???},
+#endif
+#endif
+};
+
+static int roar_err_convert_table_lookup(const struct error_table_entry ** match,
+                                         const int error,
+                                         const enum roar_error_type type,
+                                         const int to_roar) {
+ size_t i;
+
+ // we have the following loop to times as an inner if() would cost more cycles
+ // than the outer if we currently have.
+
+ if ( to_roar ) {
+  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
+   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].error == error) {
+    *match = &(__libroar_error_table[i]);
+    return ROAR_ERROR_NONE;
+   }
+  }
+ } else {
+  for (i = 0; i < (sizeof(__libroar_error_table)/sizeof(*__libroar_error_table)); i++) {
+   if ( __libroar_error_table[i].type == type && __libroar_error_table[i].roarerror == error) {
+    *match = &(__libroar_error_table[i]);
+    return ROAR_ERROR_NONE;
+   }
+  }
+ }
+
+ return ROAR_ERROR_NOENT;
+}
+
+// Convert error codes between diffrent representations.
+// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
+int    roar_err_convert(int * out, const enum roar_error_type outtype, const int in, const enum roar_error_type intype) {
+ const struct error_table_entry * tablematch;
+ int tmp;
+ int ret;
+
+ if ( out == NULL )
+  return ROAR_ERROR_FAULT;
+
+ if ( outtype == intype ) {
+  *out = in;
+  return ROAR_ERROR_NONE;
+ }
+
+ // if not to/from roar, use roar as temp type so we do only need to code two kinds of translators (not any->any).
+ if ( intype != ROAR_ERROR_TYPE_ROARAUDIO && outtype != ROAR_ERROR_TYPE_ROARAUDIO ) {
+  ret = roar_err_convert(&tmp, ROAR_ERROR_TYPE_ROARAUDIO, in, intype);
+  if ( ret != ROAR_ERROR_NONE )
+   return ret;
+
+  return roar_err_convert(out, outtype, tmp, ROAR_ERROR_TYPE_ROARAUDIO);
+ }
+
+ // from here we can asume that if intype != ROAR_ERROR_TYPE_ROARAUDIO outtype is ROAR_ERROR_TYPE_ROARAUDIO
+ // and the other way around.
+
+ if ( intype == ROAR_ERROR_TYPE_ROARAUDIO ) {
+  ret = roar_err_convert_table_lookup(&tablematch, in, outtype, 0);
+ } else {
+  ret = roar_err_convert_table_lookup(&tablematch, in, intype, 1);
+ }
+
+ if ( ret == ROAR_ERROR_NONE ) {
+  *out = intype == ROAR_ERROR_TYPE_ROARAUDIO ? tablematch->error : tablematch->roarerror;
+  return ROAR_ERROR_NONE;
+ }
+
+ if ( intype == ROAR_ERROR_TYPE_ROARAUDIO && outtype == ROAR_ERROR_TYPE_ERRNO ) {
+  // the __roar_to_errno() function always succeeds.
+  *out = __roar_to_errno(in);
+  return ROAR_ERROR_NONE;
+ }
+
+ if ( outtype == ROAR_ERROR_TYPE_ROARAUDIO && intype == ROAR_ERROR_TYPE_ERRNO ) {
+  // the __errno_to_roar() function always succeeds.
+  *out = __errno_to_roar(in);
+  return ROAR_ERROR_NONE;
+ }
+
+ roar_err_get_default_error(out, outtype);
+ return ROAR_ERROR_NOENT;
+}
+
+// Outputs a default error for the given type.
+// returnes the error or ROAR_ERROR_NONE on success so it does not alter global error state.
+int    roar_err_get_default_error(int * out, const enum roar_error_type type) {
+ int is_set = 0;
+
+ if ( out == NULL )
+  return ROAR_ERROR_FAULT;
+
+ switch (type) {
+  case ROAR_ERROR_TYPE_ROARAUDIO: is_set = 1; *out = ROAR_ERROR_UNKNOWN; break;
+#ifdef EINVAL
+  case ROAR_ERROR_TYPE_ERRNO: is_set = 1; *out = EINVAL; break;
+#endif
+#ifdef NO_RECOVERY
+  case ROAR_ERROR_TYPE_HERROR: is_set = 1; *out = NO_RECOVERY; break;
+#endif
+#ifdef __YIFF__
+  case ROAR_ERROR_TYPE_YIFF: is_set = 1; *out = YIFF_ERRNO_UNKNOWN; break;
+#endif
+  case ROAR_ERROR_TYPE_HTTP: is_set = 1; *out = 500; break;
+#ifndef DEBUG
+  // enable compiler warnings in DEBUG mode.
+  default:
+   break;
+#endif
+ }
+
+ if ( is_set ) {
+  return ROAR_ERROR_NONE;
+ }
+
+ *out = -1; // some default so we do not leave it uninited.
+ return ROAR_ERROR_NOENT;
 }
 
