<?xml version="1.0" encoding="UTF-8"?>
<fos:functions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.w3.org/xpath-functions/spec/namespace fos.xsd"
    xmlns:fos="http://www.w3.org/xpath-functions/spec/namespace">
    
    <fos:global-variables>
    </fos:global-variables>

    <fos:function name="to-octets" prefix="bin">
        <fos:signatures>
            <fos:proto name="to-octets" return-type="xs:integer*">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns binary data as a sequence of integer octets.</p>
        </fos:summary>
        <fos:rules>
            <p>If <code>$in</code> is a zero length binary data then the empty sequence is
                returned.</p>
            <p>Octets are returned as integers from 0 to 255.</p>
        </fos:rules>
    </fos:function>

    <fos:function name="from-octets" prefix="bin">
        <fos:signatures>
            <fos:proto name="from-octets" return-type="xs:base64Binary">
                <fos:arg name="in" type="xs:integer*"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Converts a sequence of octets into binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>Octets are integers from 0 to 255.</p>
            <p>If <code>$in</code> is the empty sequence, the function returns zero-sized binary
                data.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="octet-out-of-range"/> is raised if one of the octets lies
                outside the range 0 – 255. </p>
        </fos:errors>
    </fos:function>

    <fos:function name="hex" prefix="bin">
        <fos:signatures>
            <fos:proto name="hex" return-type="xs:base64Binary?">
                <fos:arg name="in" type="xs:string?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary form of the set of octets written as a sequence of (ASCII) hex
                digits ([0-9A-Fa-f]).</p>
        </fos:summary>
        <fos:rules>
            <p>
                <code>$in</code> will be effectively zero-padded from the left to generate an
                integral number of octets, i.e. an even number of hexadecimal digits.</p>
            <p>Byte order in the result follows (per-octet) character order in the string.</p>
            <p> If <code>$in</code> is an empty string, then the result will be a
                <code>xs:base64Binary</code> with no embedded data.</p>
            <p>If <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="non-numeric-character"/> is raised if <code>$in</code>
                cannot be parsed as a hexadecimal number.</p>
        </fos:errors>
        <fos:notes>
            <p>When the input string has an even number of characters, this function behaves
                similarly to the double cast
                <code>xs:base64Binary(xs:hexBinary(<emph>$string</emph>))</code>.</p>
        </fos:notes>
        <fos:examples>
            <fos:example>
                <eg xml:space="preserve">bin:hex('11223F4E') → "ESI/Tg=="</eg>
            </fos:example>
            <fos:example>
                <eg xml:space="preserve">bin:hex('1223F4E') → "ASI/Tg=="</eg>
            </fos:example>
        </fos:examples>
    </fos:function>

    <fos:function name="bin" prefix="bin">
        <fos:signatures>
            <fos:proto name="bin" return-type="xs:base64Binary?">
                <fos:arg name="in" type="xs:string?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary form of the set of octets written as a sequence of (8-wise)
                (ASCII) binary digits ([01]).</p>
        </fos:summary>
        <fos:rules>
            <p>
                <code>$in</code> will be effectively zero-padded from the left to generate an
                integral number of octets (i.e. the number of characters in <code>$in</code> will be
                a multiple of 8).</p>
            <p>Byte order in the result follows (per-octet) character order in the string.</p>
            <p> If <code>$in</code> is an empty string, then the result will be a
                <code>xs:base64Binary</code> with no embedded data.</p>
            <p>If <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="non-numeric-character"/> is raised if <code>$in</code>
                cannot be parsed as a binary number.</p>
        </fos:errors>
        <fos:examples>
            <fos:example>
                <eg xml:space="preserve">bin:bin('1101000111010101') → "0dU="</eg>
            </fos:example>
            <fos:example>
                <eg xml:space="preserve">bin:bin('1000111010101') → "EdU="</eg>
            </fos:example>
        </fos:examples>
    </fos:function>

    <fos:function name="octal" prefix="bin">
        <fos:signatures>
            <fos:proto name="octal" return-type="xs:base64Binary?">
                <fos:arg name="in" type="xs:string?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary form of the set of octets written as a sequence of (ASCII) octal
                digits ([0-7]).</p>
        </fos:summary>
        <fos:rules>
            <p>
                <code>$in</code> will be effectively zero-padded from the left to generate an
                integral number of octets.</p>
            <p>Byte order in the result follows (per-octet) character order in the string.</p>
            <p> If <code>$in</code> is an empty string, then the result will be a
                <code>xs:base64Binary</code> with no embedded data.</p>
            <p>If <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="non-numeric-character"/> is raised if <code>$in</code>
                cannot be parsed as an octal number.</p>
        </fos:errors>
        <fos:examples>
            <fos:example>
                <eg xml:space="preserve">bin:octal('11223047') → "JSYn"</eg>
            </fos:example>
        </fos:examples>
    </fos:function>

    <fos:function name="part" prefix="bin">
        <fos:signatures>
            <fos:proto name="part" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="size" type="xs:integer?" default="()"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns a specified part of binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns a section of binary data starting at the <code>$offset</code> octet. If
                <code>$size</code> is defined, the size of the returned binary data is
                <code>$size</code> octets. If <code>$size</code> is absent, all remaining data from
                <code>$offset</code> is returned.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>The values of <code>$offset</code> and <code>$size</code>
                <rfc2119>must</rfc2119> be non-negative integers.</p>
            <p>It is a dynamic error if <code>$offset</code> + <code>$size</code> is larger than the
                size of the binary data in <code>$in</code>.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset + $size</code> is larger than the size of the binary data
                of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
        </fos:errors>
        <fos:notes>
            <p>Note that <code>fn:subsequence()</code> and <code>fn:substring()</code>
                <!--<bibref ref="fo11"/>--> both use <code>xs:double</code> for offset and size –
                this is a legacy from XPath 1.0.</p>
        </fos:notes>
        <fos:examples>
            <fos:example>
                <p>Testing whether <code>$data</code> variable starts with binary content consistent
                    with a PDF file:</p>
                <eg xml:space="preserve">bin:part($data, 0, 4) eq bin:hex("25504446")</eg>
                <p><code>25504446</code> is the magic number for PDF files: it is the US-ASCII
                    encoded hexadecimal value for <code>%PDF</code>.
                    <code>bin:encode-string</code><!--<specref ref="encode-string"/>--> can be used
                    to convert a string to its binary representation.</p>
            </fos:example>
        </fos:examples>
    </fos:function>

    <fos:function name="insert-before" prefix="bin">
        <fos:signatures>
            <fos:proto name="insert-before" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="extra" type="xs:base64Binary?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Inserts additional binary data at a given point in other binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns binary data consisting sequentially of the data from <code>$in</code> upto
                and including the <code>$offset - 1</code> octet, followed by all the data from
                <code>$extra</code>, and then the remaining data from <code>$in</code>.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>The value of <code>$offset</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>


            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
            <p>If the value of <code>$extra</code> is the empty sequence, the function returns
                <code>$in</code>.</p>
            <p>If <code>$offset eq 0</code> the result is the binary concatenation of
                <code>$extra</code> and <code>$in</code>, i.e. equivalent to
                <code>bin:join(($extra,$in))</code>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset</code> is larger than the size of the binary data of
                <code>$in</code>.</p>
        </fos:errors>
        <fos:notes>
            <p>Note that when <code>$offset gt 0 and $offset lt bin:size($in)</code> the function is
                equivalent to:</p>
            <eg>bin:join((bin:part($in,0,$offset - 1),$extra,bin:part($in,$offset)))</eg>
        </fos:notes>
    </fos:function>

    <fos:function name="length" prefix="bin">
        <fos:signatures>
            <fos:proto name="length" return-type="xs:integer">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the size of binary data, measured in octets.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns the size of binary data in octets.</p>
        </fos:rules>
        <fos:equivalent style="xpath-expression" covers-error-cases="true">
            count(bin:to-octets($in)) </fos:equivalent>
    </fos:function>

    <fos:function name="join" prefix="bin">
        <fos:signatures>
            <fos:proto name="join" return-type="xs:base64Binary">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)*"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary data created by concatenating the binary data items in a
                sequence.</p>
        </fos:summary>
        <fos:rules>
            <p>The function returns an <code>xs:base64Binary</code> created by concatenating the
                items in the sequence <code>$in</code>, in order.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns a binary
                item containing no data bytes.</p>
        </fos:rules>
        <fos:equivalent style="xpath-expression" covers-error-cases="true"> bin:from-octets($in !
            bin:to-octets(.)) </fos:equivalent>
    </fos:function>

    <fos:function name="pad-left" prefix="bin">
        <fos:signatures>
            <fos:proto name="pad-left" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="size" type="xs:integer"/>
                <fos:arg name="octet" type="xs:integer?" default="0"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary data created by padding <code>$in</code> with <code>$size</code>
                octets from the left. The padding octet values are <code>$octet</code> or zero if
                omitted.</p>
        </fos:summary>
        <fos:rules>
            <p>The function returns an <code>xs:base64Binary</code> created by padding the input
                with <code>$size</code> octets <emph>in front of</emph> the input. If
                <code>$octet</code> is specified, the padding octets each have that value, otherwise
                they are initialized to 0.</p>
            <p><code>$size</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
            <p><errorref spec="BIN40" code="octet-out-of-range"/> is raised if <code>$octet</code>
                lies outside the range 0 – 255. </p>
        </fos:errors>
        <fos:equivalent style="xpath-expression" covers-error-cases="false">
            bin:join((bin:from-octets((1 to $size) ! $octet), $in)) </fos:equivalent>
        <!--<fos:notes>
            <p>Padding with a non-zero octet value can also be accomplished by the XPath
                expressions:</p>
            <eg xml:space="preserve">bin:join((bin:from-octets((1 to $pad-length) ! $pad-octet), $in)) [XPath 3.0]</eg>
            <eg xml:space="preserve">bin:join((bin:from-octets(for $ i in (1 to $pad-length) return $pad-octet), $in)) [XPath 2.0]</eg>
        </fos:notes>-->
    </fos:function>
    
    <fos:function name="pad-right" prefix="bin">
        <fos:signatures>
            <fos:proto name="pad-right" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="size" type="xs:integer"/>
                <fos:arg name="octet" type="xs:integer?" default="0"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the binary data created by padding <code>$in</code> with <code>$size</code>
                blank octets from the right. The padding octet values are <code>$octet</code> or
                zero if omitted.</p>
        </fos:summary>
        <fos:rules>
            <p>The function returns an <code>xs:base64Binary</code> created by padding the input
                with <code>$size</code> blank octets <emph>after</emph> the input. If
                <code>$octet</code> is specified, the padding octets each have that value, otherwise
                they are initialized to 0.</p>
            <p><code>$size</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
            <p><errorref spec="BIN40" code="octet-out-of-range"/> is raised if <code>$octet</code>
                lies outside the range 0 – 255. </p>
        </fos:errors>
        <fos:equivalent style="xpath-expression" covers-error-cases="false">
            bin:join((bin:from-octets($in,(1 to $size) ! $octet))) </fos:equivalent>
       <!-- <fos:notes>
            <p>Padding with a non-zero octet value can also be accomplished by the XPath
                expressions:</p>
            <eg xml:space="preserve">bin:join(($in,bin:from-octets((1 to $pad-length) ! $pad-octet)))  [XPath 3.0]</eg>
            <eg xml:space="preserve">bin:join(($in,bin:from-octets(for $ i in (1 to $pad-length) return $pad-octet)))  [XPath 2.0]</eg>
        </fos:notes>-->
    </fos:function>

    <fos:function name="find" prefix="bin">
        <fos:signatures>
            <fos:proto name="find" return-type="xs:integer?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="search" type="(xs:hexBinary | xs:base64Binary)"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the first location in <code>$in</code> of <code>$search</code>, starting at
                the <code>$offset</code> octet.</p>
        </fos:summary>
        <fos:rules>
            <p>The function returns the first location of the binary search sequence in the input,
                or if not found, the empty sequence.</p>
            <p>If <code>$search</code> is empty <code>$offset</code> is returned.</p>

            <p>The value of <code>$offset</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>The returned location is zero based.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset</code> is larger than the size of the binary data of
                <code>$in</code>.</p>
        </fos:errors>
        <fos:notes>
            <p>Finding all the matches can be accomplished with simple recursive application:</p>
            <eg xml:space="preserve"><![CDATA[
<xsl:function name="f:find-all" as="xs:integer*">
     <xsl:param name="data" as="xs:base64Binary?"/>
     <xsl:param name="offset" as="xs:integer"/>
     <xsl:param name="pattern" as="xs:base64Binary"/>
     <xsl:sequence
         select="if(bin:length($pattern) = 0) then ()
         else let $found := bin:find($data,$offset,$pattern) return
         if($found) then ($found,
             if($found + 1 lt bin:length($data)) then f:find-all($data,$found + 1,$pattern) else ())
             else ()"/>
</xsl:function>]]></eg>
        </fos:notes>
    </fos:function>

    <fos:function name="decode-string" prefix="bin">
        <fos:signatures>
            <fos:proto name="decode-string" return-type="xs:string?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="encoding" type="xs:string?" default="'utf-8'"/>
                <fos:arg name="offset" type="xs:integer?" default="0"/>
                <fos:arg name="size" type="xs:integer?" default="()"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Decodes binary data as a string in a given encoding.</p>
        </fos:summary>
        <fos:rules>
            <p>If <code>$offset</code> and <code>$size</code> are provided, the <code>$size</code>
                octets from <code>$offset</code> are decoded. If <code>$offset</code> alone is
                provided, octets from <code>$offset</code> to the end are decoded, otherwise the
                entire octet sequence is used.</p>
            <p>The <code>$encoding</code> argument is the name of an encoding. The values for this
                attribute follow the same rules as for the <code>encoding</code> attribute in an XML
                declaration. The only values which every implementation is
                    <rfc2119>required</rfc2119> to recognize are <code>utf-8</code> and
                <code>utf-16</code>.</p>
            <p>If <code>$encoding</code> is omitted, <code>utf-8</code> encoding is assumed.</p>
            <p>The values of <code>$offset</code> and <code>$size</code>
                <rfc2119>must</rfc2119> be non-negative integers.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
            <p><code>$offset</code> is zero based.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/>is raised if <code>$offset</code> is
                negative or <code>$offset + $size</code> is larger than the size of the binary data
                of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
            <p><errorref spec="BIN40" code="unknown-encoding"/> is raised if <code>$encoding</code> is
                invalid or not supported by the implementation.</p>
            <p><errorref spec="BIN40" code="conversion-error"/> is raised if there is an error or
                malformed input during decoding the string. Additional information about the error
                may be passed through suitable error reporting mechanisms – this is
                implementation-dependant.</p>
        </fos:errors>
        <fos:examples>
            <fos:example>
                <p>Testing whether <code>$data</code> variable starts with binary content consistent
                    with a PDF file:</p>
                <eg xml:space="preserve">bin:decode-string($data, 'UTF-8', 0, 4) eq '%PDF'</eg>
                <p>The first four characters of a PDF file are <code>'%PDF'</code>.</p>
            </fos:example>
        </fos:examples>
    </fos:function>

    <fos:function name="encode-string" prefix="bin">
        <fos:signatures>
            <fos:proto name="encode-string" return-type="xs:base64Binary?">
                <fos:arg name="in" type="xs:string?"/>
                <fos:arg name="encoding" type="xs:string?" default="'utf-8'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Encodes a string into binary data using a given encoding.</p>
        </fos:summary>
        <fos:rules>
            <p>The <code>$encoding</code> argument is the name of an encoding. The values for this
                attribute follow the same rules as for the <code>encoding</code> attribute in an XML
                declaration. The only values which every implementation is
                    <rfc2119>required</rfc2119> to recognize are <code>utf-8</code> and
                <code>utf-16</code>.</p>
            <p>If <code>$encoding</code> is omitted, <code>utf-8</code> encoding is assumed.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="unknown-encoding"/> is raised if <code>$encoding</code> is
                invalid or not supported by the implementation.</p>
            <p><errorref spec="BIN40" code="conversion-error"/>is raised if there is an error or
                malformed input during encoding the string. Additional information about the error
                may be passed through suitable error reporting mechanisms – this is
                implementation-dependant.</p>
        </fos:errors>
    </fos:function>

    <fos:function name="pack-integer" prefix="bin">
        <fos:signatures>
            <fos:proto name="pack-integer" return-type="xs:base64Binary">
                <fos:arg name="in" type="xs:integer"/>
                <fos:arg name="size" type="xs:integer"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the <emph>twos-complement</emph> binary representation of an integer value
                treated as <code>$size</code> octets long. Any 'excess' high-order bits are
                discarded.</p>
        </fos:summary>
        <fos:rules>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>Specifying a <code>$size</code> of zero yields an empty binary data.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
        </fos:errors>
        <fos:notes>
            <p>If the integer being packed has a maximum precision of <code>$size</code> octets,
                then signed/unsigned versions are not necessary. If the data is considered unsigned,
                then the most significant bit of the bottom <code>$size</code> octets has a normal
                positive (<code>2^(8 *$size - 1)</code>) meaning. If it is considered to be a signed
                value, then the MSB and all the higher order, discarded bits will be '1' for a
                negative value and '0' for a positive or zero. If this function were to check the
                'sizing' of the supplied integer against the packing size, then any values of MSB
                and the discarded higher order bits other than 'all 1' or 'all 0' would constitute
                an error. <emph>This function does not perform such checking.</emph></p>
        </fos:notes>
    </fos:function>
    
    <fos:function name="unpack-integer" prefix="bin">
        <fos:signatures>
            <fos:proto name="unpack-integer" return-type="xs:integer">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="size" type="xs:integer"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns a signed integer value represented by the <code>$size</code> octets starting
                from <code>$offset</code> in the input binary representation. Necessary sign
                extension is performed (i.e. the result is negative if the high order bit is
                '1').</p>
        </fos:summary>
        <fos:rules>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The values of <code>$offset</code> and <code>$size</code>
                <rfc2119>must</rfc2119> be non-negative integers.</p>
            <p><code>$offset</code> is zero based.</p>
            <p>Specifying a <code>$size</code> of zero yields the integer <code>0</code>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset + $size</code> is larger than the size of the binary data
                of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
        <fos:notes>
            <p>For discussion on integer range see <specref ref="integer"/>.</p>
        </fos:notes>
    </fos:function>

    <fos:function name="unpack-unsigned-integer" prefix="bin">
        <fos:signatures>
            <fos:proto name="unpack-unsigned-integer" return-type="xs:integer">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="size" type="xs:integer"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns an unsigned integer value represented by the <code>$size</code> octets
                starting from <code>$offset</code> in the input binary representation.</p>
        </fos:summary>
        <fos:rules>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The values of <code>$offset</code> and <code>$size</code>
                <rfc2119>must</rfc2119> be non-negative integers.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>Specifying a <code>$size</code> of zero yields the integer <code>0</code>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset + $size</code> is larger than the size of the binary data
                of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="negative-size"/> is raised if <code>$size</code> is
                negative.</p>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
        <fos:notes>
            <p>For discussion on integer range see <specref ref="integer"/>.</p>
        </fos:notes>
    </fos:function>


    <fos:function name="unpack-double" prefix="bin">
        <fos:signatures>
            <fos:proto name="unpack-double" return-type="xs:double">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Extract <loc href="http://www.w3.org/TR/xmlschema-2/#double">double</loc> value
                stored at the particular offset in binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>Extract the <loc href="http://www.w3.org/TR/xmlschema-2/#double">double</loc> value
                stored in the 8 successive octets from the <code>$offset</code> octet of the binary
                data of <code>$in</code>.</p>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The value of <code>$offset</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>The binary representation is expected to correspond with that of the IEEE
                double-precision 64-bit floating point type <bibref ref="ieee754"/>. For more
                details see <specref ref="floating"/>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset + 8</code> (octet-length of <code>xs:double</code>) is
                larger than the size of the binary data of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
    </fos:function>
    
    <fos:function name="unpack-float" prefix="bin">
        <fos:signatures>
            <fos:proto name="unpack-float" return-type="xs:float">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)"/>
                <fos:arg name="offset" type="xs:integer"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Extract <loc href="http://www.w3.org/TR/xmlschema-2/#float">float</loc> value stored
                at the particular offset in binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>Extract the <loc href="http://www.w3.org/TR/xmlschema-2/#float">float</loc> value
                stored in the 4 successive octets from the <code>$offset</code> octet of the binary
                data of <code>$in</code>.</p>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The value of <code>$offset</code>
                <rfc2119>must</rfc2119> be a non-negative integer.</p>
            <p>The <code>$offset</code> is zero based.</p>
            <p>The binary representation is expected to correspond with that of the IEEE
                single-precision 32-bit floating point type <bibref ref="ieee754"/>. For more
                details see <specref ref="floating"/>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="index-out-of-range"/> is raised if <code>$offset</code> is
                negative or <code>$offset + 4</code> (octet-length of <code>xs:float</code>) is
                larger than the size of the binary data of <code>$in</code>.</p>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
    </fos:function>

    <fos:function name="pack-double" prefix="bin">
        <fos:signatures>
            <fos:proto name="pack-double" return-type="xs:base64Binary">
                <fos:arg name="in" type="xs:double"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the 8-octet binary representation of a <loc
                    href="http://www.w3.org/TR/xmlschema-2/#double">double</loc> value.</p>
        </fos:summary>
        <fos:rules>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The binary representation will correspond with that of the IEEE double-precision
                64-bit floating point type <bibref ref="ieee754"/>. For more details see <specref
                    ref="floating"/>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
    </fos:function>

    <fos:function name="pack-float" prefix="bin">
        <fos:signatures>
            <fos:proto name="pack-float" return-type="xs:base64Binary">
                <fos:arg name="in" type="xs:float"/>
                <fos:arg name="octet-order" type="xs:string?" default="'most-significant-first'"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the 4-octet binary representation of a <loc
                    href="http://www.w3.org/TR/xmlschema-2/#float">float</loc> value.</p>
        </fos:summary>
        <fos:rules>
            <p>Most-significant-octet-first number representation is assumed unless the
                <code>$octet-order</code> parameter is specified. Acceptable values for
                <code>$octet-order</code> are described in <specref ref="endianness"/>.</p>
            <p>The binary representation will correspond with that of the IEEE single-precision
                32-bit floating point type <bibref ref="ieee754"/>. For more details see <specref
                    ref="floating"/>.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="unknown-significance-order"/> is raised if the value
                <code>$octet-order</code> is unrecognized.</p>
        </fos:errors>
    </fos:function>


    <fos:function name="or" prefix="bin">
        <fos:signatures>
            <fos:proto name="or" return-type="xs:base64Binary?">
                <fos:arg name="a" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="b" type="(xs:hexBinary | xs:base64Binary)?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the "bitwise or" of two binary arguments.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns "bitwise or" applied between <code>$a</code> and <code>$b</code>.</p>
            <p>If either argument is the empty sequence, an empty sequence is returned.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="differing-length-arguments"/> is raised if the input
                arguments are of differing length.</p>
        </fos:errors>
    </fos:function>
    
    <fos:function name="xor" prefix="bin">
        <fos:signatures>
            <fos:proto name="xor" return-type="xs:base64Binary?">
                <fos:arg name="a" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="b" type="(xs:hexBinary | xs:base64Binary)?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the "bitwise xor" of two binary arguments.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns "bitwise exclusive or" applied between <code>$a</code> and
                <code>$b</code>.</p>
            <p>If either argument is the empty sequence, an empty sequence is returned.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="differing-length-arguments"/> is raised if the input
                arguments are of differing length.</p>
        </fos:errors>
    </fos:function>
    
    <fos:function name="and" prefix="bin">
        <fos:signatures>
            <fos:proto name="and" return-type="xs:base64Binary?">
                <fos:arg name="a" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="b" type="(xs:hexBinary | xs:base64Binary)?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the "bitwise and" of two binary arguments.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns "bitwise and" applied between <code>$a</code> and <code>$b</code>.</p>
            <p>If either argument is the empty sequence, an empty sequence is returned.</p>
        </fos:rules>
        <fos:errors>
            <p><errorref spec="BIN40" code="differing-length-arguments"/> is raised if the input
                arguments are of differing length.</p>
        </fos:errors>
    </fos:function>
    
    <fos:function name="not" prefix="bin">
        <fos:signatures>
            <fos:proto name="not" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Returns the "bitwise not" of a binary argument.</p>
        </fos:summary>
        <fos:rules>
            <p>Returns "bitwise not" applied to <code>$in</code>.</p>
            <p>If the argument is the empty sequence, an empty sequence is returned.</p>
        </fos:rules>
    </fos:function>


    <fos:function name="shift" prefix="bin">
        <fos:signatures>
            <fos:proto name="shift" return-type="xs:base64Binary?">
                <fos:arg name="in" type="(xs:hexBinary | xs:base64Binary)?"/>
                <fos:arg name="by" type="xs:integer"/>
            </fos:proto>
        </fos:signatures>
        <fos:properties>
            <fos:property>deterministic</fos:property>
            <fos:property>context-independent</fos:property>
            <fos:property>focus-independent</fos:property>
        </fos:properties>
        <fos:summary>
            <p>Shift bits in binary data.</p>
        </fos:summary>
        <fos:rules>
            <p>If <code>$by</code> is positive then bits are shifted <code>$by</code> times to the
                left.</p>
            <p>If <code>$by</code> is negative then bits are shifted <code>-$by</code> times to the
                right.</p>
            <p>If <code>$by</code> is zero, the result is identical to <code>$in</code>.</p>
            <p>If <code>|$by|</code> is greater than the bit-length of <code>$in</code> then an
                all-zeros result, of the same length as <code>$in</code>, is returned.</p>
            <p><code>|$by|</code> can be greater than 8, implying multi-byte shifts.</p>
            <p>The result always has the same size as <code>$in</code>.</p>
            <p>The shifting is logical: zeros are placed into discarded bits.</p>
            <p>If the value of <code>$in</code> is the empty sequence, the function returns an empty
                sequence.</p>
        </fos:rules>
        <fos:notes>
            <p>Bit shifting across byte boundaries implies 'big-endian' treatment, i.e. the leftmost
                (high-order) bit when shifted left becomes the low-order bit of the preceding
                byte.</p>
        </fos:notes>
        <fos:examples>
            <fos:example>
                <fos:test>
                    <fos:expression><eg>bin:shift(bin:hex("000001"), 17)</eg></fos:expression>
                    <fos:result><eg>bin:hex("020000")</eg></fos:result>
                </fos:test>
                <!--<eg xml:space="preserve">bin:shift(bin:hex("000001"), 17) → bin:hex("020000")</eg>-->
            </fos:example>
        </fos:examples>
    </fos:function>    
    

</fos:functions>