/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include namespace sc { template struct FuncElseNoOp { Ret operator() (mdds::mtv::element_t, SizeT, SizeT) const { return Ret(); } }; template struct FuncNotElem { FuncElem& func; FuncNotElem(FuncElem& f) : func(f) {} bool operator() (size_t s, Elem elem) const { return !func(s, elem); } }; /** * Generic algorithm to parse blocks of multi_type_vector either partially * or fully. */ template typename StoreT::const_iterator ParseBlock( const typename StoreT::const_iterator& itPos, const StoreT& rStore, Func& rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } rFunc(*it, nOffset, nDataSize); if (bLastBlock) break; } return it; } /** * Non-const variant of the above function. TODO: Find a way to merge these * two in an elegant way. */ template typename StoreT::iterator ProcessBlock(const typename StoreT::iterator& itPos, StoreT& rStore, Func& rFunc, typename StoreT::size_type nStart, typename StoreT::size_type nEnd) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nCurRow = nStart; for (; it != rStore.end() && nCurRow <= nEnd; ++it, nOffset = 0, nCurRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nCurRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nCurRow + 1; bLastBlock = true; } rFunc(*it, nOffset, nDataSize); if (bLastBlock) break; } return it; } template void EachElem(NodeT& rNode, size_t nOffset, size_t nDataSize, FuncElem& rFuncElem) { ItrT it = BlkT::begin(*rNode.data); std::advance(it, nOffset); ItrT itEnd = it; std::advance(itEnd, nDataSize); size_t nRow = rNode.position + nOffset; for (; it != itEnd; ++it, ++nRow) rFuncElem(nRow, *it); } template void EachElem(NodeT& rNode, FuncElem& rFuncElem) { auto it = BlkT::begin(*rNode.data); auto itEnd = BlkT::end(*rNode.data); size_t nRow = rNode.position; for (; it != itEnd; ++it, ++nRow) rFuncElem(nRow, *it); } template void EachElemReverse(NodeT& rNode, FuncElem& rFuncElem) { auto it = BlkT::rbegin(*rNode.data); auto itEnd = BlkT::rend(*rNode.data); size_t nRow = rNode.position; for (; it != itEnd; ++it, ++nRow) rFuncElem(nRow, *it); } template std::pair CheckElem( const StoreT& rStore, const typename StoreT::const_iterator& it, size_t nOffset, size_t nDataSize, FuncElem& rFuncElem) { typedef std::pair PositionType; typename BlkT::const_iterator itData = BlkT::begin(*it->data); std::advance(itData, nOffset); typename BlkT::const_iterator itDataEnd = itData; std::advance(itDataEnd, nDataSize); size_t nTopRow = it->position + nOffset; size_t nRow = nTopRow; for (; itData != itDataEnd; ++itData, ++nRow) { if (rFuncElem(nRow, *itData)) return PositionType(it, nRow - it->position); } return PositionType(rStore.end(), 0); } template void ParseElements1(const StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) { typename StoreT::size_type nTopRow = 0, nDataSize = 0; typename StoreT::const_iterator it = rStore.begin(), itEnd = rStore.end(); for (; it != itEnd; ++it, nTopRow += nDataSize) { nDataSize = it->size; if (it->type != BlkT::block_type) { rFuncElse(it->type, nTopRow, nDataSize); continue; } EachElem(*it, rFuncElem); } } template typename StoreT::const_iterator ParseElements1( const typename StoreT::const_iterator& itPos, const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } if (it->type == BlkT::block_type) EachElem(*it, nOffset, nDataSize, rFuncElem); else rFuncElse(it->type, nTopRow, nDataSize); if (bLastBlock) break; } return it; }; template typename StoreT::const_iterator ParseElements2( const typename StoreT::const_iterator& itPos, const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } switch (it->type) { case Blk1::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; case Blk2::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; default: rFuncElse(it->type, nTopRow, nDataSize); } if (bLastBlock) break; } return it; } template typename StoreT::const_iterator ParseElements4( const typename StoreT::const_iterator& itPos, const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } switch (it->type) { case Blk1::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; case Blk2::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; case Blk3::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; case Blk4::block_type: EachElem(*it, nOffset, nDataSize, rFuncElem); break; default: rFuncElse(it->type, nTopRow, nDataSize); } if (bLastBlock) break; } return it; } template void ProcessElements1(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) { typename StoreT::size_type nTopRow = 0, nDataSize = 0; typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end(); for (; it != itEnd; ++it, nTopRow += nDataSize) { nDataSize = it->size; if (it->type != BlkT::block_type) { rFuncElse(it->type, nTopRow, nDataSize); continue; } EachElem(*it, rFuncElem); } } /** * This variant specifies start and end positions. */ template typename StoreT::iterator ProcessElements1( const typename StoreT::iterator& itPos, StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; PositionType aPos = rStore.position(itPos, nStart); typename StoreT::iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } if (it->type == BlkT::block_type) EachElem(*it, nOffset, nDataSize, rFuncElem); else rFuncElse(it->type, nTopRow, nDataSize); if (bLastBlock) break; } return it; }; template void ProcessElements2(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) { typename StoreT::size_type nTopRow = 0, nDataSize = 0; typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end(); for (; it != itEnd; ++it, nTopRow += nDataSize) { nDataSize = it->size; switch (it->type) { case Blk1::block_type: EachElem(*it, rFuncElem); break; case Blk2::block_type: EachElem(*it, rFuncElem); break; default: rFuncElse(it->type, nTopRow, nDataSize); } } } template void ProcessElements2Reverse(StoreT& rStore, FuncElem& rFuncElem, FuncElse& rFuncElse) { typename StoreT::size_type nTopRow = 0, nDataSize = 0; typename StoreT::iterator it = rStore.begin(), itEnd = rStore.end(); for (; it != itEnd; ++it, nTopRow += nDataSize) { nDataSize = it->size; switch (it->type) { case Blk1::block_type: EachElemReverse(*it, rFuncElem); break; case Blk2::block_type: EachElemReverse(*it, rFuncElem); break; default: rFuncElse(it->type, nTopRow, nDataSize); } } } template std::pair FindElement1( const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; typedef std::pair ElseRetType; PositionType aPos = rStore.position(nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } switch (it->type) { case Blk1::block_type: { PositionType aRet = CheckElem(rStore, it, nOffset, nDataSize, rFuncElem); if (aRet.first != rStore.end()) return aRet; } break; default: { ElseRetType aRet = rFuncElse(it->type, nTopRow, nDataSize); if (aRet.second) return PositionType(it, aRet.first); } } if (bLastBlock) break; } return PositionType(rStore.end(), 0); } template std::pair FindElement2( const StoreT& rStore, typename StoreT::size_type nStart, typename StoreT::size_type nEnd, FuncElem& rFuncElem, FuncElse& rFuncElse) { typedef std::pair PositionType; typedef std::pair ElseRetType; PositionType aPos = rStore.position(nStart); typename StoreT::const_iterator it = aPos.first; typename StoreT::size_type nOffset = aPos.second; typename StoreT::size_type nDataSize = 0; typename StoreT::size_type nTopRow = nStart; for (; it != rStore.end() && nTopRow <= nEnd; ++it, nOffset = 0, nTopRow += nDataSize) { bool bLastBlock = false; nDataSize = it->size - nOffset; if (nTopRow + nDataSize - 1 > nEnd) { // Truncate the block. nDataSize = nEnd - nTopRow + 1; bLastBlock = true; } switch (it->type) { case Blk1::block_type: { PositionType aRet = CheckElem(rStore, it, nOffset, nDataSize, rFuncElem); if (aRet.first != rStore.end()) return aRet; } break; case Blk2::block_type: { PositionType aRet = CheckElem(rStore, it, nOffset, nDataSize, rFuncElem); if (aRet.first != rStore.end()) return aRet; } break; default: { ElseRetType aRet = rFuncElse(*it, nOffset, nDataSize); if (aRet.second) return PositionType(it, aRet.first); } } if (bLastBlock) break; } return PositionType(rStore.end(), 0); } // Efficiently set all elements for which the predicate returns true as empty. template void SetElementsToEmpty1( StoreT& rStore, FuncElem& rFuncElem) { typedef std::pair PositionType; for (typename StoreT::iterator it = rStore.begin(); it != rStore.end(); ++it) { if (it->type == Blk1::block_type) { PositionType firstToEmpty = CheckElem(rStore, it, 0, it->size, rFuncElem); if (firstToEmpty.first != rStore.end()) { typename StoreT::size_type nFirstOffset = firstToEmpty.second; typename StoreT::size_type nRemainingDataSize = it->size - nFirstOffset; FuncNotElem notFuncElem(rFuncElem); PositionType lastToEmpty = CheckElem(rStore, it, nFirstOffset, nRemainingDataSize, notFuncElem); typename StoreT::size_type nLastOffset = lastToEmpty.first != rStore.end() ? lastToEmpty.second - 1 : it->size - 1; it = rStore.set_empty(it, it->position + nFirstOffset, it->position + nLastOffset); // The returned iterator points to the empty elements block. assert(it->type == sc::element_type_empty); } } } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ option value='feature/gsoc14-personas2'>feature/gsoc14-personas2 LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2024-06-12postgresql: fix arm64 buildXisco Fauli
after e4e2c7ca00151b27c8928f785af1845f918ed721 "postgresql: Upgrade to 14.12 (master only)" Change-Id: Ie2b1a08b2bbc1504d5f8bac15b5ffc6708b6b1f6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168697 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2023-03-01postgresql: upgrade to release 13.10Taichi Haradaguchi
Fixes CVE-2022-41862 Reference: https://www.postgresql.org/support/security/CVE-2022-41862/ Change-Id: I6075838972fec1c091f3150b19c5da4dc80ad6d3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147674 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
2022-11-04Fix ARM64 build after postgres upgrade to 13.8Xisco Fauli
Partially revert 096e2ba8e4fce64c04a7d7e842dd1dbab8699801 "postgresql: upgrade to release 13.8" Change-Id: I3fa2a96f9765788ab6193133c4f420eed7eb99bb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142255 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
2022-09-23postgresql: upgrade to release 13.8Taichi Haradaguchi
Fixes CVE-2022-1552 and CVE-2022-2625. Change-Id: I4964c43fefc94f12a16c45d8727ae41cf1ce278b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140458 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2021-03-14Fix ARM64 build after postgres upgrade to 13.1Thorsten Behrens
Change-Id: I12bdda6aedd9b7b15423f997fe8c6910d9c9e9d5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112464 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>