📄 simpledateformat.cpp
字号:
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <log4cxx/logstring.h>
#include <log4cxx/helpers/simpledateformat.h>
#include <apr_time.h>
#include <apr_strings.h>
#include <sstream>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/stringhelper.h>
#include <assert.h>
#if !defined(LOG4CXX)
#define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/pool.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace std;
#if LOG4CXX_HAS_STD_LOCALE
#include <locale>
#endif
#if defined(_MSC_VER) && _MSC_VER < 1300
#define HAS_FACET(locale, type) _HAS(locale, type)
#define USE_FACET(locale, type) _USE(locale, type)
#define PUT_FACET(facet, os, time, spec) facet.put(os, os, time, spec)
#else
#if defined(_RWSTD_NO_TEMPLATE_ON_RETURN_TYPE)
#define HAS_FACET(locale, type) std::has_facet(locale, (type*) 0)
#define USE_FACET(locale, type) std::use_facet(locale, (type*) 0)
#else
#define HAS_FACET(locale, type) std::has_facet < type >(locale)
#define USE_FACET(locale, type) std::use_facet < type >(locale)
#endif
#define PUT_FACET(facet, os, time, spec) facet.put(os, os, os.fill(), time, spec)
#endif
namespace log4cxx
{
namespace helpers
{
namespace SimpleDateFormatImpl
{
typedef void (*incrementFunction)(tm& time, apr_time_exp_t& apr_time);
/**
* Abstract inner class representing one format token
* (one or more instances of a character).
*/
class PatternToken {
public:
PatternToken() {
}
virtual ~PatternToken() {
}
/**
* Sets the time zone.
* @param zone new time zone.
*/
virtual void setTimeZone(const TimeZonePtr& zone) {
}
/**
* Appends the formatted content to the string.
* @param s string to which format contribution is appended.
* @param date exploded date/time.
* @param p memory pool.
*/
virtual void format(LogString& s,
const apr_time_exp_t& date,
log4cxx::helpers::Pool& p) const = 0;
protected:
static void incrementMonth(tm& time, apr_time_exp_t& aprtime) {
time.tm_mon++;
aprtime.tm_mon++;
}
static void incrementDay(tm& time, apr_time_exp_t& aprtime) {
time.tm_wday++;
aprtime.tm_wday++;
}
static void incrementHalfDay(tm& time, apr_time_exp_t& aprtime) {
time.tm_hour += 12;
aprtime.tm_hour += 12;
}
static void renderFacet(const std::locale* locale,
incrementFunction inc,
char spec,
unsigned int wspec,
const char* aprspec,
std::vector<LogString>& values) {
std::vector<LogString>::iterator valueIter = values.begin();
tm time;
memset(&time, 0, sizeof(time));
apr_time_exp_t aprtime;
memset(&aprtime, 0, sizeof(aprtime));
#if LOG4CXX_HAS_STD_LOCALE
if (locale != NULL) {
#if LOG4CXX_WCHAR_T_API
if (HAS_FACET(*locale, std::time_put<wchar_t>)) {
const std::time_put<wchar_t>& facet = USE_FACET(*locale, std::time_put<wchar_t>);
size_t start = 0;
std::basic_ostringstream<wchar_t> os;
for(; valueIter != values.end(); valueIter++) {
PUT_FACET(facet, os, &time, (wchar_t) wspec);
Transcoder::decode(os.str().substr(start), *valueIter);
start = os.str().length();
(*inc)(time, aprtime);
}
} else
#endif
if (HAS_FACET(*locale, std::time_put<char>)) {
const std::time_put<char>& facet = USE_FACET(*locale, std::time_put<char> );
size_t start = 0;
std::ostringstream os;
for(; valueIter != values.end(); valueIter++) {
PUT_FACET(facet, os, &time, spec);
Transcoder::decode(os.str().substr(start), *valueIter);
start = os.str().length();
(*inc)(time, aprtime);
}
}
}
#endif
const size_t BUFSIZE = 256;
char buf[BUFSIZE];
memset(buf, 0, BUFSIZE);
apr_size_t retsize = 0;
for(; valueIter != values.end(); valueIter++) {
apr_status_t stat = apr_strftime(buf, &retsize, BUFSIZE, aprspec, &aprtime);
(*inc)(time, aprtime);
if (stat == APR_SUCCESS) {
Transcoder::decode(std::string(buf, retsize), *valueIter);
} else {
valueIter->append(1, (logchar) 0x3F);
}
}
}
private:
/**
* Private copy constructor.
*/
PatternToken(const PatternToken&);
/**
* Private assignment operator.
*/
PatternToken& operator=(const PatternToken&);
};
class LiteralToken : public PatternToken
{
public:
LiteralToken( logchar ch1, int count1 ) : ch( ch1 ), count( count1 )
{
}
void format( LogString& s, const apr_time_exp_t & , Pool & /* p */ ) const
{
s.append( count, ch );
}
private:
logchar ch;
int count;
};
class EraToken : public PatternToken
{
public:
EraToken( int /* count */ , const std::locale * /* locale */ )
{
}
void format(LogString& s, const apr_time_exp_t & /* tm */, Pool & /* p */ ) const
{
s.append(1, (logchar) 0x41 /* 'A' */);
s.append(1, (logchar) 0x44 /* 'D' */);
}
};
class NumericToken : public PatternToken
{
public:
NumericToken( size_t width1 ) : width( width1 )
{
}
virtual int getField( const apr_time_exp_t & tm ) const = 0;
void format( LogString& s, const apr_time_exp_t & tm, Pool & p ) const
{
size_t initialLength = s.length();
StringHelper::toString( getField( tm ), p, s );
size_t finalLength = s.length();
if ( initialLength + width > finalLength )
{
s.insert( initialLength, ( initialLength + width ) - finalLength, (logchar) 0x30 /* '0' */);
}
}
private:
size_t width;
char zeroDigit;
};
class YearToken : public NumericToken
{
public:
YearToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return 1900 + tm.tm_year;
}
};
class MonthToken : public NumericToken
{
public:
MonthToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return tm.tm_mon + 1;
}
};
class AbbreviatedMonthNameToken : public PatternToken
{
public:
AbbreviatedMonthNameToken(int, const std::locale *locale) : names( 12 ) {
renderFacet(locale, PatternToken::incrementMonth, 'b', 0x62, "%b", names);
}
void format(LogString& s, const apr_time_exp_t & tm, Pool & /* p */ ) const
{
s.append( names[tm.tm_mon] );
}
private:
std::vector < LogString > names;
};
class FullMonthNameToken : public PatternToken
{
public:
FullMonthNameToken( int width, const std::locale *locale) : names( 12 )
{
renderFacet(locale, PatternToken::incrementMonth, 'B', 0x42, "%B", names);
}
void format( LogString& s, const apr_time_exp_t & tm, Pool & /* p */ ) const
{
s.append( names[tm.tm_mon] );
}
private:
std::vector < LogString > names;
};
class WeekInYearToken : public NumericToken
{
public:
WeekInYearToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return tm.tm_yday / 7;
}
};
class WeekInMonthToken : public NumericToken
{
public:
WeekInMonthToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return tm.tm_mday / 7;
}
};
class DayInMonthToken : public NumericToken
{
public:
DayInMonthToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return tm.tm_mday;
}
};
class DayInYearToken : public NumericToken
{
public:
DayInYearToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & tm ) const
{
return tm.tm_yday;
}
};
class DayOfWeekInMonthToken : public NumericToken
{
public:
DayOfWeekInMonthToken( int width1 ) : NumericToken( width1 )
{
}
int getField( const apr_time_exp_t & /* tm */ ) const
{
return -1;
}
};
class AbbreviatedDayNameToken : public PatternToken
{
public:
AbbreviatedDayNameToken( int width, const std::locale *locale) : names( 7 ) {
renderFacet(locale, PatternToken::incrementDay, 'a', 0x61, "%a", names);
}
void format( LogString& s, const apr_time_exp_t & tm, Pool & /* p */ ) const
{
s.append( names[tm.tm_wday] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -