<?php
  
require('lang.base.php');
  
uses('xml.Node''util.profiling.Timer');

  class 
StrtokStrategy extends Object {
    function 
setContent($content) {
      if (
strlen($content) > ($p= (strlen(strtok(' '.$contentXML_ILLEGAL_CHARS)) - 1))) {
        return 
$p;
      }
      return -
1;
    }
  }

  class 
StrcspnStrategy extends Object {
    function 
setContent($content) {
      if (
strlen($content) > ($pstrcspn($contentXML_ILLEGAL_CHARS))) {
        return 
$p;
      }
      return -
1;
    }
  }

  class 
StrspnStrategy extends Object {
    function 
setContent($content) {
      if (
strlen($content) != ($pstrcspn($contentXML_ILLEGAL_CHARS))) {
        return 
$p;
      }
      return -
1;
    }
  }

  
define('XML_ILLEGAL_PATTERN''/['.preg_quote(XML_ILLEGAL_CHARS).']/');
  class 
RegexStrategy extends Object {
    function 
setContent($content) {
      if (
preg_match(XML_ILLEGAL_PATTERN$content$matchesPREG_OFFSET_CAPTURE)) {
        return 
$matches[0][1];
      }
      return -
1;
    }
  }

  
$tests= array(
    
'Hello'                                                                     => -1,
    
"Hello\0"                                                                   => 5,
    
'A longer string that does not contain illegal characters'                  => -1,
    
"A longer string that contains illegal characters at the end (\1)"          => 61,
    
"Medium-size with BEL (\7) in the middle of it"                             => 22,
    
"\1At the beginning"                                                        => 0,
    
"Multi\r\nline"                                                             => -1,
  );

  
// {{{ main
  
try(); {
    
$class= &XPClass::forName($argv[1].'Strategy');
  } if (catch(
'ClassNotFoundException'$e)) {
    
$e->printStackTrace();
    exit(-
1);
  }
  
  
$strategy= &$class->newInstance();
  echo 
'== '$argv[1], " ==\n";

  
$t= &new Timer();
  
$sum0.0;
  
$errorFALSE;
  foreach (
$tests as $str => $expect) {
    echo 
'- Testing "'addcslashes($str"\0..\37!@\177..\377"), '": ';
    
flush();

    if (
$expect != ($r$strategy->setContent($str))) {
      
printf(
        
"Expectancy error, expected %s but got %s\n",
        
xp::stringOf($expect),
        
xp::stringOf($r)
      );
      
$errorTRUE;
      continue;
    }

    
$t->start();  
    for (
$i0$i 10000$i++) {
      
$strategy->setContent($str);
    }
    
$t->stop();
    
    
printf("%.3f seconds\n"$t->elapsedTime());
    
$sum+= $t->elapsedTime();
  }
  
  
$error && exit("! Failed");
  
printf("* Total time: %.3f seconds\n"$sum);
?>