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