Re: Some new pf_frag methods...?

From: Martin Sevior <msevior_at_gmail.com>
Date: Fri Jul 01 2011 - 05:03:57 CEST

Hi Ben,

I'm still working my way through these. Have you updated your GIT
repository the svn trunk? We made some important fixes to the
Piecetable a few weeks ago.

Cheers

Martin

On Fri, Jul 1, 2011 at 10:16 AM, Ben Martin
<monkeyiq@users.sourceforge.net> wrote:
> Hi,
>  While hacking away on some odf change tracking updates [1] I added a
> few methods to the core piecetable and pf_frag tree in my git repo. I
> was doing some things over and over and they seemed good candidates for
> abstraction, but there is also the possibility that I just missed the
> current good way to do the same thing :/ I might have missed one or two
> changes here, the patch will tell all ;)
>
> I added
> pf_Frag_Strux*
> pt_PieceTable::_getBlockFromPosition(PT_DocPosition pos) const;
>
> Because using _getStruxOfTypeFromPosition() if pos == a PTX_Block then
> you get the previous block instead of the block at pos. Using the new
> _getBlockFromPosition() will return the PTX_Block right at pos if one
> exists.
>
> I added the below method before the above one, it is a simpler
> implementation now. Basically if startpos and endpos are in the same
> PTX_Block then a pointer to its Frag_Strux is returned or NULL
> otherwise. So it can be used as a bool test to see if these positions
> share a block, and also you can use the return value to access that same
> block if desired.
>
> pf_Frag_Strux*
> pt_PieceTable::inSameBlock(
>  PT_DocPosition startpos,
>  PT_DocPosition endpos );
>
> The below will get the first strux that marks the end of the block
> containing currentpos or null. The end of block strux has to be
> positioned before endpos or null is returned. Note that if currentpos is
> itself a block this method will move over that PTX_Block before
> searching for the end of block to allow simpler iteration of the
> document. endpos could be optional, but it is handy for selections which
> is the context I created it for. ie, you want to get the end of block
> only if it is not beyond the user's active text selection.
>
> pf_Frag*
> pt_PieceTable::getEndOfBlock(
>  PT_DocPosition currentpos,
>  PT_DocPosition endpos );
>
> I extended _findLastStruxOfType to take a stopCondition as follows. Note
> that the old method is still there too and just delegates to this new
> one. IIRC the return value used to be pf_Frag, but as we are explicitly
> finding a frag_strux I changed that to the later to give the best type
> information to the caller. The stopConditions is an array terminated by
> Dummy. The method comment is;
>
> /**
>  * MIQ11: Extends the old _findLastStruxOfType adding a stopCondition
>  * for failure and returning a Strux* directly in the case of success.
>  * This is like a findBackwards() from a fragment.
>  *
>  * stopConditions must be terminated with a PTX_StruxDummy entry like:
>  * PTStruxType stopCondition[] = { PTX_SectionTable, PTX_StruxDummy };
>  *
>  * Find a fragment of strux type pst looking backwards from pfStart.
>  * If a strux fragment matching the stopCondition is found first then
>  * the function stops and returns 0. If no fragment with pst is found
>  * then 0 is returned.
>  *
>  * MAYBE: extend this again to take yes() and no() functors so a
>  *    function can call _findLastStruxOfType() and decide what is ok
>  *    and what is not using those.
>  *    boost::lambda would be handy to simplify the functors?
>  */
> pf_Frag_Strux* _findLastStruxOfType(
>  pf_Frag * pfStart,
>  PTStruxType pst,
>  PTStruxType* stopConditions,
>  bool bSkipEmbededSections );
>
> ------------
>
> In pf_frag I added the following:
>
> The getNextStrux() is like getNext() but will skip over fragments until
> a strux of this type is found. Return 0 otherwise
>
> pf_Frag_Strux* getNextStrux(PTStruxType t) const;
>
> In the below, if this fragment is a strux, and it is of the type passed
> in then return this fragment downcast to the frag_strux type. It seems
> to be quite common to test for the strux and then subtype, and then
> static_cast<> down to the subtype.
>
> pf_Frag_Strux* tryDownCastStrux(PTStruxType t) const;
>
>
> It might also be an idea to add templates for downcasts like
>
> template <class Frag>
> Frag* tryDownCastStrux() const;
>
> To be used like
> pf_Frag_Text* pft = pf->tryDownCastStrux<pf_Frag_Text>();
>
> Of course the template parameter can be omitted if the pft is passed as
> an argument instead of as the return value, but then you have to declare
> the pft before the call. This way the whole thing can be put into a line
> like the following. But if you pass the class or strux enum in this
> process doesn't seem to make much difference.
>
> if( pf_Frag_Text* pft = pf->tryDownCastStrux<pf_Frag_Text>() )
> {
>  // use pft
> }
>
> Mainly for debugging I added the following to pf_frag_text. This avoids
> using getBufIndex() and playing with char pointers directly, but does
> require a string copy for the result. Not a huge problem in #if DEBUG
> code though.
>
> std::string toString() const;
>
>
> ------------
>
> I also have some additions to pp_revision
>
> To merge another RevisionAttr
>
> void mergeAll( const PP_RevisionAttr& ra );
>
> To add a attr=value at a given revisionid and type
>
> void mergeAttr( UT_uint32 iId, PP_RevisionType t,
>                const gchar* pzName, const gchar* pzValue );
>
> The same but do not replace an existing value
>
> void mergeAttrIfNotAlreadyThere(
>  UT_uint32 iId, PP_RevisionType t,
>  const gchar* pzName, const gchar* pzValue );
>
> Get the lowest deletion revision for content that might be deleted more
> than once.
>
> const PP_Revision* getLowestDeletionRevision() const;
>
> I might also add a more STL like interface for PP_Revision to the
> PP_RevisionAttr class.
>
> Something like:
>
> iterator begin();
> iterator end();
> iterator find( PP_Revision* );
> iterator find( UT_uint32 iId,
>               PP_RevisionType t = PP_REVISION_NONE );
>
>
>
> [1]
> http://lists.oasis-open.org/archives/office-collab/201106/msg00024.html
>
>
Received on Fri Jul 1 05:04:05 2011

This archive was generated by hypermail 2.1.8 : Fri Jul 01 2011 - 05:04:05 CEST