{
  int i = 0, tmp = 0;

  while (isdigit (buf[i]))
    {
      tmp = (tmp * 10) + (buf[i] - '0');
      if (max && (tmp > max))
        return 0;
      ++i;
    }

  if (tmp < min)
    return 0;
  else if (i)
    {
      *num = tmp;
      (*fi)++;
      *bi += i;
      return 1;
    }
  else
    return 0;
}

#include "ace/OS_NS_time.h"

#if !defined (ACE_HAS_INLINED_OSCALLS)
# include "ace/OS_NS_time.inl"
#endif /* ACE_HAS_INLINED_OSCALLS */

#if defined (ACE_LACKS_STRPTIME)
# include "ace/os_include/os_ctype.h"
#endif /* ACE_LACKS_STRPTIME */

#include "ace/OS_NS_Thread.h"
#include "ace/Object_Manager_Base.h"

#if defined (ACE_HAS_WINCE)
#  include "ace/OS_NS_stdio.h"     /* Need ACE_OS::sprintf() */

namespace
{
  ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
    {
      ACE_TEXT ("Sun"),
      ACE_TEXT ("Mon"),
      ACE_TEXT ("Tue"),
      ACE_TEXT ("Wed"),
      ACE_TEXT ("Thu"),
      ACE_TEXT ("Fri"),
      ACE_TEXT ("Sat")
    };

  ACE_TCHAR const * const ACE_OS_month_name[] =
    {
      ACE_TEXT ("Jan"),
      ACE_TEXT ("Feb"),
      ACE_TEXT ("Mar"),
      ACE_TEXT ("Apr"),
      ACE_TEXT ("May"),
      ACE_TEXT ("Jun"),
      ACE_TEXT ("Jul"),
      ACE_TEXT ("Aug"),
      ACE_TEXT ("Sep"),
      ACE_TEXT ("Oct"),
      ACE_TEXT ("Nov"),
      ACE_TEXT ("Dec")
    };

  static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
} /* end blank namespace */
#endif /* ACE_HAS_WINCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

# if defined (ACE_HAS_WINCE)
ACE_TCHAR *
ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
{
  // buflen must be at least 26 wchar_t long.
  if (buflen < 26)              // Again, 26 is a magic number.
    {
      errno = ERANGE;
      return 0;
    }
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure
  ULARGE_INTEGER _100ns;
  _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
                     + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);
  ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
                   ACE_OS_day_of_week_name[systime.wDayOfWeek],
                   ACE_OS_month_name[systime.wMonth - 1],
                   systime.wDay,
                   systime.wHour,
                   systime.wMinute,
                   systime.wSecond,
                   systime.wYear);
  return buf;
}
# endif /* ACE_HAS_WINCE */

# if defined (ACE_LACKS_DIFFTIME)
double
ACE_OS::difftime (time_t t1, time_t t0)
{
  /* return t1 - t0 in seconds */
  struct tm tms[2], *ptms[2], temp;
  double seconds;
  int swap = 0;

  /* extract the tm structure from time_t */
  ptms[1] = ::gmtime_r (&t1, &tms[1]);
  if (ptms[1] == 0) return 0.0;

  ptms[0] = ::gmtime_r (&t0, &tms[0]);
  if (ptms[0] == 0) return 0.0;

    /* make sure t1 is > t0 */
  if (tms[1].tm_year < tms[0].tm_year)
    swap = 1;
  else if (tms[1].tm_year == tms[0].tm_year)
    {
      if (tms[1].tm_yday < tms[0].tm_yday)
        swap = 1;
      else if (tms[1].tm_yday == tms[0].tm_yday)
        {
          if (tms[1].tm_hour < tms[0].tm_hour)
            swap = 1;
          else if (tms[1].tm_hour == tms[0].tm_hour)
            {
              if (tms[1].tm_min < tms[0].tm_min)
                swap = 1;
              else if (tms[1].tm_min == tms[0].tm_min)
                {
                  if (tms[1].tm_sec < tms[0].tm_sec)
                    swap = 1;
                }
            }
        }
    }

  if (swap)
    temp = tms[0], tms[0] = tms[1], tms[1] = temp;

  seconds = 0.0;
  if (tms[1].tm_year > tms[0].tm_year)
    {
      // Accumulate the time until t[0] catches up to t[1]'s year.
      seconds = 60 - tms[0].tm_sec;
      tms[0].tm_sec = 0;
      tms[0].tm_min += 1;
      seconds += 60 * (60 - tms[0].tm_min);
      tms[0].tm_min = 0;
      tms[0].tm_hour += 1;
      seconds += 60*60 * (24 - tms[0].tm_hour);
      tms[0].tm_hour = 0;
      tms[0].tm_yday += 1;

#   define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)

      if (ISLEAPYEAR(tms[0].tm_year))
        seconds += 60*60*24 * (366 - tms[0].tm_yday);
      else
        seconds += 60*60*24 * (365 - tms[0].tm_yday);

      tms[0].tm_yday = 0;
      tms[0].tm_year += 1;

      while (tms[1].tm_year > tms[0].tm_year)
        {
          if (ISLEAPYEAR(tms[0].tm_year))
            seconds += 60*60*24 * 366;
          else
            seconds += 60*60*24 * 365;

          tms[0].tm_year += 1;
        }

#   undef ISLEAPYEAR

    }
  else
    {
      // Normalize
      if (tms[1].tm_sec < tms[0].tm_sec)
        {
          if (tms[1].tm_min == 0)
            {
              if (tms[1].tm_hour == 0)
                {
                  tms[1].tm_yday -= 1;
                  tms[1].tm_hour += 24;
                }
              tms[1].tm_hour -= 1;
              tms[1].tm_min += 60;
            }
          tms[1].tm_min -= 1;
          tms[1].tm_sec += 60;
        }
      tms[1].tm_sec -= tms[0].tm_sec;

      if (tms[1].tm_min < tms[0].tm_min)
        {
          if (tms[1].tm_hour == 0)
            {
              tms[1].tm_yday -= 1;
              tms[1].tm_hour += 24;
            }
          tms[1].tm_hour -= 1;
          tms[1].tm_min += 60;
        }
      tms[1].tm_min -= tms[0].tm_min;

      if (tms[1].tm_hour < tms[0].tm_hour)
        {
          tms[1].tm_yday -= 1;
          tms[1].tm_hour += 24;
        }
      tms[1].tm_hour -= tms[0].tm_hour;

      tms[1].tm_yday -= tms[0].tm_yday;
    }

  // accumulate the seconds
  seconds += tms[1].tm_sec;
  seconds += 60 * tms[1].tm_min;
  seconds += 60*60 * tms[1].tm_hour;
  seconds += 60*60*24 * tms[1].tm_yday;

  return seconds;
}
# endif /* ACE_LACKS_DIFFTIME */

struct tm *
ACE_OS::localtime_r (const time_t *t, struct tm *res)
{
  ACE_OS_TRACE ("ACE_OS::localtime_r");
#if defined (ACE_HAS_TR24731_2005_CRT)
  ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
  return res;
#elif defined (ACE_HAS_WINCE)
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure

  TIME_ZONE_INFORMATION pTz;

  const unsigned short int __mon_yday[2][13] =
  {
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  };

  ULARGE_INTEGER _100ns;
  ::GetTimeZoneInformation (&pTz);

  _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);

  res->tm_hour = systime.wHour;

  if(pTz.DaylightBias!=0)
    res->tm_isdst = 1;
  else
    res->tm_isdst = 1;

   int iLeap;
   iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
   // based on leap select which group to use

   res->tm_mday = systime.wDay;
   res->tm_min = systime.wMinute;
   res->tm_mon = systime.wMonth - 1;
   res->tm_sec = systime.wSecond;
   res->tm_wday = systime.wDayOfWeek;
   res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
   res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
   res->tm_year = res->tm_year - 1900;

   return res;
#elif defined (ACE_LACKS_LOCALTIME_R)
  ACE_OS_GUARD

  ACE_UNUSED_ARG (res);
  struct tm * res_ptr = 0;
  ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
  if (res_ptr == 0)
    return 0;
  else
    {
      *res = *res_ptr;
      return res;
    }
#else
  ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
#endif /* ACE_HAS_TR24731_2005_CRT */
}

time_t
ACE_OS::mktime (struct tm *t)
{
  ACE_OS_TRACE ("ACE_OS::mktime");
#   if defined (ACE_HAS_WINCE)
  SYSTEMTIME t_sys;
  FILETIME t_file;
  t_sys.wSecond = t->tm_sec;
  t_sys.wMinute = t->tm_min;
  t_sys.wHour = t->tm_hour;
  t_sys.wDay = t->tm_mday;
  t_sys.wMonth = t->tm_mon + 1;  // SYSTEMTIME is 1-indexed, tm is 0-indexed
  t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
  t_sys.wDayOfWeek = t->tm_wday;  // Ignored in below function call.
  t_sys.wMilliseconds = 0;
  if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
    return -1;
  ACE_Time_Value tv (t_file);
  return tv.sec ();
#   else
#     if defined (ACE_HAS_THREADS)  &&  !defined (ACE_HAS_MT_SAFE_MKTIME)
  ACE_OS_GUARD
#     endif /* ACE_HAS_THREADS  &&  ! ACE_HAS_MT_SAFE_MKTIME */

  ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
#   endif /* ACE_HAS_WINCE */
}

#if defined (ACE_LACKS_STRPTIME)
char *
ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
{
  int bi = 0;
  int fi = 0;
  bool percent = false;

  if (!buf || !format)
    return 0;

  while (format[fi] != '\0')
    {
      if (percent)
        {
          percent = false;
          switch (format[fi])
            {
            case '%':                        // an escaped %
              if (buf[bi] == '%')
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet: weekday via locale long/short names
                 case 'a':                        / * weekday via locale * /
                 / * FALL THROUGH * /
                 case 'A':                        / * long/short names * /
                 break;
                 */

              /* not supported yet:
                 case 'b':                        / * month via locale * /
                 / * FALL THROUGH * /
                 case 'B':                        / * long/short names * /
                 / * FALL THROUGH * /
                 case 'h':
                 break;
                 */

              /* not supported yet:
                 case 'c':                        / * %x %X * /
                 break;
                 */

              /* not supported yet:
                 case 'C':                        / * date & time -  * /
                 / * locale long format * /
                 break;
                 */

            case 'd':                        /* day of month (1-31) */
              /* FALL THROUGH */
            case 'e':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              break;

            case 'D':                        /* %m/%d/%y */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              --fi;
              tm->tm_mon--;

              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);

              ++bi;

              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);
              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'H':                        /* hour (0-23) */
              /* FALL THROUGH */
            case 'k':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet:
                 case 'I':                        / * hour (0-12) * /
                 / * FALL THROUGH * /
                 case 'l':
                 break;
                 */

            case 'j':                        /* day of year (0-366) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
                return const_cast<char*> (buf + bi);

              tm->tm_yday--;
              break;

            case 'm':                        /* an escaped % */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              tm->tm_mon--;
              break;

            case 'M':                        /* minute (0-59) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet:
                 case 'p':                        / * am or pm for locale * /
                 break;
                 */

              /* not supported yet:
                 case 'r':                        / * %I:%M:%S %p * /
                 break;
                 */

            case 'R':                        /* %H:%M */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

            case 'S':                        /* seconds (0-61) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);
              break;

            case 'T':                        /* %H:%M:%S */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);

              break;

            case 'w':                        /* day of week (0=Sun-6) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet: date, based on locale
                 case 'x':                        / * date, based on locale * /
                 break;
                 */

              /* not supported yet:
                 case 'X':                        / * time, based on locale * /
                 break;
                 */

            case 'y':                        /* the year - 1900 (0-99) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);

              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'Y':                        /* the full year (1999) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
                return const_cast<char*> (buf + bi);

              tm->tm_year -= 1900;
              break;

            default:                        /* unrecognised */
              return const_cast<char*> (buf + bi);
            } /* switch (format[fi]) */

        }
      else
        { /* if (percent) */
          if (format[fi] == '%')
            {
              percent = true;
              ++fi;
            }
          else
            {
              if (format[fi] == buf[bi])
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
            }
        } /* if (percent) */
    } /* while (format[fi] */

  return const_cast<char*> (buf + bi);
}

