merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / backend / binarywritehandler.cxx
blobbb168cb8a42f53660bb1dd0785e8890ab838b9d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: binarywritehandler.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
33 #include "binarywritehandler.hxx"
34 #include "binarycache.hxx"
35 #include <com/sun/star/util/XTimeStamped.hpp>
36 #include "typeconverter.hxx"
37 #include "simpletypehelper.hxx"
39 #define ASCII(x) rtl::OUString::createFromAscii(x)
40 namespace configmgr
42 // -----------------------------------------------------------------------------
43 namespace backend
46 namespace css = com::sun::star;
47 namespace util = css::util ;
49 // -----------------------------------------------------------------------------
51 BinaryWriteHandler::BinaryWriteHandler( rtl::OUString const & _aFileURL,
52 rtl::OUString const & _aComponentName,
53 uno::Reference<lang::XMultiServiceFactory> const & _aFactory)
54 : m_BinaryWriter(_aFileURL,_aFactory)
55 , m_aComponentName(_aComponentName)
59 // -----------------------------------------------------------------------------
60 static
61 binary::ValueFlags::Type convertTypeToValueType(uno::Type const& _aType)
63 binary::ValueFlags::Type eType = binary::ValueFlags::val_invalid;
64 uno::TypeClass const aClass = _aType.getTypeClass();
65 switch(aClass)
67 case uno::TypeClass_ANY:
68 eType = binary::ValueFlags::val_any;
69 break;
70 case uno::TypeClass_BOOLEAN:
71 eType = binary::ValueFlags::val_boolean;
72 break;
73 case uno::TypeClass_SHORT:
74 eType = binary::ValueFlags::val_int16;
75 break;
76 case uno::TypeClass_LONG:
77 eType = binary::ValueFlags::val_int32;
78 break;
79 case uno::TypeClass_HYPER:
80 eType = binary::ValueFlags::val_int64;
81 break;
82 case uno::TypeClass_DOUBLE:
83 eType = binary::ValueFlags::val_double;
84 break;
85 case uno::TypeClass_STRING:
86 eType = binary::ValueFlags::val_string;
87 break;
88 case uno::TypeClass_SEQUENCE:
89 if (_aType == SimpleTypeHelper::getBinaryType())
91 eType = binary::ValueFlags::val_binary;
93 else
95 uno::Type aType = configmgr::getSequenceElementType(_aType);
96 eType = convertTypeToValueType(aType);
98 OSL_ENSURE(!(eType & binary::ValueFlags::seq), "Binary Writer - Invalid value type: Multiple nesting of sequences");
99 eType = binary::ValueFlags::Type( eType | binary::ValueFlags::seq );
101 break;
102 default:
103 OSL_ENSURE(false, "Binary Writer - Invalid value type: not supported");
104 break;
106 return eType;
109 // -----------------------------------------------------------------------------
110 template <class T>
111 inline /* make performance crew happy ;-) */
112 void writeDirectly(BinaryWriter& _rWriter, T const& _aVal)
113 SAL_THROW( (io::IOException, uno::RuntimeException) )
115 _rWriter.write(_aVal);
117 // -----------------------------------------------------------------------------
118 static
119 inline
120 void writeDirectly(BinaryWriter& _rWriter, uno::Sequence<sal_Int8> const& _aBinary);
121 // -----------------------------------------------------------------------------
122 template <class T>
123 inline /* make performance crew happy ;-) */
124 void writeFromAny(BinaryWriter& _rWriter,uno::Any const& _aValue, T& _aVar)
125 SAL_THROW( (io::IOException, uno::RuntimeException) )
127 OSL_VERIFY(_aValue >>= _aVar ); // "Invalid Any for value"
128 writeDirectly(_rWriter,_aVar);
130 // -----------------------------------------------------------------------------
132 template <class Element>
133 void writeSequence(BinaryWriter& _rWriter, uno::Sequence< Element > const& aSequence)
134 SAL_THROW( (io::IOException, uno::RuntimeException) )
136 sal_Int32 const nLength = aSequence.getLength();
137 _rWriter.write(nLength);
139 for(sal_Int32 i=0; i<nLength; ++i)
141 writeDirectly(_rWriter, aSequence[i]);
144 // -----------------------------------------------------------------------------
145 static
146 inline
147 void writeDirectly(BinaryWriter& _rWriter, uno::Sequence<sal_Int8> const& _aBinary)
149 writeSequence(_rWriter,_aBinary);
151 // -----------------------------------------------------------------------------
152 #define CASE_WRITE_SEQUENCE(TYPE_CLASS, DATA_TYPE) \
153 case TYPE_CLASS: \
155 uno::Sequence< DATA_TYPE > aData; \
156 OSL_ASSERT( ::getCppuType(aData.getConstArray()).getTypeClass() == (TYPE_CLASS) ); \
157 OSL_VERIFY( _aValue >>= aData ); \
158 writeSequence(_rWriter,aData); \
159 } break
161 // -----------------------------------------------------------------------------
162 static
163 void writeSequenceValue(BinaryWriter& _rWriter, uno::Any const& _aValue, uno::Type const& aElementType)
164 SAL_THROW( (io::IOException, uno::RuntimeException) )
166 switch(aElementType.getTypeClass())
168 CASE_WRITE_SEQUENCE( uno::TypeClass_BOOLEAN, sal_Bool );
170 CASE_WRITE_SEQUENCE( uno::TypeClass_SHORT, sal_Int16 );
172 CASE_WRITE_SEQUENCE( uno::TypeClass_LONG, sal_Int32 );
174 CASE_WRITE_SEQUENCE( uno::TypeClass_HYPER, sal_Int64 );
176 CASE_WRITE_SEQUENCE( uno::TypeClass_DOUBLE, double );
178 CASE_WRITE_SEQUENCE( uno::TypeClass_STRING, rtl::OUString );
180 CASE_WRITE_SEQUENCE( uno::TypeClass_SEQUENCE, uno::Sequence<sal_Int8> );
182 default:
183 OSL_ENSURE(false, "Unexpected typeclass for sequence elements");
184 break;
187 #undef CASE_WRITE_SEQUENCE
189 // -----------------------------------------------------------------------------
190 static
191 void writeSimpleValue(BinaryWriter& _rWriter, uno::Any const& _aValue, uno::Type const& _aType)
192 SAL_THROW( (io::IOException, uno::RuntimeException) )
194 // PRE: Header must be written
195 uno::TypeClass aDestinationClass = _aType.getTypeClass();
196 switch (aDestinationClass)
198 case uno::TypeClass_BOOLEAN:
200 sal_Bool bValue = sal_False;
201 writeFromAny(_rWriter, _aValue, bValue);
202 break;
204 case uno::TypeClass_BYTE:
206 sal_Int8 nValue = 0;
207 writeFromAny(_rWriter, _aValue, nValue);
208 break;
210 case uno::TypeClass_SHORT:
212 sal_Int16 nValue = 0;
213 writeFromAny(_rWriter, _aValue, nValue);
214 break;
216 case uno::TypeClass_LONG:
218 sal_Int32 nValue = 0;
219 writeFromAny(_rWriter, _aValue, nValue);
220 break;
222 case uno::TypeClass_HYPER:
224 sal_Int64 nValue = 0;
225 writeFromAny(_rWriter, _aValue, nValue);
226 break;
228 case uno::TypeClass_DOUBLE:
230 double nValue = 0;
231 writeFromAny(_rWriter, _aValue, nValue);
232 break;
234 case uno::TypeClass_STRING:
236 rtl::OUString aStr;
237 writeFromAny(_rWriter, _aValue, aStr);
238 break;
240 case uno::TypeClass_SEQUENCE:
242 OSL_ENSURE (_aType == SimpleTypeHelper::getBinaryType(),"Unexpected sequence as simple type");
243 uno::Sequence<sal_Int8> aBinary;
244 writeFromAny(_rWriter, _aValue, aBinary);
245 break;
247 default:
248 OSL_ENSURE(false, "Unexpected typeclass for simple value");
249 break;
253 // -----------------------------------------------------------------------------
255 void BinaryWriteHandler::writeValue(uno::Any const& _aValue)
257 bool bSeq;
258 uno::Type aTargetType = getBasicType(_aValue.getValueType(), bSeq);
260 if (!bSeq)
262 writeSimpleValue(m_BinaryWriter,_aValue, aTargetType);
264 else
266 writeSequenceValue(m_BinaryWriter,_aValue, aTargetType);
269 // -----------------------------------------------------------------------------
271 void BinaryWriteHandler::writeFileHeader( rtl::OUString const & _aSchemaVersion,
272 const uno::Sequence<rtl::OUString> & aKnownLocales,
273 const uno::Sequence<rtl::OUString> & aDataLocales )
274 SAL_THROW( (io::IOException, uno::RuntimeException) )
276 m_BinaryWriter.write(binary::CFG_BINARY_MAGIC);
277 m_BinaryWriter.write(binary::CFG_BINARY_VERSION);
278 m_BinaryWriter.write(_aSchemaVersion);
279 writeSequence(m_BinaryWriter,aKnownLocales);
280 writeSequence(m_BinaryWriter,aDataLocales);
281 m_BinaryWriter.write(m_aComponentName);
283 // -----------------------------------------------------------------------------
285 void BinaryWriteHandler::writeGroupNode(rtl::OUString const& _aName,node::Attributes const& _aAttributes )
286 SAL_THROW( (io::IOException, uno::RuntimeException) )
288 writeAttributes(_aAttributes );
289 m_BinaryWriter.write(_aName);
292 // -----------------------------------------------------------------------------
294 void BinaryWriteHandler::writeSetNode(rtl::OUString const& _aName,
295 rtl::OUString const& _aTemplateName,
296 rtl::OUString const& _aTemplateModule,
297 node::Attributes const& _aAttributes)
298 SAL_THROW( (io::IOException, uno::RuntimeException) )
300 writeAttributes(_aAttributes );
301 m_BinaryWriter.write(_aName);
302 m_BinaryWriter.write(_aTemplateName);
303 m_BinaryWriter.write(_aTemplateModule);
305 // -----------------------------------------------------------------------------
307 void BinaryWriteHandler::writeLayerInfoList(uno::Reference<backenduno::XLayer> const * pLayers, sal_Int32 nNumLayers)
308 SAL_THROW( (io::IOException, uno::RuntimeException) )
311 m_BinaryWriter.write(nNumLayers);
312 for (sal_Int32 i = 0 ; i < nNumLayers ; ++ i)
314 uno::Reference<util::XTimeStamped> xTimeStamp = uno::Reference<util::XTimeStamped>(pLayers[i], uno::UNO_QUERY);
316 rtl::OUString aTimeStamp = xTimeStamp.is() ? xTimeStamp->getTimestamp() : rtl::OUString();
317 m_BinaryWriter.write(aTimeStamp);
321 // -----------------------------------------------------------------------------
323 void BinaryWriteHandler::writeNodeType(binary::NodeType::Type _eType)
324 SAL_THROW( (io::IOException, uno::RuntimeException) )
326 sal_Int8 nValue = static_cast< sal_Int8 >( _eType );
327 m_BinaryWriter.write(nValue);
330 // -----------------------------------------------------------------------------
332 void BinaryWriteHandler::writeAttributes(node::Attributes const& _aAttributes)
333 SAL_THROW( (io::IOException, uno::RuntimeException) )
335 sal_Int8 nValue = static_cast< sal_Int8 >( _aAttributes.state() );
337 OSL_ASSERT(0 <= nValue && nValue <= 3);
339 OSL_ENSURE(!_aAttributes.isReadonly() || !_aAttributes.isFinalized(),"Unexpected attribute mix: node is both read-only and finalized");
341 nValue |= (_aAttributes.isReadonly() ? 1 : 0) << 2;
342 nValue |= (_aAttributes.isFinalized() ? 1 : 0) << 3;
344 nValue |= (_aAttributes.isNullable() ? 1 : 0) << 4;
345 nValue |= (_aAttributes.isLocalized() ? 1 : 0) << 5;
347 nValue |= (_aAttributes.isMandatory() ? 1 : 0) << 6;
348 nValue |= (_aAttributes.isRemovable() ? 1 : 0) << 7;
350 m_BinaryWriter.write(nValue);
353 // -----------------------------------------------------------------------------
355 void BinaryWriteHandler::writeValueNode(rtl::OUString const& _aName,
356 node::Attributes const& _aAttributes,
357 uno::Type const& _aType,
358 uno::Any const& _aUserValue,
359 uno::Any const& _aDefaultValue)
360 SAL_THROW( (io::IOException, uno::RuntimeException) )
362 //write value flags
363 binary::ValueFlags::Type eType = convertTypeToValueType(_aType);
364 sal_Int8 nValueType = sal_Int8(eType);
366 bool hasUserValue = _aUserValue.hasValue();
367 bool hasDefault = _aDefaultValue.hasValue();
369 if (!hasUserValue) nValueType |= binary::ValueFlags::first_value_NULL;
370 if (!hasDefault) nValueType |= binary::ValueFlags::second_value_NULL;
372 m_BinaryWriter.write(nValueType);
373 writeAttributes(_aAttributes );
374 m_BinaryWriter.write(_aName);
376 if(hasUserValue)
378 OSL_ENSURE(_aUserValue.getValueType() == _aType, "Type mismatch in value node");
379 writeValue(_aUserValue);
381 if(hasDefault)
383 OSL_ENSURE(_aDefaultValue.getValueType() == _aType, "Type mismatch in value node");
384 writeValue(_aDefaultValue);
387 // -----------------------------------------------------------------------------
389 void BinaryWriteHandler::writeStop()
390 SAL_THROW( (io::IOException, uno::RuntimeException) )
392 sal_Int8 nStopValue = 0;
393 m_BinaryWriter.write(nStopValue);
395 // -----------------------------------------------------------------------------
397 void BinaryWriteHandler::writeComponentTree(const ISubtree * _pComponentTree)
398 SAL_THROW( (io::IOException, uno::RuntimeException) )
400 this->writeNodeType(binary::NodeType::component);
401 if (_pComponentTree)
403 this->writeTree(*_pComponentTree);
404 this->writeStop();
406 else
408 this->writeNodeType(binary::NodeType::nodata);
411 // -----------------------------------------------------------------------------
413 void BinaryWriteHandler::writeTemplatesTree(const ISubtree * _pTemplatesTree)
414 SAL_THROW( (io::IOException, uno::RuntimeException) )
416 this->writeNodeType(binary::NodeType::templates);
417 if (_pTemplatesTree)
419 this->writeTree(*_pTemplatesTree);
420 this->writeStop();
422 else
424 this->writeNodeType(binary::NodeType::nodata);
427 // -----------------------------------------------------------------------------
429 void BinaryWriteHandler::writeTree(const ISubtree & rTree)
430 SAL_THROW( (io::IOException, uno::RuntimeException) )
432 if ( rTree.isSetNode() )
434 this->writeNodeType(binary::NodeType::setnode);
435 this->writeSetNode( rTree.getName(),
436 rTree.getElementTemplateName(),
437 rTree.getElementTemplateModule(),
438 rTree.getAttributes());
440 else
442 this->writeNodeType(binary::NodeType::groupnode);
443 this->writeGroupNode( rTree.getName(), rTree.getAttributes() );
446 // process children
447 this->applyToChildren(rTree);
449 this->writeStop();
451 // -----------------------------------------------------------------------------
453 void BinaryWriteHandler::handle(const ISubtree & rTree)
455 writeTree(rTree);
457 // -----------------------------------------------------------------------------
459 void BinaryWriteHandler::handle(const ValueNode & rValue)
461 this->writeNodeType(binary::NodeType::valuenode);
463 this->writeValueNode( rValue.getName(),
464 rValue.getAttributes(),
465 rValue.getValueType(),
466 rValue.getUserValue(),
467 rValue.getDefault() );
469 // -----------------------------------------------------------------------------
471 bool BinaryWriteHandler::generateHeader(const uno::Reference<backenduno::XLayer> * pLayers,
472 sal_Int32 nNumLayers,
473 const rtl::OUString& aEntity,
474 const std::vector< com::sun::star::lang::Locale > & aKnownLocales )
475 SAL_THROW( (io::IOException, uno::RuntimeException) )
477 //Open the writer
478 if (!m_BinaryWriter.open())
479 return false;
481 this->writeFileHeader( aEntity,
482 localehelper::makeIsoSequence(aKnownLocales),
483 getAvailableLocales(pLayers,nNumLayers) );
485 this->writeLayerInfoList(pLayers, nNumLayers);
486 return true;
488 // -----------------------------------------------------------------------------
491 // -----------------------------------------------------------------------------