This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,64 @@
PROJECT(openvibe-module-date)
SET(PROJECT_VERSION_MAJOR ${OV_GLOBAL_VERSION_MAJOR})
SET(PROJECT_VERSION_MINOR ${OV_GLOBAL_VERSION_MINOR})
SET(PROJECT_VERSION_PATCH ${OV_GLOBAL_VERSION_PATCH})
SET(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH})
SET(SRC_FILES
include/date/defines.h
include/date/DateParser.h
src/DateParser.cpp
)
IF(WIN32)
LIST(APPEND SRC_FILES
"include/date/WindowsDateParser.h"
"src/WindowsDateParser.cpp"
)
ENDIF()
INCLUDE_DIRECTORIES(include/date)
INCLUDE("FindSourceRCProperties")
ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC_FILES})
SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${MODULES_FOLDER}
COMPILE_FLAGS "-DDate_Shared -DDate_Exports")
ADD_LIBRARY(${PROJECT_NAME}-static STATIC ${SRC_FILES})
SET_TARGET_PROPERTIES(${PROJECT_NAME}-static PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
FOLDER ${MODULES_FOLDER}
COMPILE_FLAGS "-DDate_Static -DDate_Exports")
IF(UNIX)
SET_TARGET_PROPERTIES(${PROJECT_NAME}-static PROPERTIES COMPILE_FLAGS "-fPIC")
ENDIF(UNIX)
INCLUDE("FindOpenViBECommon")
INCLUDE("FindThirdPartyBoost")
INCLUDE("FindThirdPartyExpat")
# ---------------------------------
# Target macros
# Defines target operating system, architecture and compiler
# ---------------------------------
SET_BUILD_PLATFORM()
# -----------------------------
# Install files
# -----------------------------
INSTALL(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(TARGETS ${PROJECT_NAME}-static
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
INSTALL(DIRECTORY include/ DESTINATION ${DIST_INCLUDEDIR} FILES_MATCHING PATTERN "*.h" PATTERN)
@@ -0,0 +1,24 @@
#pragma once
#include "defines.h"
#if defined TARGET_OS_Windows
#include "WindowsDateParser.h"
#else
#include <ctime>
#endif
namespace DateParser {
class Date_API CDateParser
{
public:
/**
* \brief parse a string representing a date along a format given by a char*, and store it in a tm struct
* \param sStringToParse: the string to parse
* \param sDateFormat: the string that gives the format of the date to parse, example "%Y-%m-%d %H:%M"
* \param tmParsed: time parsed
*/
static char* strpTime(const char* sStringToParse, const char* sDateFormat, struct tm* tmParsed);
private:
CDateParser() = default;
};
} // namespace DateParser
@@ -0,0 +1,7 @@
#pragma once
#include "defines.h"
#include <ctime>
namespace DateParser {
extern Date_API char* windowsStrptime(const char* buf, const char* fmt, struct tm* tmParsed);
} // namespace DateParser
@@ -0,0 +1,25 @@
#pragma once
#include <ov_common_defines.h>
#if defined Date_Shared
# if defined TARGET_OS_Windows
# define Date_API_Export __declspec(dllexport)
# define Date_API_Import __declspec(dllimport)
# elif defined TARGET_OS_Linux
# define Date_API_Export __attribute__((visibility("default")))
# define Date_API_Import __attribute__((visibility("default")))
# else
# define Date_API_Export
# define Date_API_Import
# endif
#else
# define Date_API_Export
# define Date_API_Import
#endif
#if defined Date_Exports
# define Date_API Date_API_Export
#else
# define Date_API Date_API_Import
#endif
@@ -0,0 +1,14 @@
#include "DateParser.h"
namespace DateParser {
char* CDateParser::strpTime(const char* sStringToParse, const char* sDateFormat, struct tm* tmParsed)
{
#if defined TARGET_OS_Windows
return windowsStrptime(sStringToParse, sDateFormat, tmParsed);
#else
return strptime(sStringToParse, sDateFormat, tmParsed);
#endif
}
} // namespace DateParser
@@ -0,0 +1,357 @@
/* $Id$ */
/* $NetBSD: windowsStrptime.c,v 1.18 1999/04/29 02:58:30 tv Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code was contributed to The NetBSD Foundation by Klaus Klein.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <array>
#if defined TARGET_OS_Windows
#include <iostream>
#include "WindowsDateParser.h"
namespace DateParser {
/*
* We do not implement alternate representations. However, we always
* check whether a given modifier is allowed for a certain conversion.
*/
#define ALT_E 0x01
#define ALT_O 0x02
#define LEGAL_ALT(x) if (alt_format & ~(x)) { return 0; }
#define EPOCH_YEAR 1970
#define SECSPERHOUR 3600
#define SECSPERDAY 86400
#define TM_YEAR_BASE 1900
static int ConvNum(const char** buf, int* dest, const int llim, const int ulim);
static const std::array<const std::string, 7> DAY = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
static const std::array<const std::string, 7> AB_DAY = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
static const std::array<const std::string, 12> MON = {
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
};
static const std::array<const std::string, 12> AB_MON = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
static const std::array<const std::string, 2> AM_PM = { "AM", "PM" };
Date_API char* DateParser::windowsStrptime(const char* buf, const char* fmt, struct tm* tmParsed)
{
char c;
const char* bp;
size_t len = 0;
int i, split_year = 0;
bp = buf;
while ((c = *fmt) != '\0')
{
/* Clear `alternate' modifier prior to new conversion. */
int alt_format = 0;
/* Eat up white-space. */
if (isspace(c))
{
while (isspace(*bp)) { bp++; }
fmt++;
continue;
}
if ((c = *fmt++) != '%') { goto literal; }
again: switch (c = *fmt++)
{
case '%': /* "%%" is converted to "%". */
literal :
if (c != *bp++) { return (nullptr); }
break;
/*
* "Alternative" modifiers. Just set the appropriate flag
* and start over again.
*/
case 'E': /* "%E?" alternative conversion modifier. */
LEGAL_ALT(0);
alt_format |= ALT_E;
goto again;
case 'O': /* "%O?" alternative conversion modifier. */
LEGAL_ALT(0);
alt_format |= ALT_O;
goto again;
/*
* "Complex" conversion rules, implemented through recursion.
*/
case 'c': /* Date and time, using the locale's format. */
LEGAL_ALT(ALT_E);
if (!((bp = windowsStrptime(bp, "%x %X", tmParsed)))) { return nullptr; }
break;
case 'D': /* The date as "%m/%d/%y". */
LEGAL_ALT(0);
if (!((bp = windowsStrptime(bp, "%m/%d/%y", tmParsed)))) { return nullptr; }
break;
case 'R': /* The time as "%H:%M". */
LEGAL_ALT(0);
if (!((bp = windowsStrptime(bp, "%H:%M", tmParsed)))) { return nullptr; }
break;
case 'r': /* The time in 12-hour clock representation. */
LEGAL_ALT(0);
if (!((bp = windowsStrptime(bp, "%I:%M:%S %p", tmParsed)))) { return nullptr; }
break;
case 'T': /* The time as "%H:%M:%S". */
LEGAL_ALT(0);
if (!((bp = windowsStrptime(bp, "%H:%M:%S", tmParsed)))) { return nullptr; }
break;
case 'X': /* The time, using the locale's format. */
LEGAL_ALT(ALT_E);
if (!((bp = windowsStrptime(bp, "%H:%M:%S", tmParsed)))) { return nullptr; }
break;
case 'x': /* The date, using the locale's format. */
LEGAL_ALT(ALT_E);
if (!((bp = windowsStrptime(bp, "%m/%d/%y", tmParsed)))) { return nullptr; }
break;
/*
* "Elementary" conversion rules.
*/
case 'A': /* The day of week, using the locale's form. */
case 'a':
LEGAL_ALT(0);
for (i = 0; i < 7; ++i)
{
/* Full name. */
len = DAY[i].size();
if (strncmp(DAY[i].c_str(), bp, len) == 0) { break; }
/* Abbreviated name. */
len = AB_DAY[i].size();
if (strncmp(AB_DAY[i].c_str(), bp, len) == 0) { break; }
}
/* Nothing matched. */
if (i == 7) { return nullptr; }
tmParsed->tm_wday = i;
bp += len;
break;
case 'B': /* The month, using the locale's form. */
case 'b':
case 'h':
LEGAL_ALT(0);
for (i = 0; i < 12; ++i)
{
/* Full name. */
len = MON[i].size();
if (strncmp(MON[i].c_str(), bp, len) == 0) { break; }
/* Abbreviated name. */
len = AB_MON[i].size();
if (strncmp(AB_MON[i].c_str(), bp, len) == 0) { break; }
}
/* Nothing matched. */
if (i == 12) { return (nullptr); }
tmParsed->tm_mon = i;
bp += len;
break;
case 'C': /* The century number. */
LEGAL_ALT(ALT_E);
if (!(ConvNum(&bp, &i, 0, 99))) { return (nullptr); }
if (split_year) { tmParsed->tm_year = (tmParsed->tm_year % 100) + (i * 100); }
else
{
tmParsed->tm_year = i * 100;
split_year = 1;
}
break;
case 'd': /* The day of month. */
case 'e':
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_mday, 1, 31))) { return (nullptr); }
break;
case 'k': /* The hour (24-hour clock representation). */
LEGAL_ALT(0);
/* FALLTHROUGH */
case 'H':
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_hour, 0, 23))) { return (nullptr); }
break;
case 'l': /* The hour (12-hour clock representation). */
LEGAL_ALT(0);
/* FALLTHROUGH */
case 'I':
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_hour, 1, 12))) { return (nullptr); }
if (tmParsed->tm_hour == 12) { tmParsed->tm_hour = 0; }
break;
case 'j': /* The day of year. */
LEGAL_ALT(0);
if (!(ConvNum(&bp, &i, 1, 366))) { return (nullptr); }
tmParsed->tm_yday = i - 1;
break;
case 'M': /* The minute. */
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_min, 0, 59))) { return (nullptr); }
break;
case 'm': /* The month. */
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &i, 1, 12))) { return (nullptr); }
tmParsed->tm_mon = i - 1;
break;
case 'p': /* The locale's equivalent of AM/PM. */
LEGAL_ALT(0);
/* AM? */
if (strcmp(AM_PM[0].c_str(), bp) == 0)
{
if (tmParsed->tm_hour > 11) { return (nullptr); }
bp += AM_PM[0].size();
break;
}
/* PM? */
if (strcmp(AM_PM[1].c_str(), bp) == 0)
{
if (tmParsed->tm_hour > 11) { return (nullptr); }
tmParsed->tm_hour += 12;
bp += AM_PM[1].size();
break;
}
/* Nothing matched. */
return nullptr;
case 'S': /* The seconds. */
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_sec, 0, 61))) { return (nullptr); }
break;
case 'U': /* The week of year, beginning on sunday. */
case 'W': /* The week of year, beginning on monday. */
LEGAL_ALT(ALT_O);
/*
* XXX This is bogus, as we can not assume any valid
* information present in the tm structure at this
* point to calculate a real value, so just check the
* range for now.
*/
if (!(ConvNum(&bp, &i, 0, 53))) { return (nullptr); }
break;
case 'w': /* The day of week, beginning on sunday. */
LEGAL_ALT(ALT_O);
if (!(ConvNum(&bp, &tmParsed->tm_wday, 0, 6))) { return (nullptr); }
break;
case 'Y': /* The year. */
LEGAL_ALT(ALT_E);
if (!(ConvNum(&bp, &i, 0, 9999))) { return (nullptr); }
tmParsed->tm_year = i - TM_YEAR_BASE;
break;
case 'y': /* The year within 100 years of the epoch. */
LEGAL_ALT(ALT_E | ALT_O);
if (!(ConvNum(&bp, &i, 0, 99))) { return (nullptr); }
if (split_year)
{
tmParsed->tm_year = ((tmParsed->tm_year / 100) * 100) + i;
break;
}
split_year = 1;
if (i <= 68) { tmParsed->tm_year = i + 2000 - TM_YEAR_BASE; }
else { tmParsed->tm_year = i + 1900 - TM_YEAR_BASE; }
break;
/*
* Miscellaneous conversions.
*/
case 'n': /* Any kind of white-space. */
case 't':
LEGAL_ALT(0);
while (isspace(*bp)) { bp++; }
break;
default: return nullptr; /* Unknown/unsupported conversion. */
}
}
/* LINTED functional specification */
return const_cast<char*>(bp);
}
static int ConvNum(const char** buf, int* dest, const int llim, const int ulim)
{
int result = 0;
/* The limit also determines the number of valid digits. */
int rulim = ulim;
if (**buf < '0' || **buf > '9') { return (0); }
do
{
result *= 10;
result += *(*buf)++ - '0';
rulim /= 10;
} while ((result * 10 <= ulim) && rulim && **buf >= '0' && **buf <= '9');
if (result < llim || result > ulim) { return 0; }
*dest = result;
return 1;
}
} // namespace DateParser
#endif