int
ACE_OS::strptime_getnum (const char *buf,
                         int *num,
                         int *bi,
                         int *fi,
                         int min,
                         int max)

#endif /* ACE_LACKS_STRPTIME */

ACE_END_VERSIONED_NAMESPACE_DECL


#include "ace/OS_NS_time.h"

#if !defined (ACE_HAS_INLINED_OSCALLS)
# include "ace/OS_NS_time.inl"
#endif /* ACE_HAS_INLINED_OSCALLS */

#if defined (ACE_LACKS_STRPTIME)
# include "ace/os_include/os_ctype.h"
#endif /* ACE_LACKS_STRPTIME */

#include "ace/OS_NS_Thread.h"
#include "ace/Object_Manager_Base.h"

#if defined (ACE_HAS_WINCE)
#  include "ace/OS_NS_stdio.h"     /* Need ACE_OS::sprintf() */

namespace
{
  ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
    {
      ACE_TEXT ("Sun"),
      ACE_TEXT ("Mon"),
      ACE_TEXT ("Tue"),
      ACE_TEXT ("Wed"),
      ACE_TEXT ("Thu"),
      ACE_TEXT ("Fri"),
      ACE_TEXT ("Sat")
    };

  ACE_TCHAR const * const ACE_OS_month_name[] =
    {
      ACE_TEXT ("Jan"),
      ACE_TEXT ("Feb"),
      ACE_TEXT ("Mar"),
      ACE_TEXT ("Apr"),
      ACE_TEXT ("May"),
      ACE_TEXT ("Jun"),
      ACE_TEXT ("Jul"),
      ACE_TEXT ("Aug"),
      ACE_TEXT ("Sep"),
      ACE_TEXT ("Oct"),
      ACE_TEXT ("Nov"),
      ACE_TEXT ("Dec")
    };

  static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
} /* end blank namespace */
#endif /* ACE_HAS_WINCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

# if defined (ACE_HAS_WINCE)
ACE_TCHAR *
ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
{
  // buflen must be at least 26 wchar_t long.
  if (buflen < 26)              // Again, 26 is a magic number.
    {
      errno = ERANGE;
      return 0;
    }
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure
  ULARGE_INTEGER _100ns;
  _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
                     + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);
  ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
                   ACE_OS_day_of_week_name[systime.wDayOfWeek],
                   ACE_OS_month_name[systime.wMonth - 1],
                   systime.wDay,
                   systime.wHour,
                   systime.wMinute,
                   systime.wSecond,
                   systime.wYear);
  return buf;
}
# endif /* ACE_HAS_WINCE */

# if defined (ACE_LACKS_DIFFTIME)
double
ACE_OS::difftime (time_t t1, time_t t0)
{
  /* return t1 - t0 in seconds */
  struct tm tms[2], *ptms[2], temp;
  double seconds;
  int swap = 0;

  /* extract the tm structure from time_t */
  ptms[1] = ::gmtime_r

  if (ptms[1] == 0) return 0.0;

  ptms[0] = ::gmtime_r (&t0, &tms[0]);
  if (ptms[0] == 0) return 0.0;

    /* make sure t1 is > t0 */
  if (tms[1].tm_year < tms[0].tm_year)
    swap = 1;
  else if (tms[1].tm_year == tms[0].tm_year)
    {
      if (tms[1].tm_yday < tms[0].tm_yday)
        swap = 1;
      else if (tms[1].tm_yday == tms[0].tm_yday)
        {
          if (tms[1].tm_hour < tms[0].tm_hour)
            swap = 1;
          else if (tms[1].tm_hour == tms[0].tm_hour)
            {
              if (tms[1].tm_min < tms[0].tm_min)
                swap = 1;
              else if (tms[1].tm_min == tms[0].tm_min)
                {
                  if (tms[1].tm_sec < tms[0].tm_sec)
                    swap = 1;
                }
            }
        }
    }

  if (swap)
    temp = tms[0], tms[0] = tms[1], tms[1] = temp;

  seconds = 0.0;
  if (tms[1].tm_year > tms[0].tm_year)
    {
      // Accumulate the time until t[0] catches up to t[1]'s year.
      seconds = 60 - tms[0].tm_sec;
      tms[0].tm_sec = 0;
      tms[0].tm_min += 1;
      seconds += 60 * (60 - tms[0].tm_min);
      tms[0].tm_min = 0;
      tms[0].tm_hour += 1;
      seconds += 60*60 * (24 - tms[0].tm_hour);
      tms[0].tm_hour = 0;
      tms[0].tm_yday += 1;

#   define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)

      if (ISLEAPYEAR(tms[0].tm_year))
        seconds += 60*60*24 * (366 - tms[0].tm_yday);
      else
        seconds += 60*60*24 * (365 - tms[0].tm_yday);

      tms[0].tm_yday = 0;
      tms[0].tm_year += 1;

      while (tms[1].tm_year > tms[0].tm_year)
        {
          if (ISLEAPYEAR(tms[0].tm_year))
            seconds += 60*60*24 * 366;
          else
            seconds += 60*60*24 * 365;

          tms[0].tm_year += 1;
        }

#   undef ISLEAPYEAR

    }
  else
    {
      // Normalize
      if (tms[1].tm_sec < tms[0].tm_sec)
        {
          if (tms[1].tm_min == 0)
            {
              if (tms[1].tm_hour == 0)
                {
                  tms[1].tm_yday -= 1;
                  tms[1].tm_hour += 24;
                }
              tms[1].tm_hour -= 1;
              tms[1].tm_min += 60;
            }
          tms[1].tm_min -= 1;
          tms[1].tm_sec += 60;
        }
      tms[1].tm_sec -= tms[0].tm_sec;

      if (tms[1].tm_min < tms[0].tm_min)
        {
          if (tms[1].tm_hour == 0)
            {
              tms[1].tm_yday -= 1;
              tms[1].tm_hour += 24;
            }
          tms[1].tm_hour -= 1;
          tms[1].tm_min += 60;
        }
      tms[1].tm_min -= tms[0].tm_min;

      if (tms[1].tm_hour < tms[0].tm_hour)
        {
          tms[1].tm_yday -= 1;
          tms[1].tm_hour += 24;
        }
      tms[1].tm_hour -= tms[0].tm_hour;

      tms[1].tm_yday -= tms[0].tm_yday;
    }

  // accumulate the seconds
  seconds += tms[1].tm_sec;
  seconds += 60 * tms[1].tm_min;
  seconds += 60*60 * tms[1].tm_hour;
  seconds += 60*60*24 * tms[1].tm_yday;

  return seconds;
}
# endif /* ACE_LACKS_DIFFTIME */

struct tm *
ACE_OS::localtime_r (const time_t *t, struct tm *res)
{
  ACE_OS_TRACE ("ACE_OS::localtime_r");
#if defined (ACE_HAS_TR24731_2005_CRT)
  ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
  return res;
#elif defined (ACE_HAS_WINCE)
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure

  TIME_ZONE_INFORMATION pTz;

  const unsigned short int __mon_yday[2][13] =
  {
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  };

  ULARGE_INTEGER _100ns;
  ::GetTimeZoneInformation (&pTz);

  _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);

  res->tm_hour = systime.wHour;

  if(pTz.DaylightBias!=0)
    res->tm_isdst = 1;
  else
    res->tm_isdst = 1;

   int iLeap;
   iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
   // based on leap select which group to use

   res->tm_mday = systime.wDay;
   res->tm_min = systime.wMinute;
   res->tm_mon = systime.wMonth - 1;
   res->tm_sec = systime.wSecond;
   res->tm_wday = systime.wDayOfWeek;
   res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
   res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
   res->tm_year = res->tm_year - 1900;

   return res;
#elif defined (ACE_LACKS_LOCALTIME_R)
  ACE_OS_GUARD

  ACE_UNUSED_ARG (res);
  struct tm * res_ptr = 0;
  ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
  if (res_ptr == 0)
    return 0;
  else
    {
      *res = *res_ptr;
      return res;
    }
#else
  ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
#endif /* ACE_HAS_TR24731_2005_CRT */
}

time_t
ACE_OS::mktime (struct tm *t)
{
  ACE_OS_TRACE ("ACE_OS::mktime");
#   if defined (ACE_HAS_WINCE)
  SYSTEMTIME t_sys;
  FILETIME t_file;
  t_sys.wSecond = t->tm_sec;
  t_sys.wMinute = t->tm_min;
  t_sys.wHour = t->tm_hour;
  t_sys.wDay = t->tm_mday;
  t_sys.wMonth = t->tm_mon + 1;  // SYSTEMTIME is 1-indexed, tm is 0-indexed
  t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
  t_sys.wDayOfWeek = t->tm_wday;  // Ignored in below function call.
  t_sys.wMilliseconds = 0;
  if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
    return -1;
  ACE_Time_Value tv (t_file);
  return tv.sec ();
#   else
#     if defined (ACE_HAS_THREADS)  &&  !defined (ACE_HAS_MT_SAFE_MKTIME)
  ACE_OS_GUARD
#     endif /* ACE_HAS_THREADS  &&  ! ACE_HAS_MT_SAFE_MKTIME */

  ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
#   endif /* ACE_HAS_WINCE */
}

