Re: Binary output method

Dylan Doxey <[email protected]>
Newsgroups gmane.org.w3c.xsl-editors
Message-ID <[email protected]>



Hello XSLT 1.1 Editors,

This is in response to a posting I found by Peter Ciuffetti dated Fri, 16 
Feb 2001.
I enjoyed writing this. I hope it is still needed 20 months after the fact.

Dylan Doxey
[email protected]


============================================================================ 
====
============================================================================ 
====


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>

<!--
	decode64 will convert an arbitrary length base64 string to the ASCII 
character form.
	It is limited to printable ASCII characters on the range of 32 to 127.
	Author: Dylan Doxey - [email protected]
	Date: October 18, 2002
	Credit: Idea and "ctoi" section go to Pete Ciuffetti
-->


<!-- This accepts a base64 string of arbitray length and translates it to 
an ASCII character string. -->
<xsl:template name="decode64">
	<xsl:param name="b64string"/>
	<xsl:variable name="padding">===</xsl:variable>
	<!-- Ensure that the lenght of the input is a multiple of 4. -->
	<xsl:variable name="b64stringPadded" select="concat($b64string, 
substring($padding, 1, (string-length($b64string) mod 4)))"/>
	<!-- Take the first four b64 characters -->
	<xsl:variable name="b64quad" select="substring($b64stringPadded, 1, 4)"/>
	<!-- create a binary string representing the first three ASCII characters -->
	<xsl:variable name="binaryTrio">
		<xsl:call-template name="base642binary">
			<xsl:with-param name="b64quad" select="$b64quad"/>
		</xsl:call-template>
	</xsl:variable>
	<!-- Convert the three bytes to ASCII characters -->
	<xsl:call-template name="bytes2ascii">
		<xsl:with-param name="bytes" select="$binaryTrio"/>
	</xsl:call-template>
	<!-- If there are additional base64 characters to be decoded then recurse. -->
	<xsl:if test="string-length($b64stringPadded) &gt; 4">
		<xsl:call-template name="decode64">
			<xsl:with-param name="b64string" select="substring($b64stringPadded, 5)"/>
		</xsl:call-template>
	</xsl:if>
</xsl:template>

<!-- This will convert three bytes of binary to the appropriate three ASCII 
characters -->
<xsl:template name="bytes2ascii">
	<xsl:param name="bytes"/>
		<xsl:variable name="ascii1">
			<xsl:call-template name="byte2ascii">
				<xsl:with-param name="byte" select="substring($bytes, 1, 8)"/>
				<xsl:with-param name="factor" select="128"/>
			</xsl:call-template>
		</xsl:variable>
		<xsl:variable name="ascii2">
			<xsl:call-template name="byte2ascii">
				<xsl:with-param name="byte" select="substring($bytes, 9, 8)"/>
				<xsl:with-param name="factor" select="128"/>
			</xsl:call-template>
		</xsl:variable>
		<xsl:variable name="ascii3">
			<xsl:call-template name="byte2ascii">
				<xsl:with-param name="byte" select="substring($bytes, 17, 8)"/>
				<xsl:with-param name="factor" select="128"/>
			</xsl:call-template>
		</xsl:variable>
		<xsl:call-template name="ascii2char">
			<xsl:with-param name="ascii" select="$ascii1"/>
		</xsl:call-template>
		<xsl:call-template name="ascii2char">
			<xsl:with-param name="ascii" select="$ascii2"/>
		</xsl:call-template>
		<xsl:call-template name="ascii2char">
			<xsl:with-param name="ascii" select="$ascii3"/>
		</xsl:call-template>
		<!-- xsl:value-of select="$ascii1"/>-<xsl:value-of 
select="$ascii2"/>-<xsl:value-of select="$ascii3"/ -->
</xsl:template>

