blob: cb9648d8dca80e282975e29db0a167e5caffe7f5 [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.
*/
// Class header file
#include "FormatterToText.hpp"
#include <xalanc/Include/XalanMemMgrAutoPtr.hpp>
#include <xalanc/PlatformSupport/Writer.hpp>
#include <xalanc/PlatformSupport/XalanOutputStream.hpp>
#include <xalanc/PlatformSupport/XalanTranscodingServices.hpp>
#if defined(XALAN_NEWLINE_IS_CRLF)
#include <xalanc/PlatformSupport/XalanUnicode.hpp>
#endif
namespace XALAN_CPP_NAMESPACE {
FormatterToText::FormatterToText(MemoryManager& theManager) :
FormatterListener(OUTPUT_METHOD_TEXT),
m_writer(0),
m_maxCharacter(XalanDOMChar(~0)),
m_encoding(theManager),
m_haveEncoding(false),
m_normalize(true),
m_handleIgnorableWhitespace(true),
m_newlineString(0),
m_newlineStringLength(0)
{
}
FormatterToText::FormatterToText(
Writer& writer,
bool normalizeLinefeed,
bool handleIgnorableWhitespace,
MemoryManager& theManager) :
FormatterListener(OUTPUT_METHOD_TEXT),
m_writer(&writer),
m_maxCharacter(XalanDOMChar(~0)),
m_encoding(theManager),
m_haveEncoding(false),
m_normalize(normalizeLinefeed),
m_handleIgnorableWhitespace(handleIgnorableWhitespace),
m_newlineString(0),
m_newlineStringLength(0)
{
update(true);
}
FormatterToText::FormatterToText(
Writer& writer,
const XalanDOMString& encoding,
bool normalizeLinefeed,
bool handleIgnorableWhitespace,
MemoryManager& theManager) :
FormatterListener(OUTPUT_METHOD_TEXT),
m_writer(&writer),
m_maxCharacter(0),
m_encoding(theManager),
m_haveEncoding(true),
m_normalize(normalizeLinefeed),
m_handleIgnorableWhitespace(handleIgnorableWhitespace),
m_newlineString(0),
m_newlineStringLength(0)
{
if(encoding.empty() == false)
{
m_encoding = encoding;
}
else
{
m_encoding = XalanDOMString(XalanTranscodingServices::s_utf8String, theManager);
}
update(false);
}
FormatterToText*
FormatterToText::create(
MemoryManager& theManager,
Writer& writer,
const XalanDOMString& encoding,
bool normalizeLinefeed,
bool handleIgnorableWhitespace)
{
typedef FormatterToText ThisType;
XalanAllocationGuard theGuard(theManager, theManager.allocate(sizeof(ThisType)));
ThisType* const theResult =
new (theGuard.get()) ThisType(
writer,
encoding,
normalizeLinefeed,
handleIgnorableWhitespace,
theManager);
theGuard.release();
return theResult;
}
FormatterToText::~FormatterToText()
{
}
void
FormatterToText::clearEncoding()
{
m_encoding.clear();
m_maxCharacter = XalanDOMChar(~0);
m_haveEncoding = false;
}
void
FormatterToText::setDocumentLocator(const Locator* const /* locator */)
{
// No action for the moment.
}
void
FormatterToText::startDocument()
{
// No action for the moment.
}
void
FormatterToText::endDocument()
{
assert(m_writer != 0);
m_writer->flush();
}
void
FormatterToText::startElement(
const XMLCh* const /* name */,
AttributeListType& /* attrs */)
{
// No action for the moment.
}
void
FormatterToText::endElement(
const XMLCh* const /* name */)
{
// No action for the moment.
}
void
FormatterToText::characters(
const XMLCh* const chars,
const size_type length)
{
assert(m_writer != 0);
if (m_normalize == false && m_haveEncoding == false)
{
m_writer->write(chars, 0, length);
}
else
{
size_type i = 0;
while (i < length)
{
if (chars[i] > m_maxCharacter)
{
//$$$ ToDo: Figure out what we're going to do here...
}
#if defined(XALAN_NEWLINE_IS_CRLF)
if (m_normalize == false)
{
m_writer->write(chars[i]);
}
else
{
// Normalize LF and CR/LF to the appropriate line ending sequence.
if (chars[i] == XalanUnicode::charLF)
{
m_writer->write(m_newlineString, 0, m_newlineStringLength);
}
else if (chars[i] == XalanUnicode::charCR &&
(i + 1 < length &&
chars[i + 1] == XalanUnicode::charLF))
{
m_writer->write(m_newlineString, 0, m_newlineStringLength);
++i;
}
else
{
m_writer->write(chars[i]);
}
}
#else
m_writer->write(chars[i]);
#endif
++i;
}
}
}
void
FormatterToText::charactersRaw(
const XMLCh* const chars,
const size_type length)
{
characters(chars, length);
}
void
FormatterToText::entityReference(const XMLCh* const /* name */)
{
// No action for the moment.
}
void
FormatterToText::ignorableWhitespace(
const XMLCh* const chars,
const size_type length)
{
if (m_handleIgnorableWhitespace == true)
{
characters(chars, length);
}
}
void
FormatterToText::processingInstruction(
const XMLCh* const /* target */,
const XMLCh* const /* data */)
{
// No action for the moment.
}
void
FormatterToText::resetDocument()
{
// No action for the moment.
}
void
FormatterToText::comment(const XMLCh* const /* data */)
{
// No action for the moment.
}
void
FormatterToText::cdata(
const XMLCh* const ch,
const size_type length)
{
characters(ch, length);
}
void
FormatterToText::update(bool fNormalizationOnly)
{
assert(m_writer != 0);
XalanOutputStream* const theStream = m_writer->getStream();
if (theStream == 0)
{
m_newlineString = XalanOutputStream::defaultNewlineString();
m_newlineStringLength = length(m_newlineString);
if (fNormalizationOnly == false)
{
// We're pretty much screwed here, since we can't transcode, so get the
// maximum character for the local code page.
m_maxCharacter = XalanTranscodingServices::getMaximumCharacterValue();
}
}
else
{
m_newlineString = theStream->getNewlineString();
assert(m_newlineString != 0);
m_newlineStringLength = length(m_newlineString);
if (fNormalizationOnly == false)
{
try
{
theStream->setOutputEncoding(m_encoding);
}
catch(const XalanOutputStream::UnsupportedEncodingException&)
{
const XalanDOMString theUTF8String(XalanTranscodingServices::s_utf8String, getMemoryManager());
// Default to UTF-8 if the requested encoding is not supported...
theStream->setOutputEncoding(theUTF8String);
m_encoding = theUTF8String;
m_haveEncoding = true;
}
m_maxCharacter = XalanTranscodingServices::getMaximumCharacterValue(theStream->getOutputEncoding());
}
}
}
}