#if defined (ACE_LACKS_STRPTIME)
char *
ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
{
  int bi = 0;
  int fi = 0;
  bool percent = false;

  if (!buf || !format)
    return 0;

  while (format[fi] != '\0')
    {
      if (percent)
        {
          percent = false;
          switch (format[fi])
            {
            case '%':                        // an escaped %
              if (buf[bi] == '%')
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet: weekday via locale long/short names
                 case 'a':                        / * weekday via locale * /
                 / * FALL THROUGH * /
                 case 'A':                        / * long/short names * /
                 break;
                 */

              /* not supported yet:
                 case 'b':                        / * month via locale * /
                 / * FALL THROUGH * /
                 case 'B':                        / * long/short names * /
                 / * FALL THROUGH * /
                 case 'h':
                 break;
                 */

              /* not supported yet:
                 case 'c':                        / * %x %X * /
                 break;
                 */

              /* not supported yet:
                 case 'C':                        / * date & time -  * /
                 / * locale long format * /
                 break;
                 */

            case 'd':                        /* day of month (1-31) */
              /* FALL THROUGH */
            case 'e':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              break;

            case 'D':                        /* %m/%d/%y */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              --fi;
              tm->tm_mon--;

              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);

              ++bi;

              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);
              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'H':                        /* hour (0-23) */
              /* FALL THROUGH */
            case 'k':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet:
                 case 'I':                        / * hour (0-12) * /
                 / * FALL THROUGH * /
                 case 'l':
                 break;
                 */

            case 'j':                        /* day of year (0-366) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
                return const_cast<char*> (buf + bi);

              tm->tm_yday--;
              break;

            case 'm':                        /* an escaped % */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              tm->tm_mon--;
              break;

            case 'M':                        /* minute (0-59) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet:
                 case 'p':                        / * am or pm for locale * /
                 break;
                 */

              /* not supported yet:
                 case 'r':                        / * %I:%M:%S %p * /
                 break;
                 */

            case 'R':                        /* %H:%M */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

            case 'S':                        /* seconds (0-61) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);
              break;

            case 'T':                        /* %H:%M:%S */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);

              break;

            case 'w':                        /* day of week (0=Sun-6) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet: date, based on locale
                 case 'x':                        / * date, based on locale * /
                 break;
                 */

              /* not supported yet:
                 case 'X':                        / * time, based on locale * /
                 break;
                 */

            case 'y':                        /* the year - 1900 (0-99) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);

              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'Y':                        /* the full year (1999) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
                return const_cast<char*> (buf + bi);

              tm->tm_year -= 1900;
              break;

            default:                        /* unrecognised */
              return const_cast<char*> (buf + bi);
            } /* switch (format[fi]) */

        }
      else
        { /* if (percent) */
          if (format[fi] == '%')
            {
              percent = true;
              ++fi;
            }
          else
            {
              if (format[fi] == buf[bi])
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
            }
        } /* if (percent) */
    } /* while (format[fi] */

  return const_cast<char*> (buf + bi);
}

int
ACE_OS::strptime_getnum (const char *buf,
                         int *num,
                         int *bi,
                         int *fi,
                         int min,
                         int max)
{
  int i = 0, tmp = 0;

  while (isdigit (buf[i]))
    {
      tmp = (tmp * 10) + (buf[i] - '0');
      if (max && (tmp > max))
        return 0;
      ++i;
    }

  if (tmp < min)
    return 0;
  else if (i)
    {
      *num = tmp;
      (*fi)++;
      *bi += i;
      return 1;
    }
  else
    return 0;
}
#endif /* ACE_LACKS_STRPTIME */

ACE_END_VERSIONED_NAMESPACE_DECL


while (tms[1].tm_year > tms[0].tm_year)
        {
          if (ISLEAPYEAR(tms[0].tm_year))
            seconds += 60*60*24 * 366;
          else
            seconds += 60*60*24 * 365;

          tms[0].tm_year += 1;
        }

#include "ace/OS_NS_time.h"

#if !defined (ACE_HAS_INLINED_OSCALLS)
# include "ace/OS_NS_time.inl"
#endif /* ACE_HAS_INLINED_OSCALLS */

#if defined (ACE_LACKS_STRPTIME)
# include "ace/os_include/os_ctype.h"
#endif /* ACE_LACKS_STRPTIME */

#include "ace/OS_NS_Thread.h"
#include "ace/Object_Manager_Base.h"

#if defined (ACE_HAS_WINCE)
#  include "ace/OS_NS_stdio.h"     /* Need ACE_OS::sprintf() */

namespace
{
  ACE_TCHAR const * const ACE_OS_day_of_week_name[] =
    {
      ACE_TEXT ("Sun"),
      ACE_TEXT ("Mon"),
      ACE_TEXT ("Tue"),
      ACE_TEXT ("Wed"),
      ACE_TEXT ("Thu"),
      ACE_TEXT ("Fri"),
      ACE_TEXT ("Sat")
    };

  ACE_TCHAR const * const ACE_OS_month_name[] =
    {
      ACE_TEXT ("Jan"),
      ACE_TEXT ("Feb"),
      ACE_TEXT ("Mar"),
      ACE_TEXT ("Apr"),
      ACE_TEXT ("May"),
      ACE_TEXT ("Jun"),
      ACE_TEXT ("Jul"),
      ACE_TEXT ("Aug"),
      ACE_TEXT ("Sep"),
      ACE_TEXT ("Oct"),
      ACE_TEXT ("Nov"),
      ACE_TEXT ("Dec")
    };

  static ACE_TCHAR const ACE_OS_CTIME_R_FMTSTR[] = ACE_TEXT ("%3s %3s %02d %02d:%02d:%02d %04d\n");
} /* end blank namespace */
#endif /* ACE_HAS_WINCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

# if defined (ACE_HAS_WINCE)
ACE_TCHAR *
ACE_OS::ctime_r (const time_t *clock, ACE_TCHAR *buf, int buflen)
{
  // buflen must be at least 26 wchar_t long.
  if (buflen < 26)              // Again, 26 is a magic number.
    {
      errno = ERANGE;
      return 0;
    }
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure
  ULARGE_INTEGER _100ns;
  _100ns.QuadPart = (DWORDLONG) *clock * 10000 * 1000
                     + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);
  ACE_OS::sprintf (buf, ACE_OS_CTIME_R_FMTSTR,
                   ACE_OS_day_of_week_name[systime.wDayOfWeek],
                   ACE_OS_month_name[systime.wMonth - 1],
                   systime.wDay,
                   systime.wHour,
                   systime.wMinute,
                   systime.wSecond,
                   systime.wYear);
  return buf;
}
# endif /* ACE_HAS_WINCE */

# if defined (ACE_LACKS_DIFFTIME)
double
ACE_OS::difftime (time_t t1, time_t t0)
{
  /* return t1 - t0 in seconds */
  struct tm tms[2], *ptms[2], temp;
  double seconds;
  int swap = 0;

  /* extract the tm structure from time_t */
  ptms[1] = ::gmtime_r (&t1, &tms[1]);
  if (ptms[1] == 0) return 0.0;

  ptms[0] = ::gmtime_r (&t0, &tms[0]);
  if (ptms[0] == 0) return 0.0;

    /* make sure t1 is > t0 */
  if (tms[1].tm_year < tms[0].tm_year)
    swap = 1;
  else if (tms[1].tm_year == tms[0].tm_year)
    {
      if (tms[1].tm_yday < tms[0].tm_yday)
        swap = 1;
      else if (tms[1].tm_yday == tms[0].tm_yday)
        {
          if (tms[1].tm_hour < tms[0].tm_hour)
            swap = 1;
          else if (tms[1].tm_hour == tms[0].tm_hour)
            {
              if (tms[1].tm_min < tms[0].tm_min)
                swap = 1;
              else if (tms[1].tm_min == tms[0].tm_min)
                {
                  if (tms[1].tm_sec < tms[0].tm_sec)
                    swap = 1;
                }
            }
        }
    }

  if (swap)
    temp = tms[0], tms[0] = tms[1], tms[1] = temp;

  seconds = 0.0;
  if (tms[1].tm_year > tms[0].tm_year)
    {
      // Accumulate the time until t[0] catches up to t[1]'s year.
      seconds = 60 - tms[0].tm_sec;
      tms[0].tm_sec = 0;
      tms[0].tm_min += 1;
      seconds += 60 * (60 - tms[0].tm_min);
      tms[0].tm_min = 0;
      tms[0].tm_hour += 1;
      seconds += 60*60 * (24 - tms[0].tm_hour);
      tms[0].tm_hour = 0;
      tms[0].tm_yday += 1;

#   define ISLEAPYEAR(y) ((y)&3u?0:(y)%25u?1:(y)/25u&12?0:1)

      if (ISLEAPYEAR(tms[0].tm_year))
        seconds += 60*60*24 * (366 - tms[0].tm_yday);
      else
        seconds += 60*60*24 * (365 - tms[0].tm_yday);

      tms[0].tm_yday = 0;
      tms[0].tm_year += 1;

#   undef ISLEAPYEAR

    }
  else
    {
      // Normalize
      if (tms[1].tm_sec < tms[0].tm_sec)
        {
          if (tms[1].tm_min == 0)
            {
              if (tms[1].tm_hour == 0)
                {
                  tms[1].tm_yday -= 1;
                  tms[1].tm_hour += 24;
                }
              tms[1].tm_hour -= 1;
              tms[1].tm_min += 60;
            }
          tms[1].tm_min -= 1;
          tms[1].tm_sec += 60;
        }
      tms[1].tm_sec -= tms[0].tm_sec;

      if (tms[1].tm_min < tms[0].tm_min)
        {
          if (tms[1].tm_hour == 0)
            {
              tms[1].tm_yday -= 1;
              tms[1].tm_hour += 24;
            }
          tms[1].tm_hour -= 1;
          tms[1].tm_min += 60;
        }
      tms[1].tm_min -= tms[0].tm_min;

      if (tms[1].tm_hour < tms[0].tm_hour)
        {
          tms[1].tm_yday -= 1;
          tms[1].tm_hour += 24;
        }
      tms[1].tm_hour -= tms[0].tm_hour;

      tms[1].tm_yday -= tms[0].tm_yday;
    }

  // accumulate the seconds
  seconds += tms[1].tm_sec;
  seconds += 60 * tms[1].tm_min;
  seconds += 60*60 * tms[1].tm_hour;
  seconds += 60*60*24 * tms[1].tm_yday;

  return seconds;
}
# endif /* ACE_LACKS_DIFFTIME */

