attachment-0001
<!........................................>
<font size="+3" color=#0000ff>XPDO (Extensible Printer Description Object Model) Virtual Machine</font>
<blockquote>
<a href="#intro"><font color=#ff0000>Introduction</font></a><br>
<a href="#xpdodatatype"><font color=#ff0000>XPDO Data Types: string, name, int, float, boolean, array, dictionary</font></a><br>
<a href="#xpdomodulization"><font color=#ff0000>XPDO File Modulization for Printer Model Family Hierarchies</font></a><br>
<a href="#execobjs"><font color=#ff0000>Executable Objects and Execution Context</font></a><br>
<a href="#load"><font color=#ff0000>The load Executable Object and Paramter Dictionaries</font></a><br>
<a href="#switch"><font color=#ff0000>The switch Executable Object</font></a><br>
<a href="#math"><font color=#ff0000>The Math Executable Objects: idiv, add, sub, expr</font></a><br>
<a href="#formatter"><font color=#ff0000>The Formatter Executable Objects: tostring, numformat, maxrepeat</font></a><br>
</blockquote>
<A NAME="intro"></a>
<font size="+1" color=#ff0000><b>Introduction</b></font><br> <p>
This document describes a very simple virtual machine based on an extensible object model
for printer description as a XML application. Many requirements in printer description such as run-time evaluation
for raster data and printer setup command generation, custom declaration, modulization and binary encoding are addressed. <p>
<ol>
<li>Everything is described as an object. <br>
<li>Every object is strongly typed. <br>
<li>The type information is available not only at compile time but also at runtime. <br>
<li>The compile-time type checking can perfectly fit into the strutural validation feature of a XML parser. <br>
<li>The run-time type checking can be optionally performed by so-called executable objects. <br>
<li>The number of pre-defined object types is limited. Custom data can be aggregated in either of two pre-defined
compound data types: dictionary and array. <br>
<li>An enumeration (the most frequently-used "custom type") can be realized by simply iterating all keys of a
dictionary. <br>
<li>A printer description file can be simply extended by a dictionary deep-merge operation. <br>
<li>A binary format of a XML-encoded printer description file can be simply realized by a serialization
process from an object map in a memory created by a XML processor. <br>
<li>Tools based on printer description data in an strongly-typed object form can provide many services
such as context-sensitive validation, product family/peer views and display string except for
localization.
</ol>
<A NAME="xpdodatatype"></a>
<font size="+1" color=#ff0000><b>XPDO Data Types</b></font><br> <p>
<code>XPDO</code> provides a object-based system which is strongly typed. <p>
There are several primitive types. They are for string, name, integer, float and boolean objects which
are encoded as below: <p>
<blockquote>
<pre>
<int>77</int> <!-- integer number object type -->
<float>-1.2</float> <!-- floating-point number object type -->
<bool>TRUE</bool> <!-- boolean object type -->
<str>a string</str> <!-- string object type -->
<name>aName</name> <!-- name object type -->
</pre>
</blockquote>
A <code>XPDO</code> numbers can be signed integer objects such as 12, -98, 0, +650 and floating point objects
such as -0.01 2.3 -4.56 -7. 0.0 <p>
A <code>XPDO</code> boolean object is for use in logical expression or returned as status information. The
names true and false are associated with the two values of this type.
The <code><TRUE/></code> and <code><FALSE/></code> are introduced for a short hand form of a boolean object
with true and false value, respectively. <p>
A <code>XPDO</code> name object is of <code>XML NMTOKEN</code> type. <p>
A <code>XPDO</code> string object is of <code>XML CDATA</code> type with one exception in favor of
hexadecimal encoding which is useful for arbitrary binary data which is often mixed in a printer command string.
The ASCII '{' character and the '}' are used to enter and exit the hexadecimal encoding mode respectively.
A string is initially in the normal ASCII encoding mode. For example, the selection command for
Letter size on Canon BJC-600 is the hexadecimal byte stream
<code>1B 28:'(' 67:'g' 03 00 6E:'n' 01 72:'r'</code> where all printable ASCII characters are shown
after a colon for the ease of reference. It can be specificed as below: <p>
<blockquote>
<pre>
<str>{1B}(g{0300}n{01}r</str> <!-- or simply {1B 28 67 03 00 6E 01 72} -->
</pre>
</blockquote>
Note that the only way to encode '{' and '}' themselves is in the hexadecimal mode. <p>
To be more precise, a hexadecimal encoded data enclosed within '<' and '>' consists of a sequence of hex characters
(the digits 0 through 9 and the letters A through F or a through f) . Each pair of hex digits defines a byte.
White-space characters are ignored. If there is an odd number of digits, the final digit that is missing is assumed to
be zero. For example, { 1B 28a } will be treated as {1b28a0}. <p>
There is also a short-hand form which takes advantage of <code>XML</code> attribute syntax
when a primitive object is associated with other object in the context
of <code>XPDO</code> dictionary key/value pairing or <code>XPDO</code> run-time operator operand.
For example, <p>
<blockquote>
<pre>
<XMoveUnit int="60"/> <!-- same as <XMoveUnit><int>60</int></XMoveUnit> -->
</pre>
</blockquote>
As shown in the example, the <code>XMoveUnit</code> is an empty-element tag with a single attribute
to explicitly declare its type and value. <p>
There are several <code>XPDO</code> compound types. They include array, dictionary and all executable objects
for flow control, math and formatting operations etc. <p>
An array object is enclosed in the <ary> start-tag and </ary> end-tag.
The nested elements of an array can be any <code>XPDO</code> primitive and compound types.
When all nested elements are of the same primitive type except the string type, a short-hand form is provided.
Consider the the following example: <p>
<blockquote>
<pre>
<MasterUnit>
<ary>
<int>720</int>
<int>432</int>
</ary>
</MasterUnit>
</pre>
</blockquote>
It can be also specified in a more concise manner. As shown below,
the nested element values are delimited by <code>XML</code> white spaces and
they must be all integer type which can be further reinforced via
the new <intary> start-tag and </intary> end-tag. <p>
<blockquote>
<pre>
<MasterUnit>
<intary>720 432</intary>
</MasterUnit>
</pre>
</blockquote>
When the integer array short form is combined with the attributed short-form mentioned earlier,
it can be specified as simple as shown below: <p>
<blockquote>
<pre>
<MasterUnit intary="720 432"/>
</pre>
</blockquote>
Similarly to the name array, float array and boolean array except the new <code><nameary>, <floatary>
and <boolary></code> tags are used respectively. <p>
A dictionary object is enclosed in the <dict> start-tag and </dict> end-tag.
The nested elements of a dictionary are nothing but key/value pairs (also referred to as entries).
Those entries are specified via the <entry> start-tag and </entry> end-tag as below: <p>
<blockquote>
<pre>
<Declarations>
<dict>
<entry name="MasterUnit"><intary>720 432</intary></entry>
<!-- ... -->
</dict>
</Declarations>
</pre>
</blockquote>
As shown, there is an attribute to specify an entry key which can be of any primitive type and
array type. An entry value can be of any primitive and compound type including dictionary itself. <p>
Note that when a dictionary entry key is a pre-definded <code>XPDO</code> name such as
<code>MasterUnit</code> in the previous example, the general <entry> tag which
is provided for printer vendor defined custom printer properties can be replaced
by the predefinded tag for that pre-definded name. Note also that when an entry value of an
pre-definded entry key name is allowed to be an dictionary only, the <dict> tag
can be removed. It is demonstrated below as a more concise version of the previous example. <p>
<blockquote>
<pre>
<Declarations>
<MasterUnit intary="720 432"/>
<!-- ... -->
</Declarations>
</pre>
</blockquote>
The conciseness due to the short-hand form is much preferred since
such a construct is so typical to appear almost everywhere in a <code>XPDO</code>document. <p>
Finally, An example that deals with a variety of object types is shown below: <p>
<pre>
<blockquote>
<CmdSelect> <!-- pre-definded CmdSelect is an dictionary with three entries:
two pre-definded Order, Cmd entries and a custom MyNotPredefined entry -->
<dict>
<Order> <!-- pre-definded Order is an array with two elements:
a pre-definded name JOB_SETUP and an integer 10 -->
<ary>
<name>JOB_SETU;</name>
<int>10</int>
</ary>
</Order>
<Cmd str="printer control commands"/>
<entry name="MyNotPredefined"><int>9</int></entry>
</dict>
</CmdSelect>
</pre>
</blockquote>
which can be abbreviated as below: <p>
<pre>
<blockquote>
<CmdSelect>
<Order name="JOB_SETUP" int="10">
<Cmd str="printer control commands"/>
<entry name="MyNotPredefined">
<int>9</int>
</entry>
</CmdSelect>
</pre>
</blockquote>
In addition to the three general short-hand forms which are attributed short-hand form,
array short-hand form and dictionary short-hand form, there are also short-hand forms that
are specific to particular pre-definded tags such as <code><Order></code> as shown
in the previous example. <p>
A name object as the typical data type of a dicitonary key is much faster to match (as opposed to
string type) in that it is the internal representation (usually the address where the name is stored)
rather than the character string for the name that gets involved for the key matching process. <p>
Note that the generic <code><entry></code> tag is for a custom entry whose key name is defined by
printer vendors. For another example, <p>
<pre>
<blockquote>
<PaperSize>
<Options>
<A4>
<Name str="A4, 210 x 297 mm"/> <!-- optional for predefined paper size -->
<PrintableOrigin intary="..."/> <!-- required for any paper size -->
<!-- ... -->
</A4>
<entry name="MyCustomPaperSize">
<Name str="My Custom Paper Size: x by y"/> <!-- required only for custom paper size -->
<PrintableOrigin intary="..."/> <!-- required for any paper size -->
<PageDimensions intary="..."/> <!-- required only for custom paper size -->
<!-- ... -->
</entry>
<!-- ... -->
</Options>
<!-- ... -->
</PaperSize>
</pre>
</blockquote>
A <code>XPDO</code> document is encoded as a single dictionary object which
contains some key/value pairs whose value may be of dictionary type. A <code>XPDO</code> object hierarchy
formed in that manner can then serve as a base for the <code>XPDO</code> modulization
(file merging for printer description inheritance) mechanism. <p>
<!...............................5.5.........>
<A NAME="xpdomodulization"></a>
<font size="+1" color=#ff0000><b>XPDO File Modulization for Printer Model Family Hierarchies</b></font><br> <p>
Printer models in a same product family share a lot in common. A bunch of related <code>XPDO</code> files
can be grouped together in a hierarchy via the <code>xpdo extend</code> processing instruction
in order to reflect the model structure of a printer product family in a nature way. <p>
Consider the following two <code>XPDO</code> files to be merged, <p>
<blockquote>
<pre>
<!-- base.xpdo file -->
<?xml version="1.0">
<XPDO>
<Dictionary>
<Base str="BASE"/>
<Untouched str="SAME"/>
</Dictionary>
<Base>
<!-- Base... -->
</Base>
<Untouched str="SAME"/>
</XPDO>
<!-- derived.xpdo file -->
<?xml version="1.0">
<?xpdo extend="base.xpdo"/>
<XPDO>
<Dictionary>
<Derived str="DERIVED"/>
<Base str="DERIVED"/>
</Dictionary>
<Derived str="DERIVED"/>
<Base str="DERIVED"/>
</XPDO>
</pre>
</blockquote>
Loading the <code>derived.xpdo</code> file would collect the following single XPDO dictionary object in memory as
a result of merging its extended <code>base.xpdo</code> file: <p>
<blockquote>
<pre>
<?xml version="1.0">
<XPDO>
<Dictionary>
<Base str="DERIVED"/> <!-- overridden from the old value: (Base) -->
<Untouched str="SAME"/>
<Derived str="DERIVED"/> <!-- new entry -->
</Dictionary>
<Base str="DERIVED"/> <!-- overridden from the old value: Base dictionary -->
<Untouched str="SAME"/>
<Derived str="DERIVED"/> <!-- new entry -->
</XPDO>
</pre>
</blockquote>
The <code>XPDO</code> files merging based on the <code>xpdo extend</code> processing instruction can
therefore work in such a simple way that is described in the following rules based on dictionary
deep (recursively) merge: <p>
<ol>
<li>Collect base dictionary and derived dictionary from the base XPDO file and derived XPDO file respectively. <p>
<li>Enumerate all entries in the derived dictionary and apply each of them with the following rules. <p>
<li>If an entry doesn't exist in its base xpdo file, it is simply added to the base dictionary. <p>
<li>If an entry does exist in its base xpdo file and the base value and the derived value are neither dictionary,
the base value is overridden by the derived value. <p>
<li>Otherwise, apply rule 2 to rule 5 recursivley with the base dictionary value and derived dictionary value. <p>
</ol>
Note that the iteration order of a dictionary defaults to what the dictionary entries are checked in. It is
usually the order specified lexically during loading time. However, when dictionaries are merged
the iteration order for new entries may not be what is appropriate for GUI presentation).
An optional <code><EntryOrder></code> entry can be added to explicitly specify the iteration order.
The value is an array consist of key names for all dictionary entries. <p>
A <code>XPDO</code> hierarchy can be as deep as needed. <p>
The following hierarchy demonstrates a possible real-life printer product family would look like in their entirety: <p>
<blockquote>
<pre>
HP_Raster
HP_DeskJet_600_Monochrome
HP_DeskJet_540_Monochrome
HP_PaintJet
HP_DeskJet_Plus
HP_DeskJet_400_Monochrome
HP_DeskJet_6xx
HP_DeskJet_67x
HP_DeskJet_660Cse
HP_DeskJet_660C
HP_DeskJet_670C
HP_DeskJet_672C
HP_DeskJet_69x
HP_DeskJet_680C
HP_DeskJet_682C
HP_DeskJet_690C
HP_DeskJet_692C
HP_DeskJet_693C
HP_DeskJet_694C
HP_DeskJet_695C
HP_DeskJet_697C
HP_DeskJet_600
HP_QuietJet
HP_DeskJet_400
HP_DeskJet_85x
HP_DeskJet_850C
HP_DeskJet_855Cse
HP_DeskJet_855Cxi
HP_DeskJet_420
HP_DeskJet_87x
HP_DeskJet_870C
HP_DeskJet_870Cse
HP_DeskJet_870Cxi
HP_DeskJet_89x
HP_DeskJet_895Cse
HP_DeskJet_895Cxi
HP_DeskJet_560C
HP_DeskJet_82x
HP_DeskJet_820Cse
HP_DeskJet_820Cxi
HP_DeskJet_540
HP_OfficeJet
HP_DeskJet_510
HP_DeskJet_7xx
HP_DeskJet_710C
HP_DeskJet_712C
HP_DeskJet_720C
HP_DeskJet_722C
HP_OfficeJet_LX
HP_DeskJet_500
HP_DeskJet_520
HP_ThinkJet
HP_DeskJet_340_Monochrome
HP_DeskJet_320
HP_DeskJet_340
HP_OfficeJet_3xx
HP_OfficeJet_300
HP_OfficeJet_330
HP_OfficeJet_350
HP_QuietJet_Plus
HP_DeskJet_550C
HP_DeskJet_500C
HP_DeskJet_Portable
HP_DeskJet_310
HP_DeskJet
</pre>
</blockquote>
<!---deleted{-------
Please refer to <a href="#xpdosamples">Appendix I. Sample XPDO files</a> for a real-life product model family hierarchy. <p>
Please also refer to <a href="#schema.extendOp">Appendix V. XPDO Reference Manual: Spec 1.0 Schema</a> for the valid usage of the <code>extend</code> operator. <p>
------deleted}---->
<!---to be edited{------------------------------------->
<A NAME="execobjs"></a>
<font size="+1" color=#ff0000><b>Executable Objects and Execution Context</b></font><br> <p>
In the process of printer description, there are cases where a printing property
is dependent on a user selection in runtime or actual printing data based on a
raster scheme needs to be generated from actual parameters passed by printing
system which does the actual graphics rendering to produce raster data. <p>
An executable object is a <code>XPDO</code> object that is evaluated at run time.
An executable object can consist of one or more nested elements of any object type
as is the case with an array. The result of the evaluation is a single
<code>XPDO</code> object of any type.
An input value is associated with a key name which is referred in the body
Of an executable object. <p>
There can be as many dictionary objects as needed for such an input parameter
loading. A system level stack is introduced as a collection of those
dictionaries and the key mapping order is defined to be from the top all way
down to the bottom of the stack. <p>
The first dictionary object automatically pushed is the so-called <code>setup dictionary</code>
which contains typically selected option (entry value) for all features (entry key). <p>
<blockquote>
<pre>
| | Top
| |
| . |
| . |
| . |
| |
| +------------------------+ |
| | parameter dictionary | |
| | for a nested executable| | (Only during the evaluation of the nested executable object for the parameters)
| | objects, if any | |
| +------------------------+ |
| |
| +----------------------+ |
| | parameter dictionary | |
| | containing one or | | (Only during the evaluation of an executable object for the parameters)
| | more entries | |
| +----------------------+ |
| |
| +----------------------+ |
| | setup dictionary | | (Always available)
| +----------------------+ |
+----------------------------+ Bottom
System dictionary stack
(Execution Context)
</pre>
</blockquote>
<!--........................-->
<A NAME="load"></a>
<font size="+1" color=#ff0000><b>The load Executable Object and Parameter Dictionaries</b></font><br> <p>
The <load> executable object is introduced to explicitly load an object from
the system dictionary stack. <p>
For example, the following load object will load the currently selected
paper size from the system setup dictionary: <p>
<blockquote>
<pre>
<load name="PaperSize"> <!-- returning a A4 name object, for example -->
</pre>
</blockquote>
Take another example shown below regarding a parametric executable object
evaluation:
<blockquote>
<pre>
<CmdYMoveAbsolute>
<!-- ... -->
<load name="DestY"/>
<!-- ... -->
</CmdYMoveAbsolute>
</pre>
</blockquote>
Note that the pre-definded parameter <code>DestY</code> is specific to the
pre-definded <code>CmdYMoveAbsolute</code> entry. Mechanically, a parameter
dictionary containing the entry with the name <code>DestY</code> as its key and
the current DestY as its integer value will be pushed to the system dictionary
stack before the evaluation takes place. It is shown as below: <p>
<blockquote>
<pre>
| | Top
| +----------------------+ |
| | parameter dictionary | |
| | containing the | | (Only during the evaluation of CmdYMoveAbsolute)
| | DestY entry | |
| +----------------------+ |
| |
| +----------------------+ |
| | setup dictionary | | (Always available)
| +----------------------+ |
+--------------------------+ Bottom
System Dictionary Stack
</pre>
</blockquote>
<!--........................-->
<A NAME="switch"></a>
<font size="+1" color=#ff0000><b>The switch Executable Object</b></font><br> <p>
The <code>switch</code> executable object provide a flow control at runtime. The
following example demonstrates how the origin of a printable area for a particular
paper size will depend on the paper orientation a user will select. <p>
<blockquote>
<pre>
<PaperSize>
<Name str="Paper Size"/>
<Options>
<A4>
<Name str="A4, 210 x 297 mm"/>
<PrintableOrigin>
<switch name="Orientation"> <!-- returning an integer object as the
associated with the Orientation key
in the system setup dictionary
-->
<case name="PORTRAIT" intary="300 300"/>
<case name="LANDSCAPE_CC90" intary="200 180"/>
<default intary="180 200"/>
</switch>
</PrintableOrigin>
<!-- ... -->
</A4>
<!-- ... -->
</Options>
<!-- ... -->
</PaperSize>
</pre>
</blockquote>
The printable origin of A4 size in case of portrait printing requested by
a user is <code>(300,300)</code>, <code>(200,180)</code> in case of LANDSCAPE (counter clockwise by 90 degree)
or <code>(180, 200)</code> in other cases. <p>
The <switch> construct shown in the previous example actually is an
abbreviation of a general form of how a switch object
Can be instantiated in memory or encoded in a binary stream. The most general
form of the previous example is shown as below: <p>
<blockquote>
<pre>
<switch>
<load name="Resolution">
<dict>
<entry name="PORTRAIT" intary="300 300"/>
<entry name="LANDSCAPE_CC90" intary="200 180"/>
<entry name="-default-" intary="180 200"/>
</dict>
</switch>
</pre>
</blockquote>
The <case> tag is only a more readable alias of <entry> tag and the
<default> tag is an abbreviation of a dictionary entry whose key is a
reserved name called "-default-". <p>
Just consider a switch object as yet another compound object. The first object
It contains can be of any type that is qualified as a dictionary key as a
runtime condition. As a control flow language construct, the object is typically
evaluated at runtime as a retuned value of a <load> tag. The second object is
a dictionary object whose entries serve a case pool.
An entry key is used to match the first condition object and when matched its
associated value is used for a returned value of a switch construct. The default
entry provided a default case if present or otherwise a null object is returned
to indicate an exceptional situation may arise. However, an warning message can
also be issued by a validating tool at loading time for pre-definded names in the
Switch construct. <p>
<!--........................-->
<A NAME="math"></a>
<font size="+1" color=#ff0000><b>The Math Executable Objects: idiv, add, sub, expr</b></font><br> <p>
There are cases where a parameter needs to be subject to mathematics operations such as
addition, subtraction and division. <p>
<A NAME="math.idiv"></a>
The <code>idiv</code> executable object must contain two integer objects. The first integer
will be divided by the second integer. Take the following as an example: <p>
<blockquote>
<pre>
<idiv>
<load name="DestY"/>
<int>2</int>
</idiv>
</pre>
</blockquote>
The returned value will be 3 given that the current value of <code>DestY</code> is 7. <p>
<A NAME="math.expr"></a>
For many frequently used expression, the <code>expr</code> executable object
is introduced to provide an optimized short form by the <code>expr</code> executable object.
The previous example can then also be specified as below: <p>
<blockquote>
<pre>
<expr str="idiv(DestX,2)"/>
</pre>
</blockquote>
There are many other pre-definded expression such as "idiv(DestY,2)", "numformat(NumOfDataBytes+1,'l')". <p>
<A NAME="math.addsub"></a>
Similarly to other math executable objects such as <code>add</code> and <code>sub</code> except that
the two nested elements they contains can be either integer or floating-point number type. <p>
<!--........................-->
<A NAME="formatter"></a>
<font size="+1" color=#ff0000><b>The Formatter Executable Objects</b></font><br> <p>
<A NAME="formatter.tostring"></a>
The value of the <code>CmdYMoveAbsolute</code> entry of the following example
will be <code>(1B)*p7Y</code> given that the current value of <code>DestY</code> is 7.
This is because a string object will be resulted from a concatenation of all nested elements
enclosed in the <code>tostring</code> executable object. <p>
<blockquote>
<pre>
<CmdYMoveAbsolute>
<tostring>
<str>(1B)*p</str>
<load name="DestY"/>
<str>Y</str>
</tostring>
</CmdYMoveAbsolute>
</pre>
</blockquote>
The <code>tostring</code> executable object is evaluated in such a way that: <p>
<ol>
<li>In case that a nested element is an executable object, it will be evaluated first as discussed
earlier and the executable object will be replaced by any object returned. <br>
<li>All elements will be converted to their textual representation as a string
object. <br>
<li>All string object will then be concatenated into a single string object. <br>
</ol>
<A NAME="numformat"></a>
The <code><numformat></code> executable object is introduced in case where a special integer formatting is needed.
For example, the '+' sign is not printed for signed integer if it is greater than 0 by the <code><tostring></code>.
The <code>numformat</code> executable object consists of one integer object followed by a string object indicating
its pre-definded formatting code. <p>
<blockquote>
<pre>
<numformat int="12" str='d'/> <!-- returning "12" which consists of two ASCII characters '1' and '2'
as what the tostring formatting does
-->
<numformat><int>12</int><str>D</str></numformat> <!-- returning "+12" which is the same as above except that
the + sign is included if the integer is greater than 0.
-->
<expr str="numformat(DestX,'l')"> <!-- returning "(0201)" which is a two-byte string with low-order byte (LSB) first
given DestX = 0x0102 (16-bit integer)
-->
<expr str="numformat(DestX,'m')"> <!-- returning "(0102)" which is a two-byte string with high-order byte (MSB) first
given DestX = 0x0102 (16-bit integer)
-->
</pre>
</blockquote>
<A NAME="maxrepeat"></a>
In cases where a printer command is forced to be emitted more than once due to its
allowable maximum value range in the command encoding,
the <code><maxrepeat></code> executable object can be very useful. <p>
The first and second object contained are both integer. The third object is an
executable object which is evaluated repeatedly using a maximum allowed
value as the first integer object) until the accumulated value is equal to
a total value as the second integer object. <p>
For the input of each executable object evaluation, a share value will be
associated automatically in the <code><MaxRepeatInstance</code>
as is the case with any other pre-definded parameters handled in the system dictionary stack.
For each returned object as a result of the third executable object evaluation, it will be
automatically converted to a textual representation and concatenated with the accumulation of
all previous repeated evaluation outputs. In other words, the final returned object of the
<code><maxrepeat></code> executable object as a whole is the same as the returned object
of an <code><tostring></code> evaluation with all those repeatedly returned objects as its
nested elements. <p>
Considering the following simple example: <p>
<blockquote>
<pre>
<maxrepeat>
<int>2</str> <!-- 1st object: limit -->
<int>5</str> <!-- 2nd object: total -->
<load name="MaxRepeatInstance"/> <!-- 3rd executable object to be repeatedly evaluated
to collect all share values stored in the
pre-definded MaxRepeatInstance -->
</maxrepeat>
</pre>
</blockquote>
which will return a string object which is the same as the object encoded below: <p>
<blockquote>
<pre>
<str>221</str> <!-- i.e., there are three shares, non of which exceeds the limit (2).
The sum of all shares (2+2+1) is the total (5) -->
</pre>
</blockquote>
For two more real-life examples: <p>
<blockquote>
<pre>
<CmdSendBlockData> <!-- pre-definded parameter: NumOfDataBytes -->
<maxrepeat> <!-- an executable object that describes how a CmdSendBlockData is
generated with a value-range encoding limit -->
<int>5100</int> <!-- limit -->
<load name="NumOfDataBytes"> <!-- total -->
<tostring> <!-- 3rd executable object to be repeatedly evaluated -->
<str>{1B}*{03}</str>
<expr str="numformat(MaxRepeatInstance,'l')"/>
</tostring>
</maxrepeat>
</CmdSendBlockData>
<CmdYMoveRelUp> <!-- pre-definded parameter: DestYRel -->
<maxrepeat> <!-- an executable object that describes how a CmdSendBlockData is
generated with a value-range encoding limit -->
<int>12600</str> <!-- limit -->
<load name="DestYRel"/> <!-- total -->
<tostring> <!-- 3rd executable object to be repeatedly evaluated -->
<str>{1B}(*p-</str>
<load name="MaxRepeatInstance"/>
</tostring>
</maxrepeat>
</CmdYMoveRelUp>
</pre>
</blockquote>
The following shows what the system dictionary stack looks like for the evaluation of <CmdSendBlockData>
in the example (similar to the <CmdYMoveRelUp>). <p>
<blockquote>
<pre>
| | Top
| +-------------------------+ |
| | parameter dictionary | |
| | containing the | | (Pushed and poped for each evaluation of 3rd executable object of maxrepeat)
| | MaxRepeatInstance entry | |
| +-------------------------+ |
| |
| +-------------------------+ |
| | parameter dictionary | |
| | containing the | | (Only during the evaluation of CmdSendBLockData)
| | NumOfDataBytes entry | |
| +-------------------------+ |
| |
| +-------------------------+ |
| | setup dictionary | | (Always available)
| +-------------------------+ |
+-----------------------------+ Bottom
System Dictionary Stack
</pre>
</blockquote>
<!---}to be edited------------------------------------->