<!-- This will convert an arbitrary length binary number to decimal. For 
this application it is assumed to be one byte. -->
<xsl:template name="byte2ascii">
	<!-- The binary input -->
	<xsl:param name="byte"/>
	<!-- This is the factor of 2 for the most significant digit -->
	<xsl:param name="factor"/>
	<!-- Calculate the value of the most significant binary digit -->
	<xsl:variable name="first" select="substring($byte, 1, 1) * $factor"/>
	<!-- Recurse to calculate the value of any remaining digits -->
	<xsl:variable name="rest">
		<xsl:choose>
			<xsl:when test="$factor &gt; 1">
				<xsl:call-template name="byte2ascii">
					<xsl:with-param name="byte" select="substring($byte, 2)"/>
					<xsl:with-param name="factor" select="$factor div 2"/>
				</xsl:call-template>
			</xsl:when>
			<!-- xsl:otherwise><xsl:value-of select="substring($byte, 1, 1) * 
$factor"/></xsl:otherwise -->
			<xsl:otherwise>0</xsl:otherwise>
		</xsl:choose>
	</xsl:variable>
	<!-- Display the result -->
	<xsl:value-of select="$first + $rest"/>
</xsl:template>

<!-- Translate a decimal on the range of 32 to 127 to an ASCII character. -->
<xsl:template name="ascii2char">
	<xsl:param name="ascii"/>
	<xsl:variable name="asciiIndex" select="$ascii - 31"/>
	<xsl:variable name="ascii32to126"> 
!"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab 
cdefghijklmnopqrstuvwxyz{|}~</xsl:variable>
	<xsl:value-of select="substring($ascii32to126, $asciiIndex, 1)"/>
</xsl:template>

<!-- Translate an arbitrary length string of base64 characters to binary. 
For this application it is assumed to be four characters at a time. -->
<xsl:template name="base642binary">
	<xsl:param name="b64quad"/>
	<!-- Get the 0-63 value of the first character -->
	<xsl:variable name="octet">
		<xsl:call-template name="ctoi">
			<xsl:with-param name="c" select="substring($b64quad, 1, 1)"/>
		</xsl:call-template>
	</xsl:variable>
	<!-- Gather a six bit (octal) binary number for this character -->
	<xsl:variable name="binary">
		<xsl:call-template name="oct2bin">
			<xsl:with-param name="octal" select="$octet"/>
			<xsl:with-param name="order" select="6"/>
		</xsl:call-template>
	</xsl:variable>
	<!-- display the binary conversion -->
	<xsl:value-of select="$binary"/>
	<!-- recurse for the remaining digits -->
	<xsl:if test="string-length($b64quad) &gt; 1">
		<xsl:call-template name="base642binary">
			<xsl:with-param name="b64quad" select="substring($b64quad, 2)"/>
		</xsl:call-template>
	</xsl:if>
</xsl:template>

<!-- Translate an octal number to its six bit binary form. -->
<xsl:template name="oct2bin">
	<xsl:param name="octal"/>
	<xsl:param name="order"/>
	<xsl:variable name="last"><xsl:value-of select="$octal mod 2"/></xsl:variable>
	<xsl:variable name="rest"><xsl:value-of select="floor($octal div 
2)"/></xsl:variable>
	<xsl:if test="$order &gt; 1">
		<xsl:call-template name="oct2bin">
			<xsl:with-param name="octal" select="$rest"/>
			<xsl:with-param name="order" select="$order - 1"/>
		</xsl:call-template>
	</xsl:if>
	<xsl:choose>
		<xsl:when test="$last != -1"><xsl:value-of select="$last"/></xsl:when>
		<xsl:otherwise>0</xsl:otherwise>
	</xsl:choose>
</xsl:template>