struct tm *
ACE_OS::localtime_r (const time_t *t, struct tm *res)
{
  ACE_OS_TRACE ("ACE_OS::localtime_r");
#if defined (ACE_HAS_TR24731_2005_CRT)
  ACE_SECURECRTCALL (localtime_s (res, t), struct tm *, 0, res);
  return res;
#elif defined (ACE_HAS_WINCE)
  // This is really stupid, converting FILETIME to timeval back and
  // forth.  It assumes FILETIME and DWORDLONG are the same structure

  TIME_ZONE_INFORMATION pTz;

  const unsigned short int __mon_yday[2][13] =
  {
    /* Normal years.  */
    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
    /* Leap years.  */
    { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  };

  ULARGE_INTEGER _100ns;
  ::GetTimeZoneInformation (&pTz);

  _100ns.QuadPart = (DWORDLONG) *t * 10000 * 1000 + ACE_Time_Value::FILETIME_to_timval_skew;
  FILETIME file_time;
  file_time.dwLowDateTime = _100ns.LowPart;
  file_time.dwHighDateTime = _100ns.HighPart;

  FILETIME localtime;
  SYSTEMTIME systime;
  FileTimeToLocalFileTime (&file_time, &localtime);
  FileTimeToSystemTime (&localtime, &systime);

  res->tm_hour = systime.wHour;

  if(pTz.DaylightBias!=0)
    res->tm_isdst = 1;
  else
    res->tm_isdst = 1;

   int iLeap;
   iLeap = (res->tm_year % 4 == 0 && (res->tm_year% 100 != 0 || res->tm_year % 400 == 0));
   // based on leap select which group to use

   res->tm_mday = systime.wDay;
   res->tm_min = systime.wMinute;
   res->tm_mon = systime.wMonth - 1;
   res->tm_sec = systime.wSecond;
   res->tm_wday = systime.wDayOfWeek;
   res->tm_yday = __mon_yday[iLeap][systime.wMonth] + systime.wDay;
   res->tm_year = systime.wYear;// this the correct year but bias the value to start at the 1900
   res->tm_year = res->tm_year - 1900;

   return res;
#elif defined (ACE_LACKS_LOCALTIME_R)
  ACE_OS_GUARD

  ACE_UNUSED_ARG (res);
  struct tm * res_ptr = 0;
  ACE_OSCALL (::localtime (t), struct tm *, 0, res_ptr);
  if (res_ptr == 0)
    return 0;
  else
    {
      *res = *res_ptr;
      return res;
    }
#else
  ACE_OSCALL_RETURN (::localtime_r (t, res), struct tm *, 0);
#endif /* ACE_HAS_TR24731_2005_CRT */
}

time_t
ACE_OS::mktime (struct tm *t)
{
  ACE_OS_TRACE ("ACE_OS::mktime");
#   if defined (ACE_HAS_WINCE)
  SYSTEMTIME t_sys;
  FILETIME t_file;
  t_sys.wSecond = t->tm_sec;
  t_sys.wMinute = t->tm_min;
  t_sys.wHour = t->tm_hour;
  t_sys.wDay = t->tm_mday;
  t_sys.wMonth = t->tm_mon + 1;  // SYSTEMTIME is 1-indexed, tm is 0-indexed
  t_sys.wYear = t->tm_year + 1900; // SYSTEMTIME is real; tm is since 1900
  t_sys.wDayOfWeek = t->tm_wday;  // Ignored in below function call.
  t_sys.wMilliseconds = 0;
  if (SystemTimeToFileTime (&t_sys, &t_file) == 0)
    return -1;
  ACE_Time_Value tv (t_file);
  return tv.sec ();
#   else
#     if defined (ACE_HAS_THREADS)  &&  !defined (ACE_HAS_MT_SAFE_MKTIME)
  ACE_OS_GUARD
#     endif /* ACE_HAS_THREADS  &&  ! ACE_HAS_MT_SAFE_MKTIME */

  ACE_OSCALL_RETURN (ACE_STD_NAMESPACE::mktime (t), time_t, (time_t) -1);
#   endif /* ACE_HAS_WINCE */
}

#if defined (ACE_LACKS_STRPTIME)
char *
ACE_OS::strptime_emulation (const char *buf, const char *format, struct tm *tm)
{
  int bi = 0;
  int fi = 0;
  bool percent = false;

  if (!buf || !format)
    return 0;

  while (format[fi] != '\0')
    {
      if (percent)
        {
          percent = false;
          switch (format[fi])
            {
            case '%':                        // an escaped %
              if (buf[bi] == '%')
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet: weekday via locale long/short names
                 case 'a':                        / * weekday via locale * /
                 / * FALL THROUGH * /
                 case 'A':                        / * long/short names * /
                 break;
                 */

              /* not supported yet:
                 case 'b':                        / * month via locale * /
                 / * FALL THROUGH * /
                 case 'B':                        / * long/short names * /
                 / * FALL THROUGH * /
                 case 'h':
                 break;
                 */

              /* not supported yet:
                 case 'c':                        / * %x %X * /
                 break;
                 */

              /* not supported yet:
                 case 'C':                        / * date & time -  * /
                 / * locale long format * /
                 break;
                 */

            case 'd':                        /* day of month (1-31) */
              /* FALL THROUGH */
            case 'e':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              break;

            case 'D':                        /* %m/%d/%y */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              --fi;
              tm->tm_mon--;

              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);

              ++bi;

              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mday, &bi, &fi, 1, 31))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != '/')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);
              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'H':                        /* hour (0-23) */
              /* FALL THROUGH */
            case 'k':
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);
              break;

              /* not supported yet:
                 case 'I':                        / * hour (0-12) * /
                 / * FALL THROUGH * /
                 case 'l':
                 break;
                 */

            case 'j':                        /* day of year (0-366) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_yday, &bi, &fi, 1, 366))
                return const_cast<char*> (buf + bi);

              tm->tm_yday--;
              break;

            case 'm':                        /* an escaped % */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_mon, &bi, &fi, 1, 12))
                return const_cast<char*> (buf + bi);

              tm->tm_mon--;
              break;

            case 'M':                        /* minute (0-59) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet:
                 case 'p':                        / * am or pm for locale * /
                 break;
                 */

              /* not supported yet:
                 case 'r':                        / * %I:%M:%S %p * /
                 break;
                 */

            case 'R':                        /* %H:%M */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              break;

            case 'S':                        /* seconds (0-61) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);
              break;

            case 'T':                        /* %H:%M:%S */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_hour, &bi, &fi, 0, 23))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_min, &bi, &fi, 0, 59))
                return const_cast<char*> (buf + bi);

              --fi;
              if (buf[bi] != ':')
                return const_cast<char*> (buf + bi);
              ++bi;
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_sec, &bi, &fi, 0, 61))
                return const_cast<char*> (buf + bi);

              break;

            case 'w':                        /* day of week (0=Sun-6) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_wday, &bi, &fi, 0, 6))
                return const_cast<char*> (buf + bi);

              break;

              /* not supported yet: date, based on locale
                 case 'x':                        / * date, based on locale * /
                 break;
                 */

              /* not supported yet:
                 case 'X':                        / * time, based on locale * /
                 break;
                 */

            case 'y':                        /* the year - 1900 (0-99) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 99))
                return const_cast<char*> (buf + bi);

              if (tm->tm_year < 69)
                tm->tm_year += 100;
              break;

            case 'Y':                        /* the full year (1999) */
              if (!ACE_OS::strptime_getnum
                     (buf + bi, &tm->tm_year, &bi, &fi, 0, 0))
                return const_cast<char*> (buf + bi);

              tm->tm_year -= 1900;
              break;

            default:                        /* unrecognised */
              return const_cast<char*> (buf + bi);
            } /* switch (format[fi]) */

        }
      else
        { /* if (percent) */
          if (format[fi] == '%')
            {
              percent = true;
              ++fi;
            }
          else
            {
              if (format[fi] == buf[bi])
                {
                  ++fi;
                  ++bi;
                }
              else
                return const_cast<char*> (buf + bi);
            }
        } /* if (percent) */
    } /* while (format[fi] */

  return const_cast<char*> (buf + bi);
}

int
ACE_OS::strptime_getnum (const char *buf,
                         int *num,
                         int *bi,
                         int *fi,
                         int min,
                         int max)
{
  int i = 0, tmp = 0;

  while (isdigit (buf[i]))
    {
      tmp = (tmp * 10) + (buf[i] - '0');
      if (max && (tmp > max))
        return 0;
      ++i;
    }

  if (tmp < min)
    return 0;
  else if (i)
    {
      *num = tmp;
      (*fi)++;
      *bi += i;
      return 1;
    }
  else
    return 0;
}
#endif /* ACE_LACKS_STRPTIME */

ACE_END_VERSIONED_NAMESPACE_DECL


/****************************************************************************
 *
 * $Id: file.cpp 3496 2011-11-22 15:14:32Z fnovotny $
 *
 * This file is part of the ViSP software.
 *
 *
 * Edition License.
 *
 * See http://example.com for more information.
 *
 * This software was developed at:
 * INRIA Rennes - Bretagne Atlantique
 * Campus Universitaire de Beaulieu
 * 35042 Rennes Cedex
 * France
 * http://example.com
 *
 * If you have questions regarding the use of this file, please contact
 * INRIA at example@nnthink.com
 *
 *
 * Contact example@nnthink.com if any conditions of this licensing are
 * not clear to you.
 *
 * Description:
 *
 *
 * Authors:
 * Filip Novotny
 *
 *
 *****************************************************************************/

/*!
  \file calibrator_main.cpp
  \brief
*/

#include "calibrator.h"
#include "ros/ros.h"

{
  ros::init(argc, argv, "calibrator");

  visp_camera_calibration::Calibrator().spin();

  return 0;
}


{
  ros::init(argc, argv, "calibrator");

  visp_camera_calibration::Calibrator().spin();

  return 0;
}

/****************************************************************************
 *
 * $Id: file.cpp 3496 2011-11-22 15:14:32Z fnovotny $
 *
 * This file is part of the ViSP software.
 *
 *
 * Edition License.
 *
 * See http://example.com for more information.
 *
 * This software was developed at:
 * INRIA Rennes - Bretagne Atlantique
 * Campus Universitaire de Beaulieu
 * 35042 Rennes Cedex
 * France
 * http://example.com
 *
 * If you have questions regarding the use of this file, please contact
 * INRIA at example@nnthink.com
 *
 *
 * Contact example@nnthink.com if any conditions of this licensing are
 * not clear to you.
 *
 * Description:
 *
 *
 * Authors:
 * Filip Novotny
 *
 *
 *****************************************************************************/

/*!
  \file calibrator_main.cpp
  \brief
*/

#include "calibrator.h"
#include "ros/ros.h"

int main(int argc, char **argv)


/****************************************************************************
 *
 * $Id: file.cpp 3496 2011-11-22 15:14:32Z fnovotny $
 *
 * This file is part of the ViSP software.
 *
 *
 * Edition License.
 *
 * See http://example.com for more information.
 *
 * This software was developed at:
 * INRIA Rennes - Bretagne Atlantique
 * Campus Universitaire de Beaulieu
 * 35042 Rennes Cedex
 * France
 * http://example.com
 *
 * If you have questions regarding the use of this file, please contact
 * INRIA at example@nnthink.com
 *
 *
 * Contact example@nnthink.com if any conditions of this licensing are
 * not clear to you.
 *
 * Description:
 *
 *
 * Authors:
 * Filip Novotny
 *
 *
 *****************************************************************************/

