summaryrefslogtreecommitdiff
path: root/oox/inc/oox/ole/axbinarywriter.hxx
blob: eb4aec532d1f68846c550b82e8fe8883e4a2b73c (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * Version: MPL 1.1 / GPLv3+ / LGPLv3+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 * [ Copyright (C) 2011 Noel Power<noel.power@suse.com> (initial developer) ]
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
 * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
 * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
 * instead of those above.
 */
#ifndef OOX_OLE_AXBINARYWRITER_HXX
#define OOX_OLE_AXBINARYWRITER_HXX

#include <utility>
#include "oox/helper/binaryoutputstream.hxx"
#include "oox/helper/refvector.hxx"

namespace oox {
namespace ole {
// ============================================================================

/** A wrapper for a binary output stream that supports aligned write operations.

    The implementation does support seeking back the wrapped stream. All
    seeking operations (tell, seekTo, align) are performed relative to the
    position of the wrapped stream at construction time of this wrapper.
    Unlike it's reader class counterpart it is NOT possible to construct this
    wrapper with an unseekable output stream.
 */
class AxAlignedOutputStream : public BinaryOutputStream
{
public:
    explicit            AxAlignedOutputStream( BinaryOutputStream& rOutStrm );

    /** Returns the size of the data this stream represents, if the wrapped
        stream supports the size() operation. */
    virtual sal_Int64   size() const;
    /** Return the current relative stream position (relative to position of
        the wrapped stream at construction time). */
    virtual sal_Int64   tell() const;
    /** Seeks the stream to the passed relative position, if it is behind the
        current position. */
    virtual void        seek( sal_Int64 nPos );
    /** Closes the input stream but not the wrapped stream. */
    virtual void        close();

    /** Reads nBytes bytes to the passed sequence.
        @return  Number of bytes really read. */
    virtual void writeData( const StreamDataSequence& orData, size_t nAtomSize = 1 );
    /** Reads nBytes bytes to the (existing) buffer opMem.
        @return  Number of bytes really read. */
    virtual void   writeMemory( const void* pMem, sal_Int32 nBytes, size_t nAtomSize = 1 );

    /** Aligns the stream to a multiple of the passed size (relative to the
        position of the wrapped stream at construction time). */
    void                align( size_t nSize );

    void         pad( sal_Int32 nBytes, size_t nAtomSize = 1);
    /** Aligns the stream according to the passed type and reads a value. */
    template< typename Type >
    inline void         writeAligned( Type nVal ) { align( sizeof( Type ) ); writeValue( nVal ); }
    /** Aligns the stream according to the passed type and skips the size of the type. */
    template< typename Type >
    inline void         padAligned() { align( sizeof( Type ) ); pad( sizeof( Type ) ); }

private:
    BinaryOutputStream*  mpOutStrm;           ///< The wrapped input stream.
    sal_Int64           mnStrmPos;          ///< Tracks relative position in the stream.
    sal_Int64           mnStrmSize;         ///< Size of the wrapped stream data.
    sal_Int64           mnWrappedBeginPos;     ///< starting pos or wrapped stream
};

/** A pair of integer values as a property. */
typedef ::std::pair< sal_Int32, sal_Int32 > AxPairData;

/** An array of string values as a property. */
typedef ::std::vector< OUString > AxStringArray;

// ============================================================================

/** Export helper to write simple and complex ActiveX form control properties
    to a binary input stream. */
class AxBinaryPropertyWriter
{
public:
    explicit            AxBinaryPropertyWriter( BinaryOutputStream& rOutStrm, bool b64BitPropFlags = false );

    /** Write an integer property value to the stream, the
        respective flag in the property mask is set. */
    template< typename StreamType, typename DataType >
    inline void         writeIntProperty( DataType& ornValue )
                            { if( startNextProperty() ) maOutStrm.writeAligned< StreamType >( ornValue ); }
    /** Write a boolean property value to the stream, the
        respective flag in the property mask is set. */
    void                writeBoolProperty( bool orbValue, bool bReverse = false );
    /** Write a pair property the stream, the respective flag in
        the property mask is set. */
    void                writePairProperty( AxPairData& orPairData );
    /** Write a string property to the stream, the respective flag
        in the property mask is set. */
    void                writeStringProperty( OUString& orValue, bool bCompressed = true );

    /** Skips the next property clears the respective
        flag in the property mask. */
    inline void         skipProperty() { startNextProperty( true ); }

    /** Final processing, write contents of all complex properties, writes record size */
    bool                finalizeExport();

private:
    bool                ensureValid( bool bCondition = true );
    bool                startNextProperty( bool bSkip = false );

private:
    /** Base class for complex properties such as string, point, size, GUID, picture. */
    struct ComplexProperty
    {
        virtual             ~ComplexProperty();
        virtual bool        writeProperty( AxAlignedOutputStream& rOutStrm ) = 0;
    };

    /** Complex property for a 32-bit value pair, e.g. point or size. */
    struct PairProperty : public ComplexProperty
    {
        AxPairData&         mrPairData;

        inline explicit     PairProperty( AxPairData& rPairData ) :
                                mrPairData( rPairData ) {}
        virtual bool        writeProperty( AxAlignedOutputStream& rOutStrm );
    };

    /** Complex property for a string value. */
    struct StringProperty : public ComplexProperty
    {
        OUString&    mrValue;
        sal_uInt32          mnSize;

        inline explicit     StringProperty( OUString& rValue, sal_uInt32 nSize ) :
                                mrValue( rValue ), mnSize( nSize ) {}
        virtual bool        writeProperty( AxAlignedOutputStream& rOutStrm );
    };

    /** Stream property for a picture or mouse icon. */
    struct PictureProperty : public ComplexProperty
    {
        StreamDataSequence& mrPicData;

        inline explicit     PictureProperty( StreamDataSequence& rPicData ) :
                                mrPicData( rPicData ) {}
        virtual bool        writeProperty( AxAlignedOutputStream& rOutStrm );
    };

    typedef RefVector< ComplexProperty > ComplexPropVector;

private:
    AxAlignedOutputStream maOutStrm;        ///< The input stream to read from.
    ComplexPropVector   maLargeProps;       ///< Stores info for all used large properties.
    ComplexPropVector   maStreamProps;      ///< Stores info for all used stream data properties.
    AxPairData          maDummyPairData;    ///< Dummy pair for unsupported properties.
    StreamDataSequence  maDummyPicData;     ///< Dummy picture for unsupported properties.
    OUString     maDummyString;      ///< Dummy string for unsupported properties.
    AxStringArray       maDummyStringArray; ///< Dummy string array for unsupported properties.
    sal_Int16           mnBlockSize;
    sal_Int64           mnPropFlagsStart;     ///< pos of Prop flags
    sal_Int64           mnPropFlags;        ///< Flags specifying existing properties.
    sal_Int64           mnNextProp;         ///< Next property to read.
    bool                mbValid;            ///< True = stream still valid.
    bool                mb64BitPropFlags;
};

// ============================================================================
} // namespace ole
} // namespace oox

#endif

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