diff options
-rw-r--r-- | sfx2/source/doc/Metadatable.cxx | 29 | ||||
-rw-r--r-- | sw/source/core/crsr/bookmrk.cxx | 32 | ||||
-rw-r--r-- | sw/source/core/doc/doc.cxx | 17 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 21 | ||||
-rw-r--r-- | sw/source/core/doc/docnum.cxx | 26 | ||||
-rw-r--r-- | xmloff/qa/unit/uxmloff.cxx | 6 | ||||
-rw-r--r-- | xmloff/source/style/impastpl.cxx | 230 | ||||
-rw-r--r-- | xmloff/source/style/impastpl.hxx | 4 | ||||
-rw-r--r-- | xmloff/source/text/txtlists.cxx | 24 |
9 files changed, 322 insertions, 67 deletions
diff --git a/sfx2/source/doc/Metadatable.cxx b/sfx2/source/doc/Metadatable.cxx index d7528f63de40..ae4a72368658 100644 --- a/sfx2/source/doc/Metadatable.cxx +++ b/sfx2/source/doc/Metadatable.cxx @@ -394,19 +394,34 @@ template< typename T > /*static*/ OUString create_id(const ::boost::unordered_map< OUString, T, OUStringHash > & i_rXmlIdMap) { - static rtlRandomPool s_Pool( rtl_random_createPool() ); + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); const OUString prefix(s_prefix); typename ::boost::unordered_map< OUString, T, OUStringHash > ::const_iterator iter; OUString id; - do + + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(4000000000); + do + { + id = prefix + OUString::number(nIdCounter++); + iter = i_rXmlIdMap.find(id); + } + while (iter != i_rXmlIdMap.end()); + } + else { - sal_Int32 n; - rtl_random_getBytes(s_Pool, & n, sizeof(n)); - id = prefix + OUString::number(abs(n)); - iter = i_rXmlIdMap.find(id); + static rtlRandomPool s_Pool( rtl_random_createPool() ); + do + { + sal_Int32 n; + rtl_random_getBytes(s_Pool, & n, sizeof(n)); + id = prefix + OUString::number(abs(n)); + iter = i_rXmlIdMap.find(id); + } + while (iter != i_rXmlIdMap.end()); } - while (iter != i_rXmlIdMap.end()); return id; } diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index 11e62108b71e..3a4ba43c6de4 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -172,19 +172,29 @@ namespace sw { namespace mark OUString MarkBase::GenerateNewName(const OUString& rPrefix) { - static rtlRandomPool aPool = rtl_random_createPool(); - static OUString sUniquePostfix; - static sal_Int32 nCount = SAL_MAX_INT32; - OUStringBuffer aResult(rPrefix); - if(nCount == SAL_MAX_INT32) + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(6000000000); + return rPrefix + OUString::number(nIdCounter++); + } + else { - sal_Int32 nRandom; - rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom)); - sUniquePostfix = OUStringBuffer(13).append('_').append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear(); - nCount = 0; + static rtlRandomPool aPool = rtl_random_createPool(); + static OUString sUniquePostfix; + static sal_Int32 nCount = SAL_MAX_INT32; + OUStringBuffer aResult(rPrefix); + if(nCount == SAL_MAX_INT32) + { + sal_Int32 nRandom; + rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom)); + sUniquePostfix = OUStringBuffer(13).append('_').append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear(); + nCount = 0; + } + // putting the counter in front of the random parts will speed up string comparisons + return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear(); } - // putting the counter in front of the random parts will speed up string comparisons - return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear(); } void MarkBase::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew ) diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx index a4eef0e5ee96..e4bdbca0dfbd 100644 --- a/sw/source/core/doc/doc.cxx +++ b/sw/source/core/doc/doc.cxx @@ -476,13 +476,18 @@ sal_uInt32 SwDoc::getRsid() const void SwDoc::setRsid( sal_uInt32 nVal ) { - // Increase the rsid with a random number smaller than 2^17. This way we - // expect to be able to edit a document 2^12 times before rsid overflows. + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + sal_uInt32 nIncrease = 0; - static rtlRandomPool aPool = rtl_random_createPool(); - rtl_random_getBytes( aPool, &nIncrease, sizeof ( nIncrease ) ); - nIncrease &= ( 1<<17 ) - 1; - nIncrease++; // make sure the new rsid is not the same + if (!bHack) + { + // Increase the rsid with a random number smaller than 2^17. This way we + // expect to be able to edit a document 2^12 times before rsid overflows. + static rtlRandomPool aPool = rtl_random_createPool(); + rtl_random_getBytes( aPool, &nIncrease, sizeof ( nIncrease ) ); + nIncrease &= ( 1<<17 ) - 1; + nIncrease++; // make sure the new rsid is not the same + } mnRsid = nVal + nIncrease; } diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx index 7c3b3c8435f1..1a2fb44c07cc 100644 --- a/sw/source/core/doc/docnew.cxx +++ b/sw/source/core/doc/docnew.cxx @@ -407,12 +407,21 @@ SwDoc::SwDoc() mpStyleAccess = createStyleManager( &aIgnorableParagraphItems ); } - // Initialize the session id of the current document to a random number - // smaller than 2^21. - static rtlRandomPool aPool = rtl_random_createPool(); - rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) ); - mnRsid &= ( 1<<21 ) - 1; - mnRsid++; + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) + { + mnRsid = 0; + } + else + { + // Initialize the session id of the current document to a random number + // smaller than 2^21. + static rtlRandomPool aPool = rtl_random_createPool(); + rtl_random_getBytes( aPool, &mnRsid, sizeof ( mnRsid ) ); + mnRsid &= ( 1<<21 ) - 1; + mnRsid++; + } mnRsidRoot = mnRsid; ResetModified(); diff --git a/sw/source/core/doc/docnum.cxx b/sw/source/core/doc/docnum.cxx index 5df1a8094c99..80577647e8ae 100644 --- a/sw/source/core/doc/docnum.cxx +++ b/sw/source/core/doc/docnum.cxx @@ -2596,15 +2596,25 @@ namespace listfunc } const String CreateUniqueListId( const SwDoc& rDoc ) { - // #i92478# - OUString aNewListId( "list" ); - // #o12311627# - static rtlRandomPool s_RandomPool( rtl_random_createPool() ); - sal_Int64 n; - rtl_random_getBytes( s_RandomPool, &n, sizeof(n) ); - aNewListId += OUString::number( (n < 0 ? -n : n) ); + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); - return MakeListIdUnique( rDoc, aNewListId ); + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(7000000000); + return MakeListIdUnique( rDoc, OUString( "list" + OUString::number(nIdCounter++) ) ); + } + else + { + // #i92478# + OUString aNewListId( "list" ); + // #o12311627# + static rtlRandomPool s_RandomPool( rtl_random_createPool() ); + sal_Int64 n; + rtl_random_getBytes( s_RandomPool, &n, sizeof(n) ); + aNewListId += OUString::number( (n < 0 ? -n : n) ); + + return MakeListIdUnique( rDoc, aNewListId ); + } } } diff --git a/xmloff/qa/unit/uxmloff.cxx b/xmloff/qa/unit/uxmloff.cxx index a0bd4306226b..8dfa5021ed99 100644 --- a/xmloff/qa/unit/uxmloff.cxx +++ b/xmloff/qa/unit/uxmloff.cxx @@ -75,7 +75,11 @@ void Test::testAutoStylePool() OUString aName = xPool->Add( XML_STYLE_FAMILY_TEXT_PARAGRAPH, "", aProperties ); // not that interesting but worth checking - CPPUNIT_ASSERT_MESSAGE( "style / naming changed", aName == "Bob1" ); + bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + if (bHack) + CPPUNIT_ASSERT_MESSAGE( "style / naming changed", aName == "Bob" ); + else + CPPUNIT_ASSERT_MESSAGE( "style / naming changed", aName == "Bob1" ); // find ourselves again: OUString aSameName = xPool->Find( XML_STYLE_FAMILY_TEXT_PARAGRAPH, "", aProperties ); diff --git a/xmloff/source/style/impastpl.cxx b/xmloff/source/style/impastpl.cxx index 9b54e94db591..8aca0b1b3f1d 100644 --- a/xmloff/source/style/impastpl.cxx +++ b/xmloff/source/style/impastpl.cxx @@ -60,24 +60,190 @@ void XMLAutoStyleFamily::ClearEntries() maParentSet.clear(); } +static OUString +data2string(void *data, + const typelib_TypeDescriptionReference *type); + +static OUString +struct2string(void *data, + const typelib_TypeDescription *type) +{ + assert(type->eTypeClass == typelib_TypeClass_STRUCT); + + OUStringBuffer result; + + result.append("{"); + + const typelib_CompoundTypeDescription *compoundType = + &((const typelib_StructTypeDescription*) type)->aBase; + + for (int i = 0; i < compoundType->nMembers; i++) + { + if (i > 0) + result.append(":"); + result.append(compoundType->ppMemberNames[i]); + result.append("="); + result.append(data2string(((char *)data)+compoundType->pMemberOffsets[i], + compoundType->ppTypeRefs[i])); + } + + result.append("}"); + + return result.makeStringAndClear(); +} + +static OUString +data2string(void *data, + const typelib_TypeDescriptionReference *type) +{ + OUStringBuffer result; + + switch (type->eTypeClass) + { + case typelib_TypeClass_VOID: + break; + case typelib_TypeClass_BOOLEAN: + result.append((*reinterpret_cast<const sal_Bool*>(data) == sal_False ) ? OUString("false") : OUString("true")); + break; + case typelib_TypeClass_BYTE: + result.append(OUString::number((*reinterpret_cast<const sal_Int8*>(data)))); + break; + case typelib_TypeClass_SHORT: + result.append(OUString::number((*reinterpret_cast<const sal_Int16*>(data)))); + break; + case typelib_TypeClass_LONG: + result.append(OUString::number((*reinterpret_cast<const sal_Int32*>(data)))); + break; + case typelib_TypeClass_HYPER: + result.append(OUString::number((*reinterpret_cast<const sal_Int64*>(data)))); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data)))); + break; + case typelib_TypeClass_UNSIGNED_LONG: + result.append(OUString::number((*reinterpret_cast<const sal_uInt32*>(data)), 16)); + break; + case typelib_TypeClass_UNSIGNED_HYPER: + result.append(OUString::number((*reinterpret_cast<const sal_uInt64*>(data)), 16)); + break; + case typelib_TypeClass_FLOAT: + result.append(OUString::number((*reinterpret_cast<const float*>(data)))); + break; + case typelib_TypeClass_DOUBLE: + result.append(OUString::number((*reinterpret_cast<const double*>(data)))); + break; + case typelib_TypeClass_CHAR: + result.append("U+"); + result.append(OUString::number((*reinterpret_cast<const sal_uInt16*>(data)))); + break; + case typelib_TypeClass_STRING: + result.append(*reinterpret_cast<OUString*>(data)); + break; + case typelib_TypeClass_TYPE: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_INTERFACE: + result.append("wtf"); + break; + case typelib_TypeClass_STRUCT: + result.append(struct2string(data, type->pType)); + break; + case typelib_TypeClass_ENUM: + result.append(OUString::number((*reinterpret_cast<const sal_Int32*>(data)))); + break; + default: + assert(false); // this cannot happen I hope + break; + } + + return result.makeStringAndClear(); +} + +static OUString +any2string(uno::Any any) +{ + return data2string((void*)any.getValue(), any.pType); +} + // Class SvXMLAutoStylePoolProperties_Impl // ctor class SvXMLAutoStylePoolProperties_Impl -XMLAutoStylePoolProperties::XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties ) +XMLAutoStylePoolProperties::XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const vector< XMLPropertyState >& rProperties, OUString& rParentName ) : maProperties( rProperties ), mnPos ( rFamilyData.mnCount ) { - // create a name that hasn't been used before. The created name has not - // to be added to the array, because it will never tried again - OUStringBuffer sBuffer( 7 ); - do + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) { - rFamilyData.mnName++; - sBuffer.append( rFamilyData.maStrPrefix ); - sBuffer.append( OUString::number( rFamilyData.mnName ) ); - msName = sBuffer.makeStringAndClear(); + OUStringBuffer aStemBuffer(32); + aStemBuffer.append( rFamilyData.maStrPrefix ); + + if (rParentName != "") + { + aStemBuffer.append("-"); + aStemBuffer.append(rParentName); + } + + // Create a name based on the properties used + for( size_t i = 0, n = maProperties.size(); i < n; ++i ) + { + XMLPropertyState& rState = maProperties[i]; + if (rState.mnIndex == -1) + continue; + OUString sXMLName(rFamilyData.mxMapper->getPropertySetMapper()->GetEntryXMLName(rState.mnIndex)); + if (sXMLName == "") + continue; + aStemBuffer.append("-"); + aStemBuffer.append(OUString::number(rFamilyData.mxMapper->getPropertySetMapper()->GetEntryNameSpace(rState.mnIndex))); + aStemBuffer.append(":"); + aStemBuffer.append(sXMLName); + aStemBuffer.append("="); + aStemBuffer.append(any2string(rState.maValue)); + } + +#if 0 + // Finally append an incremental counter in an attempt to make identical + // styles always come out in the same order. Will see if this works. + aStemBuffer.append("-z"); + static sal_Int32 nCounter = 0; + aStemBuffer.append(OUString::number(nCounter++)); +#endif + + // create a name that hasn't been used before. The created name has not + // to be added to the array, because it will never tried again + OUStringBuffer aTry( aStemBuffer ); + + msName = aTry.makeStringAndClear(); + bool bWarned = false; + while (rFamilyData.maNameSet.find(msName) != + rFamilyData.maNameSet.end()) + { + if (!bWarned) + SAL_WARN("xmloff", "Overlapping style name for " << msName); + bWarned = true; + rFamilyData.mnName++; + aTry.append( aStemBuffer ); + aTry.append( "-" ); + aTry.append( OUString::number( rFamilyData.mnName ) ); + msName = aTry.makeStringAndClear(); + } + rFamilyData.maNameSet.insert(msName); + } + else + { + // create a name that hasn't been used before. The created name has not + // to be added to the array, because it will never tried again + OUStringBuffer sBuffer( 7 ); + do + { + rFamilyData.mnName++; + sBuffer.append( rFamilyData.maStrPrefix ); + sBuffer.append( OUString::number( rFamilyData.mnName ) ); + msName = sBuffer.makeStringAndClear(); + } + while (rFamilyData.maNameSet.find(msName) != rFamilyData.maNameSet.end()); } - while (rFamilyData.maNameSet.find(msName) != rFamilyData.maNameSet.end()); } bool operator<( const XMLAutoStyleFamily& r1, const XMLAutoStyleFamily& r2) @@ -119,7 +285,7 @@ sal_Bool XMLAutoStylePoolParent::Add( XMLAutoStyleFamily& rFamilyData, const vec if( !pProperties ) { - pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties ); + pProperties = new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent ); PropertiesListType::iterator it = maPropertiesList.begin(); ::std::advance( it, i ); maPropertiesList.insert( it, pProperties ); @@ -158,7 +324,7 @@ sal_Bool XMLAutoStylePoolParent::AddNamed( XMLAutoStyleFamily& rFamilyData, cons if (rFamilyData.maNameSet.find(rName) == rFamilyData.maNameSet.end()) { XMLAutoStylePoolProperties* pProperties = - new XMLAutoStylePoolProperties( rFamilyData, rProperties ); + new XMLAutoStylePoolProperties( rFamilyData, rProperties, msParent ); // ignore the generated name pProperties->SetName( rName ); PropertiesListType::iterator it = maPropertiesList.begin(); @@ -274,7 +440,10 @@ void SvXMLAutoStylePoolP_Impl::RegisterName( sal_Int32 nFamily, const OUString& DBG_ASSERT( aFind != maFamilySet.end(), "SvXMLAutoStylePool_Impl::RegisterName: unknown family" ); if (aFind != maFamilySet.end()) + { + // SAL_DEBUG("SvXMLAutoStylePoolP_Impl::RegisterName: " << nFamily << ", '" << rName << "'"); aFind->maNameSet.insert(rName); + } } // @@ -418,7 +587,7 @@ namespace { struct AutoStylePoolExport { const OUString* mpParent; - const XMLAutoStylePoolProperties* mpProperties; + XMLAutoStylePoolProperties* mpProperties; AutoStylePoolExport() : mpParent(NULL), mpProperties(NULL) {} }; @@ -450,21 +619,20 @@ void SvXMLAutoStylePoolP_Impl::exportXML( // which contains a parent-name and a SvXMLAutoStylePoolProperties_Impl std::vector<AutoStylePoolExport> aExpStyles(nCount); - sal_uInt32 i; - for( i=0; i < nCount; i++ ) + for( size_t i=0; i < nCount; i++ ) { aExpStyles[i].mpParent = 0; aExpStyles[i].mpProperties = 0; } - XMLAutoStyleFamily::ParentSetType::const_iterator it = rFamily.maParentSet.begin(), itEnd = rFamily.maParentSet.end(); + XMLAutoStyleFamily::ParentSetType::iterator it = rFamily.maParentSet.begin(), itEnd = rFamily.maParentSet.end(); for (; it != itEnd; ++it) { - const XMLAutoStylePoolParent& rParent = *it; + XMLAutoStylePoolParent& rParent = *it; size_t nProperties = rParent.GetPropertiesList().size(); for( size_t j = 0; j < nProperties; j++ ) { - const XMLAutoStylePoolProperties* pProperties = + XMLAutoStylePoolProperties* pProperties = &rParent.GetPropertiesList()[j]; sal_uLong nPos = pProperties->GetPos(); DBG_ASSERT( nPos < nCount, @@ -479,12 +647,36 @@ void SvXMLAutoStylePoolP_Impl::exportXML( } } + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + + if (bHack) + { + struct { + bool operator() (AutoStylePoolExport a, AutoStylePoolExport b) + { + return (a.mpProperties->GetName() < b.mpProperties->GetName() || + (a.mpProperties->GetName() == b.mpProperties->GetName() && *a.mpParent < *b.mpParent)); + } + } aComparator; + + std::sort(aExpStyles.begin(), aExpStyles.end(), aComparator); + + for (size_t i = 0; i < nCount; i++) + { + OUString oldName = aExpStyles[i].mpProperties->GetName(); + sal_Int32 dashIx = oldName.indexOf('-'); + OUString newName = (dashIx > 0 ? oldName.copy(0, dashIx) : oldName) + OUString::number(i); + // SAL_DEBUG("renaming '" << oldName << "' -> '" << newName << "'"); + aExpStyles[i].mpProperties->SetName(newName); + } + } + // // create string to export for each XML-style. That means for each property-list // OUString aStrFamilyName = rFamily.maStrFamilyName; - for( i=0; i<nCount; i++ ) + for( size_t i = 0; i < nCount; i++ ) { DBG_ASSERT( aExpStyles[i].mpProperties, "SvXMLAutoStylePool_Impl::exportXML: empty position" ); diff --git a/xmloff/source/style/impastpl.hxx b/xmloff/source/style/impastpl.hxx index f8e2e28baea2..409ac0cdb6a5 100644 --- a/xmloff/source/style/impastpl.hxx +++ b/xmloff/source/style/impastpl.hxx @@ -80,7 +80,7 @@ class XMLAutoStylePoolProperties public: - XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const ::std::vector< XMLPropertyState >& rProperties ); + XMLAutoStylePoolProperties( XMLAutoStyleFamily& rFamilyData, const ::std::vector< XMLPropertyState >& rProperties, OUString& rParentname ); ~XMLAutoStylePoolProperties() { @@ -120,7 +120,7 @@ public: const OUString& GetParent() const { return msParent; } - const PropertiesListType& GetPropertiesList() const + PropertiesListType& GetPropertiesList() { return maPropertiesList; } diff --git a/xmloff/source/text/txtlists.cxx b/xmloff/source/text/txtlists.cxx index 1c35a54fcfaa..853286ff864c 100644 --- a/xmloff/source/text/txtlists.cxx +++ b/xmloff/source/text/txtlists.cxx @@ -228,13 +228,23 @@ const OUString& XMLTextListsHelper::GetListStyleOfLastProcessedList() const OUString XMLTextListsHelper::GenerateNewListId() const { - // Value of xml:id in element <text:list> has to be a valid ID type (#i92478#) - OUString sTmpStr( "list" ); - sal_Int64 n = Time( Time::SYSTEM ).GetTime(); - n += Date( Date::SYSTEM ).GetDate(); - n += rand(); - // Value of xml:id in element <text:list> has to be a valid ID type (#i92478#) - sTmpStr += OUString::number( n ); + static bool bHack = (getenv("LIBO_ONEWAY_STABLE_ODF_EXPORT") != NULL); + OUString sTmpStr( "list" ); + + if (bHack) + { + static sal_Int64 nIdCounter = SAL_CONST_INT64(5000000000); + sTmpStr += OUString::number(nIdCounter++); + } + else + { + // Value of xml:id in element <text:list> has to be a valid ID type (#i92478#) + sal_Int64 n = Time( Time::SYSTEM ).GetTime(); + n += Date( Date::SYSTEM ).GetDate(); + n += rand(); + // Value of xml:id in element <text:list> has to be a valid ID type (#i92478#) + sTmpStr += OUString::number( n ); + } OUString sNewListId( sTmpStr ); if ( mpProcessedLists != 0 ) |