/*!
  \file calibrator_main.cpp
  \brief
*/

#include "calibrator.h"
#include "ros/ros.h"

int main(int argc, char **argv)
{
  ros::init(argc, argv, "calibrator");

  visp_camera_calibration::Calibrator().spin();

  retur


void stereopipeline_accel(ap_uint<INPUT_PTR_WIDTH> *img_L, ap_uint<INPUT_PTR_WIDTH> *img_R, ap_uint<OUTPUT_PTR_WIDTH> *img_disp,
	ap_fixed<32,12> *cameraMA_l, ap_fixed<32,12> *cameraMA_r, ap_fixed<32,12> *distC_l, ap_fixed<32,12> *distC_r, ap_fixed<32,12> *irA_l,
	ap_fixed<32,12> *irA_r, int *bm_state_arr, int rows, int cols)

{
#pragma HLS INTERFACE m_axi     port=img_L  offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi     port=img_R  offset=slave bundle=gmem5
#pragma HLS INTERFACE m_axi     port=img_disp  offset=slave bundle=gmem6
#pragma HLS INTERFACE m_axi     port=cameraMA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=cameraMA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=distC_l  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=distC_r  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=irA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=irA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=bm_state_arr  offset=slave bundle=gmem4
#pragma HLS INTERFACE s_axilite port=rows               bundle=control
#pragma HLS INTERFACE s_axilite port=cols               bundle=control
#pragma HLS INTERFACE s_axilite port=return                bundle=control

	ap_fixed<32,12> cameraMA_l_fix[XF_CAMERA_MATRIX_SIZE], cameraMA_r_fix[XF_CAMERA_MATRIX_SIZE], distC_l_fix[XF_DIST_COEFF_SIZE], distC_r_fix[XF_DIST_COEFF_SIZE], irA_l_fix[XF_CAMERA_MATRIX_SIZE], irA_r_fix[XF_CAMERA_MATRIX_SIZE];

	for (int i=0; i<XF_CAMERA_MATRIX_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		cameraMA_l_fix[i] = cameraMA_l[i];
		cameraMA_r_fix[i] = cameraMA_r[i];
		irA_l_fix[i] = irA_l[i];
		irA_r_fix[i] = irA_r[i];
	}
	for (int i=0; i<XF_DIST_COEFF_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		distC_l_fix[i] = distC_l[i];
		distC_r_fix[i] = distC_r[i];
	}

	xf::xFSBMState<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS> bm_state;
	bm_state.preFilterType = bm_state_arr[0];
	bm_state.preFilterSize = bm_state_arr[1];
	bm_state.preFilterCap = bm_state_arr[2];
	bm_state.SADWindowSize = bm_state_arr[3];
	bm_state.minDisparity = bm_state_arr[4];
	bm_state.numberOfDisparities = bm_state_arr[5];
	bm_state.textureThreshold = bm_state_arr[6];
	bm_state.uniquenessRatio = bm_state_arr[7];
	bm_state.ndisp_unit = bm_state_arr[8];
	bm_state.sweepFactor = bm_state_arr[9];
	bm_state.remainder = bm_state_arr[10];

	int _cm_size = 9, _dc_size = 5;

	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_L(rows,cols);
#pragma HLS stream variable=mat_L.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_R(rows,cols);
#pragma HLS stream variable=mat_R.data depth=2
	xf::Mat<XF_16UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_disp(rows,cols);
#pragma HLS stream variable=mat_disp.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxLMat(rows,cols);
#pragma HLS stream variable=mapxLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyLMat(rows,cols);
#pragma HLS stream variable=mapyLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxRMat(rows,cols);
#pragma HLS stream variable=mapxRMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyRMat(rows,cols);
#pragma HLS stream variable=mapyRMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> leftRemappedMat(rows,cols);
#pragma HLS stream variable=leftRemappedMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> rightRemappedMat(rows,cols);
#pragma HLS stream variable=rightRemappedMat.data depth=2

#pragma HLS DATAFLOW

	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_L,mat_L);
	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_R,mat_R);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_l_fix,distC_l_fix,irA_l_fix,mapxLMat,mapyLMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_L,leftRemappedMat,mapxLMat,mapyLMat);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_r_fix,distC_r_fix,irA_r_fix,mapxRMat,mapyRMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_R,rightRemappedMat,mapxRMat,mapyRMat);

	xf::StereoBM<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS,XF_8UC1,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(leftRemappedMat, rightRemappedMat, mat_disp, bm_state);

	xf::xfMat2Array<OUTPUT_PTR_WIDTH,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(mat_disp,img_disp);
}
}


/***************************************************************************
All rights reserved.

***************************************************************************/
#include "xf_stereo_pipeline_config.h"

extern "C" {
void stereopipeline_accel(ap_uint<INPUT_PTR_WIDTH> *img_L, ap_uint<INPUT_PTR_WIDTH> *img_R, ap_uint<OUTPUT_PTR_WIDTH> *img_disp,
	ap_fixed<32,12> *cameraMA_l, ap_fixed<32,12> *cameraMA_r, ap_fixed<32,12> *distC_l, ap_fixed<32,12> *distC_r, ap_fixed<32,12> *irA_l,
	ap_fixed<32,12> *irA_r, int *bm_state_arr, int rows, int cols)
{
#pragma HLS INTERFACE m_axi     port=img_L  offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi     port=img_R  offset=slave bundle=gmem5
#pragma HLS INTERFACE m_axi     port=img_disp  offset=slave bundle=gmem6
#pragma HLS INTERFACE m_axi     port=cameraMA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=cameraMA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=distC_l  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=distC_r  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=irA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=irA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=bm_state_arr  offset=slave bundle=gmem4
#pragma HLS INTERFACE s_axilite port=rows               bundle=control
#pragma HLS INTERFACE s_axilite port=cols               bundle=control
#pragma HLS INTERFACE s_axilite port=return                bundle=control

	ap_fixed<32,12> cameraMA_l_fix[XF_CAMERA_MATRIX_SIZE], cameraMA_r_fix[XF_CAMERA_MATRIX_SIZE], distC_l_fix[XF_DIST_COEFF_SIZE], distC_r_fix[XF_DIST_COEFF_SIZE], irA_l_fix[XF_CAMERA_MATRIX_SIZE], irA_r_fix[XF_CAMERA_MATRIX_SIZE];

	for (int i=0; i<XF_CAMERA_MATRIX_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		cameraMA_l_fix[i] = cameraMA_l[i];
		cameraMA_r_fix[i] = cameraMA_r[i];
		irA_l_fix[i] = irA_l[i];
		irA_r_fix[i] = irA_r[i];
	}
	for (int i=0; i<XF_DIST_COEFF_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		distC_l_fix[i] = distC_l[i];
		distC_r_fix[i] = distC_r[i];
	}

	xf::xFSBMState<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS> bm_state;
	bm_state.preFilterType = bm_state_arr[0];
	bm_state.preFilterSize = bm_state_arr[1];
	bm_state.preFilterCap = bm_state_arr[2];
	bm_state.SADWindowSize = bm_state_arr[3];
	bm_state.minDisparity = bm_state_arr[4];
	bm_state.numberOfDisparities = bm_state_arr[5];
	bm_state.textureThreshold = bm_state_arr[6];
	bm_state.uniquenessRatio = bm_state_arr[7];
	bm_state.ndisp_unit

	bm_state.sweepFactor = bm_state_arr[9];
	bm_state.remainder = bm_state_arr[10];

	int _cm_size = 9, _dc_size = 5;

	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_L(rows,cols);
#pragma HLS stream variable=mat_L.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_R(rows,cols);
#pragma HLS stream variable=mat_R.data depth=2
	xf::Mat<XF_16UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_disp(rows,cols);
#pragma HLS stream variable=mat_disp.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxLMat(rows,cols);
#pragma HLS stream variable=mapxLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyLMat(rows,cols);
#pragma HLS stream variable=mapyLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxRMat(rows,cols);
#pragma HLS stream variable=mapxRMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyRMat(rows,cols);
#pragma HLS stream variable=mapyRMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> leftRemappedMat(rows,cols);
#pragma HLS stream variable=leftRemappedMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> rightRemappedMat(rows,cols);
#pragma HLS stream variable=rightRemappedMat.data depth=2

#pragma HLS DATAFLOW

	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_L,mat_L);
	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_R,mat_R);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_l_fix,distC_l_fix,irA_l_fix,mapxLMat,mapyLMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_L,leftRemappedMat,mapxLMat,mapyLMat);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_r_fix,distC_r_fix,irA_r_fix,mapxRMat,mapyRMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_R,rightRemappedMat,mapxRMat,mapyRMat);

	xf::StereoBM<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS,XF_8UC1,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(leftRemappedMat, rightRemappedMat, mat_disp, bm_state);

	xf::xfMat2Array<OUTPUT_PTR_WIDTH,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(mat_disp,img_disp);
}
}


for (int i=0; i<XF_CAMERA_MATRIX_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		cameraMA_l_fix[i] = cameraMA_l[i];
		cameraMA_r_fix[i] = cameraMA_r[i];
		irA_l_fix[i] = irA_l[i];
		irA_r_fix[i] = irA_r[i];
	}

/***************************************************************************
All rights reserved.

***************************************************************************/
#include "xf_stereo_pipeline_config.h"

