/*
#  $Id$
# -----------------------------------------------------------------------------
#  The part of 'VideoNEXT MediaClient SDK'
# -----------------------------------------------------------------------------
#  Author: Petrov Maxim, 09/18/2009
#  Edited by:
#  QA by:
#  Copyright: videoNEXT LLC
# -----------------------------------------------------------------------------
*/

#include "osdep.h"

int __get_errno()
{
#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__MINGW32CE__)
   if (GetLastError()) return GetLastError();
   else return WSAGetLastError();
#else
   return errno;
#endif
}

#if not defined(__ANDROID__) || (__ANDROID_API__ >= __ANDROID_API_L__)
void __set_errno(int error)
{
#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__MINGW32CE__)
   SetLastError(error);
#else
   errno = error;
#endif
}
#endif

#if defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_WCE) || defined(__MINGW32CE__)

int strerror_r(int errnum, char *strerrbuf, size_t buflen) {
   *strerrbuf = '\0';

   char* errmsg;
   if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                  NULL, 
                  errnum, 
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
                  (char*)&errmsg, 
                  0, 
                  NULL))
   {
      strncpy(strerrbuf, errmsg, buflen);
      LocalFree(errmsg);
   }

   return 0;
}

char *getenv(const char *name) {
   return NULL;
}

void bzero(void *s, size_t n) {
   memset(s, 0, n);
}

#if 0 // FIXME
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
{
   if (af == AF_INET)
   {
      struct sockaddr_in in;
      memset(&in, 0, sizeof(in));
      in.sin_family = AF_INET;
      memcpy(&in.sin_addr, src, sizeof(struct in_addr));
      getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
      return dst;
   }
   else if (af == AF_INET6)
   {
      struct sockaddr_in6 in;
      memset(&in, 0, sizeof(in));
      in.sin6_family = AF_INET6;
      memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
      getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
      return dst;
   }

   return NULL;
}
#endif

static inline unsigned popcount(unsigned x)
{
    unsigned count = 0;
    while (x)
    {
        count += x & 1;
        x = x >> 1;
    }
    return count;
}

#endif // WIN32

unsigned getCPUCount()
{
#if defined (WIN32)
    DWORD_PTR process;
    DWORD_PTR system;

    if (GetProcessAffinityMask (GetCurrentProcess(), &process, &system))
        return popcount (system);
#elif defined(_SC_NPROCESSORS_CONF)
    return sysconf(_SC_NPROCESSORS_CONF);
#else
    fprintf(stderr, "getCPUCount is not implemented for your platform\n");
    return 1;
#endif

    return 1;
}

