You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-dev@xmlgraphics.apache.org by Glen Mazza <gr...@yahoo.com> on 2003/12/15 23:13:44 UTC

(Peter) read-only BitSet usage

Peter,

I just asked Finn a similar question in Bugzilla, I
also need to ask you to make sure I'm understanding
the BitSets correctly.

In Alt-Design's FOPropertySets there are many
read-only BitSets.  (These are somewhat different from
Finn's, BTW--he created a BitSet for each FO to
indicate those properties relevant for it, but you
seem to be using them for different purposes.) 

Problem is, in your code, I can't find them in use
anywhere.  (I haven't queried all of them, but I did
try to find several.)  What is the purpose of these
BitSets--in what ways do you envision using them?  I
know the benefits of convenient bitwise OR'ing and
AND'ing for determining things--here, I just want to
see the main scope of their usage--where you see them
delivering the most convenience/benefit.

Thanks,
Glen

__________________________________
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/

Re: (Peter) read-only BitSet usage

Posted by "Peter B. West" <pb...@powerup.com.au>.
Glen Mazza wrote:
> Peter,
> 
> I just asked Finn a similar question in Bugzilla, I
> also need to ask you to make sure I'm understanding
> the BitSets correctly.
> 
> In Alt-Design's FOPropertySets there are many
> read-only BitSets.  (These are somewhat different from
> Finn's, BTW--he created a BitSet for each FO to
> indicate those properties relevant for it, but you
> seem to be using them for different purposes.) 
> 
> Problem is, in your code, I can't find them in use
> anywhere.  (I haven't queried all of them, but I did
> try to find several.)  What is the purpose of these
> BitSets--in what ways do you envision using them?  I
> know the benefits of convenient bitwise OR'ing and
> AND'ing for determining things--here, I just want to
> see the main scope of their usage--where you see them
> delivering the most convenience/benefit.
> 

Start with FoBlock.java
http://cvs.apache.org/viewcvs.cgi/*checkout*/xml-fop/src/java/org/apache/fop/fo/flow/Attic/FoBlock.java?content-type=text%2Fplain&rev=1.1.2.1

Near the top is a static block that
   initializes propsets
               sparsePropsMap
               sparseIndices
The propsets BitSet is used as a convenience for initializing 
sparsePropsMap and sparseIndices.

Check the Rec for fo:block
http://www.w3.org/TR/xsl/slice6.html#fo_block