extern "C" {
void stereopipeline_accel(ap_uint<INPUT_PTR_WIDTH> *img_L, ap_uint<INPUT_PTR_WIDTH> *img_R, ap_uint<OUTPUT_PTR_WIDTH> *img_disp,
	ap_fixed<32,12> *cameraMA_l, ap_fixed<32,12> *cameraMA_r, ap_fixed<32,12> *distC_l, ap_fixed<32,12> *distC_r, ap_fixed<32,12> *irA_l,
	ap_fixed<32,12> *irA_r, int *bm_state_arr, int rows, int cols)
{
#pragma HLS INTERFACE m_axi     port=img_L  offset=slave bundle=gmem1
#pragma HLS INTERFACE m_axi     port=img_R  offset=slave bundle=gmem5
#pragma HLS INTERFACE m_axi     port=img_disp  offset=slave bundle=gmem6
#pragma HLS INTERFACE m_axi     port=cameraMA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=cameraMA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=distC_l  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=distC_r  offset=slave bundle=gmem3
#pragma HLS INTERFACE m_axi     port=irA_l  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=irA_r  offset=slave bundle=gmem2
#pragma HLS INTERFACE m_axi     port=bm_state_arr  offset=slave bundle=gmem4
#pragma HLS INTERFACE s_axilite port=rows               bundle=control
#pragma HLS INTERFACE s_axilite port=cols               bundle=control
#pragma HLS INTERFACE s_axilite port=return                bundle=control

	ap_fixed<32,12> cameraMA_l_fix[XF_CAMERA_MATRIX_SIZE], cameraMA_r_fix[XF_CAMERA_MATRIX_SIZE], distC_l_fix[XF_DIST_COEFF_SIZE], distC_r_fix[XF_DIST_COEFF_SIZE], irA_l_fix[XF_CAMERA_MATRIX_SIZE], irA_r_fix[XF_CAMERA_MATRIX_SIZE];

	for (int i=0; i<XF_DIST_COEFF_SIZE; i++)
	{
#pragma HLS PIPELINE II=1
		distC_l_fix[i] = distC_l[i];
		distC_r_fix[i] = distC_r[i];
	}

	xf::xFSBMState<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS> bm_state;
	bm_state.preFilterType = bm_state_arr[0];
	bm_state.preFilterSize = bm_state_arr[1];
	bm_state.preFilterCap = bm_state_arr[2];
	bm_state.SADWindowSize = bm_state_arr[3];
	bm_state.minDisparity = bm_state_arr[4];
	bm_state.numberOfDisparities = bm_state_arr[5];
	bm_state.textureThreshold = bm_state_arr[6];
	bm_state.uniquenessRatio = bm_state_arr[7];
	bm_state.ndisp_unit = bm_state_arr[8];
	bm_state.sweepFactor = bm_state_arr[9];
	bm_state.remainder = bm_state_arr[10];

	int _cm_size = 9, _dc_size = 5;

	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_L(rows,cols);
#pragma HLS stream variable=mat_L.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_R(rows,cols);
#pragma HLS stream variable=mat_R.data depth=2
	xf::Mat<XF_16UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mat_disp(rows,cols);
#pragma HLS stream variable=mat_disp.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxLMat(rows,cols);
#pragma HLS stream variable=mapxLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyLMat(rows,cols);
#pragma HLS stream variable=mapyLMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapxRMat(rows,cols);
#pragma HLS stream variable=mapxRMat.data depth=2
	xf::Mat<XF_32FC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> mapyRMat(rows,cols);
#pragma HLS stream variable=mapyRMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> leftRemappedMat(rows,cols);
#pragma HLS stream variable=leftRemappedMat.data depth=2
	xf::Mat<XF_8UC1, XF_HEIGHT, XF_WIDTH, XF_NPPC1> rightRemappedMat(rows,cols);
#pragma HLS stream variable=rightRemappedMat.data depth=2

#pragma HLS DATAFLOW

	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_L,mat_L);
	xf::Array2xfMat<INPUT_PTR_WIDTH,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(img_R,mat_R);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_l_fix,distC_l_fix,irA_l_fix,mapxLMat,mapyLMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_L,leftRemappedMat,mapxLMat,mapyLMat);

	xf::InitUndistortRectifyMapInverse<XF_CAMERA_MATRIX_SIZE,XF_DIST_COEFF_SIZE,XF_32FC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(cameraMA_r_fix,distC_r_fix,irA_r_fix,mapxRMat,mapyRMat,_cm_size,_dc_size);
	xf::remap<XF_REMAP_BUFSIZE,XF_INTERPOLATION_BILINEAR,XF_8UC1,XF_32FC1,XF_8UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(mat_R,rightRemappedMat,mapxRMat,mapyRMat);

	xf::StereoBM<SAD_WINDOW_SIZE,NO_OF_DISPARITIES,PARALLEL_UNITS,XF_8UC1,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1,XF_USE_URAM>(leftRemappedMat, rightRemappedMat, mat_disp, bm_state);

	xf::xfMat2Array<OUTPUT_PTR_WIDTH,XF_16UC1,XF_HEIGHT,XF_WIDTH,XF_NPPC1>(mat_disp,img_disp);
}
}


bool WebGPUComputePipeline::recompile(const WebGPUDevice& device)

/*
 *
 */

#include "config.h"
#include "WebGPUComputePipeline.h"

#if ENABLE(WEBGPU)

#include "GPUComputePipeline.h"
#include "GPUErrorScopes.h"
#include "GPUPipeline.h"
#include "GPUProgrammableStageDescriptor.h"
#include "GPUShaderModule.h"
#include "GPUShaderModuleDescriptor.h"
#include "WebGPUDevice.h"
#include "WebGPUShaderModule.h"
#include <wtf/Optional.h>
#include <wtf/Ref.h>

namespace WebCore {

Ref<WebGPUComputePipeline> WebGPUComputePipeline::create(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
{
    return adoptRef(*new WebGPUComputePipeline(device, WTFMove(pipeline), errorScopes, WTFMove(computeShader)));
}

WebGPUComputePipeline::WebGPUComputePipeline(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
    : WebGPUPipeline(device, errorScopes)
    , m_computePipeline(WTFMove(pipeline))
    , m_computeShader(WTFMove(computeShader))
{
}

WebGPUComputePipeline::~WebGPUComputePipeline() = default;

bool WebGPUComputePipeline::cloneShaderModules(const WebGPUDevice& device)
{
    if (m_computeShader.module) {
        const auto& computeSource = m_computeShader.module->source();
        m_computeShader.module = WebGPUShaderModule::create(GPUShaderModule::tryCreate(device.device(), { computeSource }), computeSource);
        return true;
    }
    return false;
}

{
    if (m_computePipeline && m_computeShader.module) {
        if (auto* gpuComputeShaderModule = m_computeShader.module->module()) {
            GPUProgrammableStageDescriptor computeStage(makeRef(*gpuComputeShaderModule), { m_computeShader.entryPoint });
            return m_computePipeline->recompile(device.device(), WTFMove(computeStage));
        }
    }
    return false;
}

} // namespace WebCore

#endif // ENABLE(WEBGPU)


{
    if (m_computeShader.module) {
        const auto& computeSource = m_computeShader.module->source();
        m_computeShader.module = WebGPUShaderModule::create(GPUShaderModule::tryCreate(device.device(), { computeSource }), computeSource);
        return true;
    }
    return false;
}

/*
 *
 */

#include "config.h"
#include "WebGPUComputePipeline.h"

#if ENABLE(WEBGPU)

#include "GPUComputePipeline.h"
#include "GPUErrorScopes.h"
#include "GPUPipeline.h"
#include "GPUProgrammableStageDescriptor.h"
#include "GPUShaderModule.h"
#include "GPUShaderModuleDescriptor.h"
#include "WebGPUDevice.h"
#include "WebGPUShaderModule.h"
#include <wtf/Optional.h>
#include <wtf/Ref.h>

namespace WebCore {

Ref<WebGPUComputePipeline> WebGPUComputePipeline::create(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
{
    return adoptRef(*new WebGPUComputePipeline(device, WTFMove(pipeline), errorScopes, WTFMove(computeShader)));
}

WebGPUComputePipeline::WebGPUComputePipeline(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
    : WebGPUPipeline(device, errorScopes)
    , m_computePipeline(WTFMove(pipeline))
    , m_computeShader(WTFMove(computeShader))
{
}

WebGPUComputePipeline::~WebGPUComputePipeline() = default;

bool WebGPUComputePipeline::cloneShaderModules(const WebGPUDevice& device)

bool WebGPUComputePipeline::recompile(const WebGPUDevice& device)
{
    if (m_computePipeline && m_computeShader.module) {
        if (auto* gpuComputeShaderModule = m_computeShader.module->module()) {
            GPUProgrammableStageDescriptor computeStage(makeRef(*gpuComputeShaderModule), { m_computeShader.entryPoint });
            return m_computePipeline->recompile(device.device(), WTFMove(computeStage));
        }
    }
    return false;
}

} // namespace WebCore

#endif // ENABLE(WEBGPU)


/*
 *
 */

#include "config.h"
#include "WebGPUComputePipeline.h"

#if ENABLE(WEBGPU)

#include "GPUComputePipeline.h"
#include "GPUErrorScopes.h"
#include "GPUPipeline.h"
#include "GPUProgrammableStageDescriptor.h"
#include "GPUShaderModule.h"
#include "GPUShaderModuleDescriptor.h"
#include "WebGPUDevice.h"
#include "WebGPUShaderModule.h"
#include <wtf/Optional.h>
#include <wtf/Ref.h>

namespace WebCore {

Ref<WebGPUComputePipeline> WebGPUComputePipeline::create(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
{
    return adoptRef(*new WebGPUComputePipeline(device, WTFMove(pipeline), errorScopes, WTFMove(computeShader)));
}

WebGPUComputePipeline::WebGPUComputePipeline(WebGPUDevice& device, RefPtr<GPUComputePipeline>&& pipeline, GPUErrorScopes& errorScopes, WebGPUPipeline::ShaderData&& computeShader)
    : WebGPUPipeline(device, errorScopes)
    , m_computePipeline(WTFMove(pipeline))
    , m_computeShader(WTFMove(computeShader))
{
}

WebGPUComputePipeline::~WebGPUComputePipeline() = default;

bool WebGPUComputePipeline::cloneShaderModules(const WebGPUDevice& device)
{
    if (m_computeShader.module) {
        const auto& computeSource = m_computeShader.module->source();
        m_computeShader.module = WebGPUShaderModule::create(GPUShaderModule::tryCreate(device.device(), { computeSource }), computeSource);
        return true;
    }
    return false;
}

bool WebGPUComputePipeline::recompile(const WebGPUDevice& device)
{
    if (m_computePipeline && m_computeShader.module) {
        if (auto* gpuComputeShaderModule = m_computeShader.module->module()) {
            GPUProgrammableStageDescriptor computeStage(makeRef(*gpuComputeShaderModule), { m_computeShader.entryPoint });
            return m_computePipeline->recompile(device.device(), WTFMove(computeStage));
        }
    }
    r

}

} // namespace WebCore

#endif // ENABLE(WEBGPU)


// The developer of the original code and/or files is Tripwire, Inc.
// fcospeclist.cpp
// cFCOSpecList -- a list of iFCOSpec's with in a well defined order.

#include "stdfco.h"
#include "fcospeclist.h"
#include "fcospecutil.h"
#include "core/serializer.h"
#include "core/debug.h"
#include "core/errorutil.h"

// class cFCOSpecList-- a list of iFCOSpec's with a well defined order.

IMPLEMENT_TYPEDSERIALIZABLE(cFCOSpecList, _T("cFCOSpecList"), 0, 1)

cFCOSpecList::cFCOSpecList()
{
}

{
    Clear();
}

void cFCOSpecList::Clear()
{
    std::list<PairType>::iterator itr;

    for (itr = mAddedList.begin(); itr != mAddedList.end(); ++itr)
    {
        itr->first->Release();
        itr->second->Release();
    }

    mCanonicalList.clear();
    mAddedList.clear();
}

bool cFCOSpecList::IsEmpty() const
{
    return mAddedList.empty();
}

int cFCOSpecList::Size() const
{
    return mAddedList.size();
}

const cFCOSpecList& cFCOSpecList::operator=(const cFCOSpecList& rhs)
{
    Clear();

    cFCOSpecListAddedIter itr(rhs);

    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        Add(itr.Spec(), itr.Attr());
    }

    return *this;
}

void cFCOSpecList::Add(iFCOSpec* pSpec, cFCOSpecAttr* pAttr)
{
    std::list<PairType>::iterator itr;
    pSpec->AddRef();
    if (pAttr == 0)
        pAttr = new cFCOSpecAttr;
    else
        pAttr->AddRef();
    for (itr = mCanonicalList.begin();; ++itr)
    {
        if (itr == mCanonicalList.end() || iFCOSpecUtil::FCOSpecLessThan(*pSpec, *itr->first))
        {
            mCanonicalList.insert(itr, PairType(pSpec, pAttr));
            mAddedList.push_back(PairType(pSpec, pAttr));
            break;
        }
    }
}

iFCOSpec* cFCOSpecList::Lookup(iFCOSpec* pSpec) const
{
    std::list<PairType>::iterator itr;
    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (itr->first == pSpec)
        {
            pSpec->AddRef();
            return itr->first;
        }

    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (iFCOSpecUtil::FCOSpecEqual(*pSpec, *itr->first))
        {
            itr->first->AddRef();
            return itr->first;
        }

    return NULL;
}

void cFCOSpecList::Read(iSerializer* pSerializer, int32 version)
{
    if (version > Version())
        ThrowAndAssert(eSerializerVersionMismatch(_T("FCO Spec List")));

    Clear();

    int   i;
    int32 size;
    pSerializer->ReadInt32(size);

    for (i = 0; i < size; ++i)
    {
        iFCOSpec*     pReadInSpec = static_cast<iFCOSpec*>(pSerializer->ReadObjectDynCreate());
        cFCOSpecAttr* pSpecAttr   = static_cast<cFCOSpecAttr*>(pSerializer->ReadObjectDynCreate());
        Add(pReadInSpec, pSpecAttr);
        pReadInSpec->Release(); // Add() will increase the ref count by 1
        pSpecAttr->Release();
    }
}

void cFCOSpecList::Write(iSerializer* pSerializer) const
{
    pSerializer->WriteInt32(Size());

    cFCOSpecListAddedIter itr(*this);
    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        pSerializer->WriteObjectDynCreate(itr.Spec());
        pSerializer->WriteObjectDynCreate(itr.Attr());
    }
}

// class cFCOSpecListAddedIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListAddedIter::cFCOSpecListAddedIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mAddedList.begin();
}

cFCOSpecListAddedIter::~cFCOSpecListAddedIter()
{
}

void cFCOSpecListAddedIter::SeekBegin() const
{
    mIter = mpSpecList->mAddedList.begin();
}

bool cFCOSpecListAddedIter::Done() const
{
    return mIter == mpSpecList->mAddedList.end();
}

bool cFCOSpecListAddedIter::IsEmpty() const
{
    return mpSpecList->mAddedList.empty();
}

void cFCOSpecListAddedIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListAddedIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListAddedIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListAddedIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListAddedIter::Attr()
{
    return mIter->second;
}

void cFCOSpecListAddedIter::Remove()
{
    ASSERT(!Done());

    // the tricky part is finding the spec in the other list...
    std::list<cFCOSpecList::PairType>::iterator i;
    for (i = mpSpecList->mCanonicalList.begin(); i != mpSpecList->mCanonicalList.end(); ++i)
    {
        if (i->first == mIter->first)
            break;
    }
    ASSERT(i != mpSpecList->mCanonicalList.end());

    // now to do the deleteing!
    mIter = mpSpecList->mAddedList.erase(mIter);
    mpSpecList->mCanonicalList.erase(i);
}

// class cFCOSpecListCanonicalIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListCanonicalIter::cFCOSpecListCanonicalIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mCanonicalList.begin();
}

cFCOSpecListCanonicalIter::~cFCOSpecListCanonicalIter()
{
}

void cFCOSpecListCanonicalIter::SeekBegin() const
{
    mIter = mpSpecList->mCanonicalList.begin();
}

bool cFCOSpecListCanonicalIter::Done() const
{
    return mIter == mpSpecList->mCanonicalList.end();
}

bool cFCOSpecListCanonicalIter::IsEmpty() const
{
    return mpSpecList->mCanonicalList.empty();
}

void cFCOSpecListCanonicalIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListCanonicalIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListCanonicalIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr()
{
    return mIter->second;
}


{
    return mpSpecList->mCanonicalList.empty();
}

// The developer of the original code and/or files is Tripwire, Inc.
// fcospeclist.cpp
// cFCOSpecList -- a list of iFCOSpec's with in a well defined order.

#include "stdfco.h"
#include "fcospeclist.h"
#include "fcospecutil.h"
#include "core/serializer.h"
#include "core/debug.h"
#include "core/errorutil.h"

// class cFCOSpecList-- a list of iFCOSpec's with a well defined order.

IMPLEMENT_TYPEDSERIALIZABLE(cFCOSpecList, _T("cFCOSpecList"), 0, 1)

cFCOSpecList::cFCOSpecList()
{
}

cFCOSpecList::~cFCOSpecList()
{
    Clear();
}

void cFCOSpecList::Clear()
{
    std::list<PairType>::iterator itr;

    for (itr = mAddedList.begin(); itr != mAddedList.end(); ++itr)
    {
        itr->first->Release();
        itr->second->Release();
    }

    mCanonicalList.clear();
    mAddedList.clear();
}

bool cFCOSpecList::IsEmpty() const
{
    return mAddedList.empty();
}

int cFCOSpecList::Size() const
{
    return mAddedList.size();
}

const cFCOSpecList& cFCOSpecList::operator=(const cFCOSpecList& rhs)
{
    Clear();

    cFCOSpecListAddedIter itr(rhs);

    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        Add(itr.Spec(), itr.Attr());
    }

