38#include "blocxx/BLOCXX_config.h"
54#ifdef BLOCXX_HAVE_UNISTD_H
68namespace LogMessagePatternFormatterImpl
95using namespace LogMessagePatternFormatterImpl;
186 (*i)->formatMessage(message, output);
198class MessageConverter :
public Converter
205 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
207 output += message.message;
211#define CDATA_START_DEF "<![CDATA["
212#define CDATA_END_DEF "]]>"
213#define CDATA_PSEUDO_END_DEF "]]>"
221class XMLMessageConverter :
public Converter
224 XMLMessageConverter(
const Formatting&
formatting)
228 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
230 output += CDATA_START;
231 const String& msg(message.message);
234 size_t end = msg.indexOf(CDATA_END);
243 output.append(&msg[start], end - start);
244 output += CDATA_EMBEDDED_END;
245 start = end +
static_cast<String
>(CDATA_END).length();
246 if (start < msg.length())
248 end = msg.indexOf(CDATA_END, start);
261class LiteralConverter :
public Converter
264 LiteralConverter(
const String&
literal)
268 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
278class ThreadConverter :
public Converter
285 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
292class PidConverter :
public Converter
299 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
302 output += ::GetCurrentProcessId();
304 output += ::getpid();
310class ComponentConverter :
public Converter
313 ComponentConverter(
const Formatting&
formatting,
int precision)
318 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
322 output += message.component;
326 const String& component(message.component);
327 size_t len(component.length());
331 end = component.lastIndexOf(
'.', end - 1);
338 output += component.substring(end + 1, len - (end + 1));
347class FileLocationConverter :
public Converter
350 FileLocationConverter(
const Formatting&
formatting)
354 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
356 if (message.filename != 0)
358 output += message.filename;
364class FullLocationConverter :
public Converter
367 FullLocationConverter(
const Formatting&
formatting)
371 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
373 if (message.filename != 0)
375 output += message.filename;
377 output += message.fileline;
384class LineLocationConverter :
public Converter
387 LineLocationConverter(
const Formatting&
formatting)
391 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
393 output += message.fileline;
398class MethodLocationConverter :
public Converter
401 MethodLocationConverter(
const Formatting&
formatting)
405 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
407 if (message.methodname != 0)
409 output += message.methodname;
415class CategoryConverter :
public Converter
418 CategoryConverter(
const Formatting&
formatting)
422 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
424 output += message.category;
429class RelativeTimeConverter :
public Converter
432 RelativeTimeConverter(
const Formatting&
formatting)
436 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
438 output += getRelativeTime();
442 static UInt64 getRelativeTime()
449 static UInt64 getNowMillis()
453 return UInt64(now.get()) * 1000 + (now.getMicrosecond() / 1000);
470class DateConverter :
public Converter
473 DateConverter(
const Formatting&
formatting,
const String& format)
477 size_t pos =
m_format.indexOf(
"%Q");
485 virtual void convert(
const LogMessage &message, StringBuffer &output)
const
494 size_t len = ::strftime(buf,
sizeof(buf),
m_format.c_str(), &nowTm);
499 char* p = strstr(buf,
"%Q");
504 long deciMillis = now.getMicrosecond() / 1000;
505 String strMillis(deciMillis);
507 switch (strMillis.length())
545 Parser(
const String& pattern_)
547 ,
state(E_LITERAL_STATE)
552 void parse(Array<ConverterRef>& converters)
555 size_t patternLength(
pattern.length());
557 while (
i < patternLength)
563 case E_LITERAL_STATE:
565 if (
i == patternLength)
586 converters.push_back(ConverterRef(
new LiteralConverter(
literal.toString())));
590 state = E_CONVERTER_STATE;
621 if (
i + 1 > patternLength)
631 int hexNumber = std::strtol(begin, &end, 16);
632 if (end == begin || errno == ERANGE || hexNumber > CHAR_MAX)
638 literal +=
static_cast<char>(hexNumber);
639 i += (end - begin) + 1;
655 case E_CONVERTER_STATE:
674 converters.push_back(finalizeConverter(c));
692 converters.push_back(finalizeConverter(c));
707 Format(
"Invalid pattern \"%1\" in position %2. Was expecting a digit, instead got char %3.",
722 converters.push_back(finalizeConverter(c));
723 state = E_LITERAL_STATE;
733 converters.push_back(ConverterRef(
new LiteralConverter(
literal.toString())));
743 size_t end =
pattern.indexOf(
'}',
i);
746 String rv =
pattern.substring(
i + 1, end - (
i + 1));
759 String opt = getOption();
767 catch (StringConversionException& e)
770 Format(
"Invalid pattern \"%1\" in position %2. A positive integer is required for precision option (%3).",
779 ConverterRef finalizeConverter(
char c)
787 rv =
new ComponentConverter(
formatting, getPrecision());
794 String dateOpt = getOption();
801 dateFormat = dateOpt;
818 rv =
new DateConverter(
formatting, dateFormat);
897 Format(
"Invalid pattern \"%1\" in position %2. Unsupported conversion (%3).",
906 state = E_LITERAL_STATE;
#define BLOCXX_DEFINE_EXCEPTION_WITH_ID(NAME)
Define a new exception class named <NAME>Exception that derives from Exception.
#define BLOCXX_THROW_ERR(exType, msg, err)
Throw an exception using FILE and LINE.
#define BLOCXX_GLOBAL_STRING_INIT(str)
V::const_iterator const_iterator
This class can be used to store a global variable that is lazily initialized in a thread safe manner.
StringBuffer & append(char c)
void truncate(size_t index)
Truncate the string at the given index.
This String class is an abstract data type that represents as NULL terminated string of characters.
String substring(size_t beginIndex, size_t length=npos) const
Create another String object that is comprised of a substring of this String object.
BLOCXX_COMMON_API UInt64 thread_t_ToUInt64(Thread_t thr)
Convert a Thread_t to an UInt64.
LazyGlobal< String, char const *const > GlobalString