Note the Contents:
   (#PCDATA|%inline;|%block;)*

Note the immediately following properties that apply.  Compare the 
properties with the initialization set for FoBlock.  Note the individual 
bits set with, e.g.,
propsets.set(PropNames.BREAK_BEFORE);
and also the complete sets added with, e.g.,
propsets.or(PropertySets.borderSet);
from
http://cvs.apache.org/viewcvs.cgi/*checkout*/xml-fop/src/java/org/apache/fop/fo/Attic/PropertySets.java?content-type=text%2Fplain&rev=1.1.2.1

These have now been encoded in the sparse array details.

Within FoBlock, note the basic processing loop -

super(foTree, FObjectNames.BLOCK, parent, event
         stateFlags, sparsePropsMap, sparseIndices)
do
   ev = xmlevents.expectPcdataOrInlineOrBlock
    or
   ev = xmlevents.expectOutOfLinePcdataOrInlineOrBlock
   if ev != null
     generate FOs
while ev != null
makeSparsePropsSet

(Note in passing that this loop "automatically" validates the contents 
of the fo:block.  This is pull parsing in action.  More later.)

The super() call includes the processing of the attributes on this 
fo:block event, using the sparse array details constructed with the 
assistance of the PropertySets class.

Back to FONode.java.
http://cvs.apache.org/viewcvs.cgi/*checkout*/xml-fop/src/java/org/apache/fop/fo/FONode.java?content-type=text%2Fplain&rev=1.2.2.1

The sparsePropsMap and sparseIndices references are stored in FONode. 
They will subsequently be used at the end of the FoBlock processing loop 
in the call to makeSparseProps.  I think they went into the super 
arguments so they would be available if needed in the property parsing 
process.

To return to the contents of fo:block - (#PCDATA|%inline;|%block;)*

In the FoBlock processing loop are calls to 
xmlevents.expectPcdataOrInlineOrBlock and 
xmlevents.expectOutOfLinePcdataOrInlineOrBlock.  These are in 
fop.xml.SyncedFoXmlEventsBuffer.java.
http://cvs.apache.org/viewcvs.cgi/*checkout*/xml-fop/src/java/org/apache/fop/xml/Attic/SyncedFoXmlEventsBuffer.java?content-type=text%2Fplain&rev=1.1.2.1

E.g.
     public FoXMLEvent expectOutOfLinePcdataOrInlineOrBlock()
         throws FOPException, UnexpectedStartElementException
     {
         FoXMLEvent ev = expectStartElement
             (FObjectSets.outOfLinePcdataBlockInlineSet,
                                    XMLEvent.RETAIN_W_SPACE);
         if (ev == null)
             ev = expectCharacters();
         return ev;
     }

The relevant expectStartElement method contains a glaring bug, which I 
have just spotted.

    /**
      * Expect one of an <tt>BitSet</tt> of possible STARTELEMENT events.
      * The next STARTELEMENT must be in the fo: namespace, and must have
      * an
      * FO type which matches one of those in the argument
      * <tt>BitSet</tt>.
      * <p>TODO:<br>
      * This method should be retro-fitted to list and array versions.
      *
      * @param set a <tt>BitSet</tt> containing the FO types
      * of possible events, one of which must be the next returned.
      * @param discardWhiteSpace - if true, discard any
      * <tt>characters</tt>
      * events which contain only whitespace.
      * @return the matching STARTELEMENT event.If the next
      * event detected is not of the required type, <tt>null</tt> is
      * returned.
      * The erroneous event is pushed back.
      * @exception FOPException if buffer errors or interrupts occur
      * @exception NoSuchElementException if end of buffer detected.
      */
     public FoXMLEvent expectStartElement
                      (BitSet set, boolean discardWhiteSpace)
         throws FOPException, UnexpectedStartElementException
     {
         FoXMLEvent ev;
         ev = expectTypedEvent
                  (XMLEvent.STARTELEMENT, discardWhiteSpace);
         if (ev == null) return ev;

         // BUG!!!
         for (int i = set.nextSetBit(0);
               i >= 0;
               i = set.nextSetBit(++i))
         {
             if (ev.foType == i)
                 return ev; // Found it!
         }
         // Not found - push the STARTELEMENT event back and throw an
         // UnexpectedStartElementException
         pushBack(ev);
         throw new UnexpectedStartElementException
              ("Unexpected START element: " + ev.getQName());
     }

The bug is in the failure to use the random access available to BitSets, 
but not to the array version of the method (where the array contains 
only the relevant elements).  The correct usage would be simply

              if (set.get(event.foType))
                  return ev;

While I'm at it, I should rename 'set' to 'bitset'.

In any case, if the event.foType (an int) is in the set of valid FOs, 
the event is returned; else no valid FO element was found.

The valid sets for these calls (expectOutOfLinePcdataOrInlineOrBlock, 
expectPcdataOrInlineOrBlock, etc) which correspond to the contents of a 
given fo as expressed in the Rec (e.g. (#PCDATA|%inline;|%block;)* for 
fo:block) are found in fop.fo.FObjectSets.java.
http://cvs.apache.org/viewcvs.cgi/*checkout*/xml-fop/src/java/org/apache/fop/fo/Attic/FObjectSets.java?content-type=text%2Fplain&rev=1.1.2.1

There may be some sets I haven't covered, but that should give you a 
feel for it.  Any questions?

Peter
-- 
Peter B. West <http://www.powerup.com.au/~pbwest/resume.html>