    return *this;
}

void cFCOSpecList::Add(iFCOSpec* pSpec, cFCOSpecAttr* pAttr)
{
    std::list<PairType>::iterator itr;
    pSpec->AddRef();
    if (pAttr == 0)
        pAttr = new cFCOSpecAttr;
    else
        pAttr->AddRef();
    for (itr = mCanonicalList.begin();; ++itr)
    {
        if (itr == mCanonicalList.end() || iFCOSpecUtil::FCOSpecLessThan(*pSpec, *itr->first))
        {
            mCanonicalList.insert(itr, PairType(pSpec, pAttr));
            mAddedList.push_back(PairType(pSpec, pAttr));
            break;
        }
    }
}

iFCOSpec* cFCOSpecList::Lookup(iFCOSpec* pSpec) const
{
    std::list<PairType>::iterator itr;
    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (itr->first == pSpec)
        {
            pSpec->AddRef();
            return itr->first;
        }

    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (iFCOSpecUtil::FCOSpecEqual(*pSpec, *itr->first))
        {
            itr->first->AddRef();
            return itr->first;
        }

    return NULL;
}

void cFCOSpecList::Read(iSerializer* pSerializer, int32 version)
{
    if (version > Version())
        ThrowAndAssert(eSerializerVersionMismatch(_T("FCO Spec List")));

    Clear();

    int   i;
    int32 size;
    pSerializer->ReadInt32(size);

    for (i = 0; i < size; ++i)
    {
        iFCOSpec*     pReadInSpec = static_cast<iFCOSpec*>(pSerializer->ReadObjectDynCreate());
        cFCOSpecAttr* pSpecAttr   = static_cast<cFCOSpecAttr*>(pSerializer->ReadObjectDynCreate());
        Add(pReadInSpec, pSpecAttr);
        pReadInSpec->Release(); // Add() will increase the ref count by 1
        pSpecAttr->Release();
    }
}

void cFCOSpecList::Write(iSerializer* pSerializer) const
{
    pSerializer->WriteInt32(Size());

    cFCOSpecListAddedIter itr(*this);
    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        pSerializer->WriteObjectDynCreate(itr.Spec());
        pSerializer->WriteObjectDynCreate(itr.Attr());
    }
}

// class cFCOSpecListAddedIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListAddedIter::cFCOSpecListAddedIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mAddedList.begin();
}

cFCOSpecListAddedIter::~cFCOSpecListAddedIter()
{
}

void cFCOSpecListAddedIter::SeekBegin() const
{
    mIter = mpSpecList->mAddedList.begin();
}

bool cFCOSpecListAddedIter::Done() const
{
    return mIter == mpSpecList->mAddedList.end();
}

bool cFCOSpecListAddedIter::IsEmpty() const
{
    return mpSpecList->mAddedList.empty();
}

void cFCOSpecListAddedIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListAddedIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListAddedIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListAddedIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListAddedIter::Attr()
{
    return mIter->second;
}

void cFCOSpecListAddedIter::Remove()
{
    ASSERT(!Done());

    // the tricky part is finding the spec in the other list...
    std::list<cFCOSpecList::PairType>::iterator i;
    for (i = mpSpecList->mCanonicalList.begin(); i != mpSpecList->mCanonicalList.end(); ++i)
    {
        if (i->first == mIter->first)
            break;
    }
    ASSERT(i != mpSpecList->mCanonicalList.end());

    // now to do the deleteing!
    mIter = mpSpecList->mAddedList.erase(mIter);
    mpSpecList->mCanonicalList.erase(i);
}

// class cFCOSpecListCanonicalIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListCanonicalIter::cFCOSpecListCanonicalIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mCanonicalList.begin();
}

cFCOSpecListCanonicalIter::~cFCOSpecListCanonicalIter()
{
}

void cFCOSpecListCanonicalIter::SeekBegin() const
{
    mIter = mpSpecList->mCanonicalList.begin();
}

bool cFCOSpecListCanonicalIter::Done() const
{
    return mIter == mpSpecList->mCanonicalList.end();
}

bool cFCOSpecListCanonicalIter::IsEmpty() const

void cFCOSpecListCanonicalIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListCanonicalIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListCanonicalIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr()
{
    return mIter->second;
}


// The developer of the original code and/or files is Tripwire, Inc.
// fcospeclist.cpp
// cFCOSpecList -- a list of iFCOSpec's with in a well defined order.

#include "stdfco.h"
#include "fcospeclist.h"
#include "fcospecutil.h"
#include "core/serializer.h"
#include "core/debug.h"
#include "core/errorutil.h"

// class cFCOSpecList-- a list of iFCOSpec's with a well defined order.

IMPLEMENT_TYPEDSERIALIZABLE(cFCOSpecList, _T("cFCOSpecList"), 0, 1)

cFCOSpecList::cFCOSpecList()
{
}

cFCOSpecList::~cFCOSpecList()
{
    Clear();
}

void cFCOSpecList::Clear()
{
    std::list<PairType>::iterator itr;

    for (itr = mAddedList.begin(); itr != mAddedList.end(); ++itr)
    {
        itr->first->Release();
        itr->second->Release();
    }

    mCanonicalList.clear();
    mAddedList.clear();
}

