<!--
     Extract any (binary) data inside ...{$mark1}...{$mark2}... byte aligned.
-->
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:dp="http://www.datapower.com/extensions"
  xmlns:func="http://exslt.org/functions"
  extension-element-prefixes="dp"
>
  <dp:input-mapping  href="store:///pkcs7-convert-input.ffd" type="ffd"/>
  <dp:output-mapping href="store:///pkcs7-convert-input.ffd" type="ffd"/>

<!--
For reply to this developerWorks posting:
http://ibm.com/developerworks/forums/thread.jspa?messageID=14795386#14795386
-->
  <xsl:variable name="mark1" select="'3C5064663E'"/>    <!-- <Pdf> -->
  <xsl:variable name="mark2" select="'3C2F5064663E'"/>  <!-- </Pdf> -->


  <!--
       Determine byte aligned prefix of $srchHex in $inputHex.

       returns empty string in case of "not found" and "starts-with"
  -->
  <func:function name="func:beforeByteAligned">
    <xsl:param name="inputHex"/>
    <xsl:param name="srchHex"/>

    <xsl:choose>
      <!-- not found, return empty string -->
      <xsl:when test="not(contains($inputHex,$srchHex))" />

      <!-- hit, byte aligned, done -->
      <xsl:when 
        test="string-length(substring-before($inputHex,$srchHex)) mod 2 = 0">

        <func:result select="substring-before($inputHex,$srchHex)"/>
      </xsl:when>

      <!-- hit, but not byte aligned, search further right -->
      <xsl:otherwise>
        <xsl:variable name="len" 
          select="string-length(substring-before($inputHex,$srchHex))"/>

        <xsl:variable name="noSrchPart"
          select="substring($inputHex,1,$len+1)"/>
                
        <func:result 
          select="concat(
                    $noSrchPart,
                    func:beforeByteAligned(
                      substring-after($inputHex,$noSrchPart),
                      $srchHex
                    )
                  )"
        />
      </xsl:otherwise>
    </xsl:choose>
   </func:function>


  <xsl:template match="/">
    <!-- start of "profile all" region -->
    <dp:profile name="ExtractRegion">

      <!-- base64 encoded (binary) input -->    
      <xsl:variable name="input64"
         select="dp:binary-encode(/object/message/node())"/>

      <!-- hex encoded (binary) input -->    
      <xsl:variable name="input16"
        select="dp:radix-convert($input64,64,16)"/>

      <xsl:variable name="before16" 
        select="func:beforeByteAligned($input16,$mark1)"/>

      <!-- hex encoded result -->
      <xsl:variable name="extracted16" 
        select="func:beforeByteAligned(
                  substring-after($input16,concat($before16,$mark1)),
                  $mark2
                )"
      />

      <!-- frame as required by dp:output-mapping -->
      <object>
        <message>
          <xsl:copy-of 
            select="dp:binary-decode(dp:radix-convert($extracted16,16,64))"/>
        </message>
      </object>

    </dp:profile>
    <!-- end of "profile all" region -->
  </xsl:template>
  
</xsl:stylesheet>