Cool, that helps.
This is specific to UTF-8 decoding, but I sort of wanted to have generic
bitwise operations. I was actually surprised those aren't in the base
operators but whatever.
Cheers,
E.
On 2/16/11 9:15 AM, "Chris Maloney" <voldrani(_at_)gmail(_dot_)com> wrote:
[Sorry, hit the "Send" button by mistake.]
I thought of some more optimizations on the way to work this morning.
First of all, you can simplify your expressions:
....
<xsl:variable name="byte1Bit7"
select="if ($byte1 > 127) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit6"
select="if ($byte1 mod 128 > 63) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit5"
select="if ($byte1 mod 64 > 31) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit4"
select="if ($byte1 mod 32 > 15) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit3"
select="if ($byte1 mod 16 > 7) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit2"
select="if ($byte1 mod 8 > 3) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit1"
select="if ($byte1 mod 4 > 1) then 1 else 0"
as="xs:integer"/>
<xsl:variable name="byte1Bit0"
select="$byte1 mod 2"
as="xs:integer"/>
...
Then, it occurred to me that if you're doing bitwise-and specifically
for utf-8 conversion, then you can optimize this quite a bit. The
ANDing needed by utf-8 conversion is never to a random bit pattern,
but instead to fixed bit-masks, where the bits are always grouped
together. So, for example, you could make a specific function to AND
with 0x3F:
<xsl:function name="relpath:bitwiseAnd3F" as="xs:integer">
<xsl:param name="arg" as="xs:integer"/>
<xsl:variable name='result'
as='xs:integer'
select="$arg mod 64"/>
<xsl:sequence select="$result"/>
</xsl:function>
and its complement to AND with 0xC0:
<xsl:function name="relpath:bitwiseAndC0" as="xs:integer">
<xsl:param name="byte" as="xs:integer"/>
<xsl:variable name='result'
as='xs:integer'
select="($byte - $byte mod 64) / 64"/>
<xsl:sequence select="$result"/>
</xsl:function>
Cheers!
On Tue, Feb 15, 2011 at 5:41 PM, Eliot Kimber
<ekimber(_at_)reallysi(_dot_)com> wrote:
I have implemented UTF-8 URI decoding in XSLT 2. It required that I
implement left-shift and bitwise AND operations. Left-shift is easy but
bitwise AND is a little more involved. My solution is below, but I'm
wondering if there's a more elegant and/or efficient way to do this?
My approach was based on info from Ken Holman's site that shows how to
calculate each bit of the byte. I do that and then sum the result of
multiplying the AND of each bit pair times the appropriate power of two.
<xsl:function name="relpath:bitwiseAnd" as="xs:integer">
<xsl:param name="byte1" as="xs:integer"/>
<xsl:param name="byte2" as="xs:integer"/>
<xsl:variable name="byte1Bit7" select="if (($byte1 mod 256) - ($byte1
mod 128) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit6" select="if (($byte1 mod 128) - ($byte1
mod 64) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit5" select="if (($byte1 mod 64) - ($byte1
mod 32) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit4" select="if (($byte1 mod 32) - ($byte1
mod 16) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit3" select="if (($byte1 mod 16) - ($byte1
mod 8) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit2" select="if (($byte1 mod 8) - ($byte1
mod 4) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit1" select="if (($byte1 mod 4) - ($byte1
mod 2) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte1Bit0" select="if (($byte1 mod 2) > 0) then 1
else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit7" select="if (($byte2 mod 256) - ($byte2
mod 128) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit6" select="if (($byte2 mod 128) - ($byte2
mod 64) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit5" select="if (($byte2 mod 64) - ($byte2
mod 32) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit4" select="if (($byte2 mod 32) - ($byte2
mod 16) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit3" select="if (($byte2 mod 16) - ($byte2
mod 8) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit2" select="if (($byte2 mod 8) - ($byte2
mod 4) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit1" select="if (($byte2 mod 4) - ($byte2
mod 2) > 0) then 1 else 0" as="xs:integer"/>
<xsl:variable name="byte2Bit0" select="if (($byte2 mod 2) > 0) then 1
else 0" as="xs:integer"/>
<xsl:variable name="result" as="xs:integer"
select="
(128 * $byte2Bit7 * $byte1Bit7) +
(64 * $byte2Bit6 * $byte1Bit6) +
(32 * $byte2Bit5 * $byte1Bit5) +
(16 * $byte2Bit4 * $byte1Bit4) +
(8* $byte2Bit3 * $byte1Bit3) +
(4 * $byte2Bit2 * $byte1Bit2) +
(2 * $byte2Bit1 * $byte1Bit1) +
(1 * $byte2Bit0 * $byte1Bit0)
"
/>
<xsl:sequence select="$result"/>
</xsl:function>
Cheers,
E.
--
Eliot Kimber
Senior Solutions Architect
"Bringing Strategy, Content, and Technology Together"
Main: 512.554.9368
www.reallysi.com
www.rsuitecms.com
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail:
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--
--
Eliot Kimber
Senior Solutions Architect
"Bringing Strategy, Content, and Technology Together"
Main: 512.554.9368
www.reallysi.com
www.rsuitecms.com
--~------------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--