bool cFCOSpecList::IsEmpty() const
{
    return mAddedList.empty();
}

int cFCOSpecList::Size() const
{
    return mAddedList.size();
}

const cFCOSpecList& cFCOSpecList::operator=(const cFCOSpecList& rhs)
{
    Clear();

    cFCOSpecListAddedIter itr(rhs);

    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        Add(itr.Spec(), itr.Attr());
    }

    return *this;
}

void cFCOSpecList::Add(iFCOSpec* pSpec, cFCOSpecAttr* pAttr)
{
    std::list<PairType>::iterator itr;
    pSpec->AddRef();
    if (pAttr == 0)
        pAttr = new cFCOSpecAttr;
    else
        pAttr->AddRef();
    for (itr = mCanonicalList.begin();; ++itr)
    {
        if (itr == mCanonicalList.end() || iFCOSpecUtil::FCOSpecLessThan(*pSpec, *itr->first))
        {
            mCanonicalList.insert(itr, PairType(pSpec, pAttr));
            mAddedList.push_back(PairType(pSpec, pAttr));
            break;
        }
    }
}

iFCOSpec* cFCOSpecList::Lookup(iFCOSpec* pSpec) const
{
    std::list<PairType>::iterator itr;
    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (itr->first == pSpec)
        {
            pSpec->AddRef();
            return itr->first;
        }

    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (iFCOSpecUtil::FCOSpecEqual(*pSpec, *itr->first))
        {
            itr->first->AddRef();
            return itr->first;
        }

    return NULL;
}

void cFCOSpecList::Read(iSerializer* pSerializer, int32 version)
{
    if (version > Version())
        ThrowAndAssert(eSerializerVersionMismatch(_T("FCO Spec List")));

    Clear();

    int   i;
    int32 size;
    pSerializer->ReadInt32(size);

    for (i = 0; i < size; ++i)
    {
        iFCOSpec*     pReadInSpec = static_cast<iFCOSpec*>(pSerializer->ReadObjectDynCreate());
        cFCOSpecAttr* pSpecAttr   = static_cast<cFCOSpecAttr*>(pSerializer->ReadObjectDynCreate());
        Add(pReadInSpec, pSpecAttr);
        pReadInSpec->Release(); // Add() will increase the ref count by 1
        pSpecAttr->Release();
    }
}

void cFCOSpecList::Write(iSerializer* pSerializer) const
{
    pSerializer->WriteInt32(Size());

    cFCOSpecListAddedIter itr(*this);
    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        pSerializer->WriteObjectDynCreate(itr.Spec());
        pSerializer->WriteObjectDynCreate(itr.Attr());
    }
}

// class cFCOSpecListAddedIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListAddedIter::cFCOSpecListAddedIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mAddedList.begin();
}

cFCOSpecListAddedIter::~cFCOSpecListAddedIter()
{
}

void cFCOSpecListAddedIter::SeekBegin() const
{
    mIter = mpSpecList->mAddedList.begin();
}

bool cFCOSpecListAddedIter::Done() const
{
    return mIter == mpSpecList->mAddedList.end();
}

bool cFCOSpecListAddedIter::IsEmpty() const
{
    return mpSpecList->mAddedList.empty();
}

void cFCOSpecListAddedIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListAddedIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListAddedIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListAddedIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListAddedIter::Attr()
{
    return mIter->second;
}

void cFCOSpecListAddedIter::Remove()
{
    ASSERT(!Done());

    // the tricky part is finding the spec in the other list...
    std::list<cFCOSpecList::PairType>::iterator i;
    for (i = mpSpecList->mCanonicalList.begin(); i != mpSpecList->mCanonicalList.end(); ++i)
    {
        if (i->first == mIter->first)
            break;
    }
    ASSERT(i != mpSpecList->mCanonicalList.end());

    // now to do the deleteing!
    mIter = mpSpecList->mAddedList.erase(mIter);
    mpSpecList->mCanonicalList.erase(i);
}

// class cFCOSpecListCanonicalIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListCanonicalIter::cFCOSpecListCanonicalIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mI

}

cFCOSpecListCanonicalIter::~cFCOSpecListCanonicalIter()
{
}

void cFCOSpecListCanonicalIter::SeekBegin() const
{
    mIter = mpSpecList->mCanonicalList.begin();
}

bool cFCOSpecListCanonicalIter::Done() const
{
    return mIter == mpSpecList->mCanonicalList.end();
}

bool cFCOSpecListCanonicalIter::IsEmpty() const
{
    return mpSpecList->mCanonicalList.empty();
}

void cFCOSpecListCanonicalIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListCanonicalIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListCanonicalIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr()
{
    return mIter->second;
}


cFCOSpecListAddedIter::cFCOSpecListAddedIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mAddedList.begin();
}

// The developer of the original code and/or files is Tripwire, Inc.
// fcospeclist.cpp
// cFCOSpecList -- a list of iFCOSpec's with in a well defined order.

#include "stdfco.h"
#include "fcospeclist.h"
#include "fcospecutil.h"
#include "core/serializer.h"
#include "core/debug.h"
#include "core/errorutil.h"

// class cFCOSpecList-- a list of iFCOSpec's with a well defined order.

IMPLEMENT_TYPEDSERIALIZABLE(cFCOSpecList, _T("cFCOSpecList"), 0, 1)

cFCOSpecList::cFCOSpecList()
{
}

cFCOSpecList::~cFCOSpecList()
{
    Clear();
}

void cFCOSpecList::Clear()
{
    std::list<PairType>::iterator itr;

    for (itr = mAddedList.begin(); itr != mAddedList.end(); ++itr)
    {
        itr->first->Release();
        itr->second->Release();
    }

    mCanonicalList.clear();
    mAddedList.clear();
}

bool cFCOSpecList::IsEmpty() const
{
    return mAddedList.empty();
}

int cFCOSpecList::Size() const
{
    return mAddedList.size();
}

const cFCOSpecList& cFCOSpecList::operator=(const cFCOSpecList& rhs)
{
    Clear();

    cFCOSpecListAddedIter itr(rhs);

    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        Add(itr.Spec(), itr.Attr());
    }

    return *this;
}

void cFCOSpecList::Add(iFCOSpec* pSpec, cFCOSpecAttr* pAttr)
{
    std::list<PairType>::iterator itr;
    pSpec->AddRef();
    if (pAttr == 0)
        pAttr = new cFCOSpecAttr;
    else
        pAttr->AddRef();
    for (itr = mCanonicalList.begin();; ++itr)
    {
        if (itr == mCanonicalList.end() || iFCOSpecUtil::FCOSpecLessThan(*pSpec, *itr->first))
        {
            mCanonicalList.insert(itr, PairType(pSpec, pAttr));
            mAddedList.push_back(PairType(pSpec, pAttr));
            break;
        }
    }
}

iFCOSpec* cFCOSpecList::Lookup(iFCOSpec* pSpec) const
{
    std::list<PairType>::iterator itr;
    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (itr->first == pSpec)
        {
            pSpec->AddRef();
            return itr->first;
        }

    for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr)
        if (iFCOSpecUtil::FCOSpecEqual(*pSpec, *itr->first))
        {
            itr->first->AddRef();
            return itr->first;
        }

    return NULL;
}

void cFCOSpecList::Read(iSerializer* pSerializer, int32 version)
{
    if (version > Version())
        ThrowAndAssert(eSerializerVersionMismatch(_T("FCO Spec List")));

    Clear();

    int   i;
    int32 size;
    pSerializer->ReadInt32(size);

    for (i = 0; i < size; ++i)
    {
        iFCOSpec*     pReadInSpec = static_cast<iFCOSpec*>(pSerializer->ReadObjectDynCreate());
        cFCOSpecAttr* pSpecAttr   = static_cast<cFCOSpecAttr*>(pSerializer->ReadObjectDynCreate());
        Add(pReadInSpec, pSpecAttr);
        pReadInSpec->Release(); // Add() will increase the ref count by 1
        pSpecAttr->Release();
    }
}

void cFCOSpecList::Write(iSerializer* pSerializer) const
{
    pSerializer->WriteInt32(Size());

    cFCOSpecListAddedIter itr(*this);
    for (itr.SeekBegin(); !itr.Done(); itr.Next())
    {
        pSerializer->WriteObjectDynCreate(itr.Spec());
        pSerializer->WriteObjectDynCreate(itr.Attr());
    }
}

// class cFCOSpecListAddedIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListAddedIter::~cFCOSpecListAddedIter()
{
}

void cFCOSpecListAddedIter::SeekBegin() const
{
    mIter = mpSpecList->mAddedList.begin();
}

bool cFCOSpecListAddedIter::Done() const
{
    return mIter == mpSpecList->mAddedList.end();
}

bool cFCOSpecListAddedIter::IsEmpty() const
{
    return mpSpecList->mAddedList.empty();
}

void cFCOSpecListAddedIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListAddedIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListAddedIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListAddedIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListAddedIter::Attr()
{
    return mIter->second;
}

void cFCOSpecListAddedIter::Remove()
{
    ASSERT(!Done());

    // the tricky part is finding the spec in the other list...
    std::list<cFCOSpecList::PairType>::iterator i;
    for (i = mpSpecList->mCanonicalList.begin(); i != mpSpecList->mCanonicalList.end(); ++i)
    {
        if (i->first == mIter->first)
            break;
    }
    ASSERT(i != mpSpecList->mCanonicalList.end());

    // now to do the deleteing!
    mIter = mpSpecList->mAddedList.erase(mIter);
    mpSpecList->mCanonicalList.erase(i);
}

// class cFCOSpecListCanonicalIter -- iterate using the order in which items were
//      added to this list.

cFCOSpecListCanonicalIter::cFCOSpecListCanonicalIter(const cFCOSpecList& list)
{
    mpSpecList = (cFCOSpecList*)&list;
    mIter      = mpSpecList->mCanonicalList.begin();
}

cFCOSpecListCanonicalIter::~cFCOSpecListCanonicalIter()
{
}

void cFCOSpecListCanonicalIter::SeekBegin() const
{
    mIter = mpSpecList->mCanonicalList.begin();
}

bool cFCOSpecListCanonicalIter::Done() const
{
    return mIter == mpSpecList->mCanonicalList.end();
}

bool cFCOSpecListCanonicalIter::IsEmpty() const
{
    return mpSpecList->mCanonicalList.empty();
}

void cFCOSpecListCanonicalIter::Next() const
{
    ++mIter;
}

const iFCOSpec* cFCOSpecListCanonicalIter::Spec() const
{
    return mIter->first;
}

iFCOSpec* cFCOSpecListCanonicalIter::Spec()
{
    return mIter->first;
}
const cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() const
{
    return mIter->second;
}
cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr()
{
    return mIter->second;
}