blob: 597f0fce1958c0a7ae465b63c2bd60d253884a09 [file] [log] [blame]
/*
* 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.
*/
#if defined(_MSC_VER)
#pragma warning ( disable: 4231 4251 4275 4786 )
#endif
#include <log4cxx/ndc.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/threadspecificdata.h>
using namespace log4cxx;
using namespace log4cxx::helpers;
NDC::NDC(const std::string& message)
{
push(message);
}
NDC::~NDC()
{
pop();
}
LogString& NDC::getMessage(NDC::DiagnosticContext& ctx)
{
return ctx.first;
}
LogString& NDC::getFullMessage(NDC::DiagnosticContext& ctx)
{
return ctx.second;
}
void NDC::clear()
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
while (!stack.empty())
{
stack.pop();
}
data->recycle();
}
}
NDC::Stack* NDC::cloneStack()
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
return new Stack(stack);
}
}
return new Stack();
}
void NDC::inherit(NDC::Stack* stack)
{
if (stack != NULL)
{
ThreadSpecificData::inherit(*stack);
delete stack;
}
}
bool NDC::get(LogString& dest)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
dest.append(getFullMessage(stack.top()));
return true;
}
data->recycle();
}
return false;
}
int NDC::getDepth()
{
int size = 0;
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
size = (int)data->getStack().size();
if (size == 0)
{
data->recycle();
}
}
return size;
}
LogString NDC::pop()
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
LogString value(getMessage(stack.top()));
stack.pop();
data->recycle();
return value;
}
data->recycle();
}
return LogString();
}
bool NDC::pop(std::string& dst)
{
bool retval = false;
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(getMessage(stack.top()), dst);
stack.pop();
retval = true;
}
data->recycle();
}
return retval;
}
LogString NDC::peek()
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
return getMessage(stack.top());
}
data->recycle();
}
return LogString();
}
bool NDC::peek(std::string& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(getMessage(stack.top()), dst);
return true;
}
data->recycle();
}
return false;
}
void NDC::pushLS(const LogString& message)
{
ThreadSpecificData::push(message);
}
void NDC::push(const std::string& message)
{
LOG4CXX_DECODE_CHAR(msg, message);
pushLS(msg);
}
void NDC::remove()
{
clear();
}
bool NDC::empty()
{
bool empty = true;
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
empty = stack.empty();
if (empty)
{
data->recycle();
}
}
return empty;
}
#if LOG4CXX_WCHAR_T_API
NDC::NDC(const std::wstring& message)
{
push(message);
}
void NDC::push(const std::wstring& message)
{
LOG4CXX_DECODE_WCHAR(msg, message);
pushLS(msg);
}
bool NDC::pop(std::wstring& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(getMessage(stack.top()), dst);
stack.pop();
data->recycle();
return true;
}
data->recycle();
}
return false;
}
bool NDC::peek(std::wstring& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(getMessage(stack.top()), dst);
return true;
}
data->recycle();
}
return false;
}
#endif
#if LOG4CXX_UNICHAR_API
NDC::NDC(const std::basic_string<UniChar>& message)
{
push(message);
}
void NDC::push(const std::basic_string<UniChar>& message)
{
LOG4CXX_DECODE_UNICHAR(msg, message);
pushLS(msg);
}
bool NDC::pop(std::basic_string<UniChar>& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(stack.top().message, dst);
stack.pop();
data->recycle();
return true;
}
data->recycle();
}
return false;
}
bool NDC::peek(std::basic_string<UniChar>& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
Transcoder::encode(stack.top().message, dst);
return true;
}
data->recycle();
}
return false;
}
#endif
#if LOG4CXX_CFSTRING_API
NDC::NDC(const CFStringRef& message)
{
push(message);
}
void NDC::push(const CFStringRef& message)
{
LOG4CXX_DECODE_CFSTRING(msg, message);
pushLS(msg);
}
bool NDC::pop(CFStringRef& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
dst = Transcoder::encode(getMessage(stack.top()));
stack.pop();
data->recycle();
return true;
}
data->recycle();
}
return false;
}
bool NDC::peek(CFStringRef& dst)
{
ThreadSpecificData* data = ThreadSpecificData::getCurrentData();
if (data != 0)
{
Stack& stack = data->getStack();
if (!stack.empty())
{
dst = Transcoder::encode(getMessage(stack.top()));
return true;
}
data->recycle();
}
return false;
}
#endif