<!-- Convert a base64 Character to an integer via table lookup -->
<xsl:template name="ctoi">
<xsl:param name="c"/>
	<xsl:choose>
		<xsl:when test="$c = 'A'">0</xsl:when>
		<xsl:when test="$c = 'B'">1</xsl:when>
		<xsl:when test="$c = 'C'">2</xsl:when>
		<xsl:when test="$c = 'D'">3</xsl:when>
		<xsl:when test="$c = 'E'">4</xsl:when>
		<xsl:when test="$c = 'F'">5</xsl:when>
		<xsl:when test="$c = 'G'">6</xsl:when>
		<xsl:when test="$c = 'H'">7</xsl:when>
		<xsl:when test="$c = 'I'">8</xsl:when>
		<xsl:when test="$c = 'J'">9</xsl:when>
		<xsl:when test="$c = 'K'">10</xsl:when>
		<xsl:when test="$c = 'L'">11</xsl:when>
		<xsl:when test="$c = 'M'">12</xsl:when>
		<xsl:when test="$c = 'N'">13</xsl:when>
		<xsl:when test="$c = 'O'">14</xsl:when>
		<xsl:when test="$c = 'P'">15</xsl:when>
		<xsl:when test="$c = 'Q'">16</xsl:when>
		<xsl:when test="$c = 'R'">17</xsl:when>
		<xsl:when test="$c = 'S'">18</xsl:when>
		<xsl:when test="$c = 'T'">19</xsl:when>
		<xsl:when test="$c = 'U'">20</xsl:when>
		<xsl:when test="$c = 'V'">21</xsl:when>
		<xsl:when test="$c = 'W'">22</xsl:when>
		<xsl:when test="$c = 'X'">23</xsl:when>
		<xsl:when test="$c = 'Y'">24</xsl:when>
		<xsl:when test="$c = 'Z'">25</xsl:when>
		<xsl:when test="$c = 'a'">26</xsl:when>
		<xsl:when test="$c = 'b'">27</xsl:when>
		<xsl:when test="$c = 'c'">28</xsl:when>
		<xsl:when test="$c = 'd'">29</xsl:when>
		<xsl:when test="$c = 'e'">30</xsl:when>
		<xsl:when test="$c = 'f'">31</xsl:when>
		<xsl:when test="$c = 'g'">32</xsl:when>
		<xsl:when test="$c = 'h'">33</xsl:when>
		<xsl:when test="$c = 'i'">34</xsl:when>
		<xsl:when test="$c = 'j'">35</xsl:when>
		<xsl:when test="$c = 'k'">36</xsl:when>
		<xsl:when test="$c = 'l'">37</xsl:when>
		<xsl:when test="$c = 'm'">38</xsl:when>
		<xsl:when test="$c = 'n'">39</xsl:when>
		<xsl:when test="$c = 'o'">40</xsl:when>
		<xsl:when test="$c = 'p'">41</xsl:when>
		<xsl:when test="$c = 'q'">42</xsl:when>
		<xsl:when test="$c = 'r'">43</xsl:when>
		<xsl:when test="$c = 's'">44</xsl:when>
		<xsl:when test="$c = 't'">45</xsl:when>
		<xsl:when test="$c = 'u'">46</xsl:when>
		<xsl:when test="$c = 'v'">47</xsl:when>
		<xsl:when test="$c = 'w'">48</xsl:when>
		<xsl:when test="$c = 'x'">49</xsl:when>
		<xsl:when test="$c = 'y'">50</xsl:when>
		<xsl:when test="$c = 'z'">51</xsl:when>
		<xsl:when test="$c = '0'">52</xsl:when>
		<xsl:when test="$c = '1'">53</xsl:when>
		<xsl:when test="$c = '2'">54</xsl:when>
		<xsl:when test="$c = '3'">55</xsl:when>
		<xsl:when test="$c = '4'">56</xsl:when>
		<xsl:when test="$c = '5'">57</xsl:when>
		<xsl:when test="$c = '6'">58</xsl:when>
		<xsl:when test="$c = '7'">59</xsl:when>
		<xsl:when test="$c = '8'">60</xsl:when>
		<xsl:when test="$c = '9'">61</xsl:when>
		<xsl:when test="$c = '+'">62</xsl:when>
		<xsl:when test="$c = '/'">63</xsl:when>
		<xsl:otherwise>-1</xsl:otherwise>
	</xsl:choose>
</xsl:template>

</xsl:stylesheet>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.