summaryrefslogtreecommitdiff
path: root/filter/source/svg/test/odfserializer.cxx
blob: 838c4e9f8d164ce6d50e3a9e939ceadb7f68f2ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 *    OpenOffice.org - a multi-platform office productivity suite
 *
 *    Author:
 *      Fridrich Strba  <fridrich.strba@bluewin.ch>
 *      Thorsten Behrens <tbehrens@novell.com>
 *
 *      Copyright (C) 2008, Novell Inc.
 *      Parts copyright 2005 by Sun Microsystems, Inc.
 *
 *   The Contents of this file are made available subject to
 *   the terms of GNU Lesser General Public License Version 3.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"

#include "odfserializer.hxx"
#include <osl/diagnose.h>
#include <rtl/ustrbuf.hxx>
#include <cppuhelper/compbase1.hxx>
#include <cppuhelper/basemutex.hxx>
#include <com/sun/star/uno/Sequence.hxx>
#include <boost/noncopyable.hpp>

using namespace ::com::sun::star;

namespace svgi
{

typedef ::cppu::WeakComponentImplHelper1<
    com::sun::star::xml::sax::XDocumentHandler> ODFSerializerBase;

class ODFSerializer : private cppu::BaseMutex,
                public ODFSerializerBase,
                boost::noncopyable
{
public:
    explicit ODFSerializer(const uno::Reference<io::XOutputStream>& xOut) :
        ODFSerializerBase(m_aMutex),
        m_xOutStream(xOut),
        m_aLineFeed(1),
        m_aBuf()
    {
        m_aLineFeed[0] = '\n';
    }

    virtual void SAL_CALL startDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL endDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL startElement( const ::rtl::OUString& aName, const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL processingInstruction( const ::rtl::OUString& aTarget, const ::rtl::OUString& aData ) throw (xml::sax::SAXException, uno::RuntimeException);
    virtual void SAL_CALL setDocumentLocator( const uno::Reference< xml::sax::XLocator >& xLocator ) throw (xml::sax::SAXException, uno::RuntimeException);

private:
    uno::Reference<io::XOutputStream> m_xOutStream;
    uno::Sequence<sal_Int8>           m_aLineFeed;
    uno::Sequence<sal_Int8>           m_aBuf;
};

void SAL_CALL ODFSerializer::startDocument(  ) throw (xml::sax::SAXException, uno::RuntimeException)
{
    OSL_PRECOND(m_xOutStream.is(), "ODFSerializer(): invalid output stream");

    rtl::OUStringBuffer aElement;
    aElement.appendAscii("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    characters(aElement.makeStringAndClear());
}

void SAL_CALL ODFSerializer::endDocument() throw (xml::sax::SAXException, uno::RuntimeException)
{}

void SAL_CALL ODFSerializer::startElement( const ::rtl::OUString& aName,
                                           const uno::Reference< xml::sax::XAttributeList >& xAttribs ) throw (xml::sax::SAXException, uno::RuntimeException)
{
    rtl::OUStringBuffer aElement;
    aElement.appendAscii("<");
    aElement.append(aName);
    aElement.appendAscii(" ");

    const sal_Int16 nLen=xAttribs->getLength();
    for( sal_Int16 i=0; i<nLen; ++i )
    {
        rtl::OUStringBuffer aAttribute;
        aElement.append(xAttribs->getNameByIndex(i));
        aElement.appendAscii("=\"");
        aElement.append(xAttribs->getValueByIndex(i));
        aElement.appendAscii("\" ");
    }

    aElement.appendAscii(">");
    characters(aElement.makeStringAndClear());
}

void SAL_CALL ODFSerializer::endElement( const ::rtl::OUString& aName ) throw (xml::sax::SAXException, uno::RuntimeException)
{
    rtl::OUStringBuffer aElement;
    aElement.appendAscii("</");
    aElement.append(aName);
    aElement.appendAscii(">");
    characters(aElement.makeStringAndClear());
}

void SAL_CALL ODFSerializer::characters( const ::rtl::OUString& aChars ) throw (xml::sax::SAXException, uno::RuntimeException)
{
    const rtl::OString aStr = rtl::OUStringToOString(aChars,
                                                     RTL_TEXTENCODING_UTF8);
    const sal_Int32 nLen( aStr.getLength() );
    m_aBuf.realloc( nLen );
    const sal_Char* pStr = aStr.getStr();
    std::copy(pStr,pStr+nLen,m_aBuf.getArray());

    m_xOutStream->writeBytes(m_aBuf);
    // TODO(F1): Make pretty printing configurable
    m_xOutStream->writeBytes(m_aLineFeed);
}

void SAL_CALL ODFSerializer::ignorableWhitespace( const ::rtl::OUString& aWhitespaces ) throw (xml::sax::SAXException, uno::RuntimeException)
{
    // TODO(F1): Make pretty printing configurable
    characters(aWhitespaces);
}

void SAL_CALL ODFSerializer::processingInstruction( const ::rtl::OUString&,
                                                    const ::rtl::OUString& ) throw (xml::sax::SAXException, uno::RuntimeException)
{}

void SAL_CALL ODFSerializer::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& ) throw (xml::sax::SAXException, uno::RuntimeException)
{}

uno::Reference< xml::sax::XDocumentHandler> createSerializer(const uno::Reference<io::XOutputStream>& xOut )
{
    return uno::Reference<xml::sax::XDocumentHandler>(new ODFSerializer(xOut));
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */