<?php
/**
* Socket functions -  reading and writing for using plain text files.
* using preg_* functions    
*
* @author	Thomas Weinert	<subjective@subjective.de>
* @version	1.4.6
* @package  Netzbrett
* @modulegroup    Netzbrett_Socket
* @module   Netzbrett_Socket_Text_Fast
*/

/**
* Comparses two entries by date and id. 
*@param array $b Item 1 
*@param array $a Item 2
*@return integer comparison result (-1,0,1)
*/
function fast_date_sort($b, $a) { 
  if ($a["DATE"] != $b["DATE"]) {
    return ($a["DATE"] < $b["DATE"]) ? -1 : 1; 
  } else if ($a["FILE"] != $b["FILE"]) {
    return ($a["FILE"] < $b["FILE"]) ? -1 : 1;
  } else {
    return 0;
  }
}

/**
* Converts a string to a timestamp
* (to import old data from Netzbrett 1.2.x) 
*@param string $str string to convert 
*@return integer timestamp
*/
function fast_str2date($str) {
  preg_match("/^([0-9]{2})\.([0-9]{2})\.([0-9]{4})-([0-9]{1,2}):([0-9]{2})$/",$str,$regs);
  return mktime($regs[4], $regs[5], 0, $regs[2], $regs[1], $regs[3]);
}

/**
* Read entries list without TEXT. 
*@param string $data_dir data directory 
*@return array entries list or false
*@access public
*/
function fast_text_read_entries($data_dir="./data/") {
  $result = false;
  if ($dh = @opendir($data_dir)) {
    while ($file = readdir($dh)) {
      if (preg_match('/^[1-9]+[0-9]*$/',$file)) {
        if ($fh = fopen($data_dir.$file,"r")) {
          $lines = fread($fh,filesize($data_dir.$file));
          if (preg_match_all("/([A-Z]+)\|\|(.*)\|\|EO(F|L)/msU",$lines,$regs,PREG_SET_ORDER)) {
            unset($entry);
            if (is_array($regs)) {
              foreach($regs as $reg) {
                if ($GLOBALS["importmode"]) {
                  if ($reg[1] == "DATE") {
                    $i_date = (integer) $reg[2];
                    $i_date = (string) $i_date;
                    if ($i_date != $reg[2]) {
                      $mustchange = true;
                      $entry["DATE"] = fast_str2date($reg[2]);
                    } else {
                      $entry[$reg[1]] = $reg[2];
                    }
                  } else {
                    $entry[$reg[1]] = $reg[2];
                  }
                } else {
                  $entry[$reg[1]] = $reg[2];
                }
              }
              $entry["FILE"] = (integer) $file;  
              $entries_list[$file] = $entry;     
            }
          }
          fclose($fh);
        } 
      }
    }
    closedir($dh);
	if (gettype($entries_list)=="array") {
      uasort ($entries_list, fast_date_sort);
      $result = $entries_list;
    }
  } else {
    echo "<div align=\"center\"><h2>Can not open &quot;".$data_dir."&quot;!</h2></div>";
  }
  return $result;
}

/**
* Read one entry 
*@param string $data_dir data directory 
*@param integer $entrynr entry number 
*@return array loaded entry
*@access public
*/
function fast_text_read_entry($data_dir="./data/",$entrynr=0) {
  $entry = false;
  if (($entrynr > 0) && file_exists(chk_slash($data_dir).$entrynr)) {
    if ($fh = fopen($data_dir.$entrynr,"r")) {
      $entry = array("FILE"=>$entrynr);
      $lines = fread($fh,filesize($data_dir.$entrynr));
      if (preg_match_all("/([A-Z]+)\|\|(.*)\|\|EO(F|L)/msU",$lines,$regs,PREG_SET_ORDER)) {
        if (is_array($regs)) {
					foreach($regs as $reg) {
					  $entry[$reg[1]] = $reg[2];
				  }
				}
			}
			fclose($fh);
		}
	}
  return $entry;
}

/**
* Save/Update entry 
*@param string $data_dir data directory 
*@param boolean $new save as new entry
*@param array $entry_data entry data
*@param integer $entryno number of entry ($new==true) or of previous entry
*@return integer entry number or false
*@access public
*/
function fast_text_save_entry($data_dir="./data/",$new,$entry_data,$entryno) {

  $result = false;

  $fileno = (integer) $entryno;
  $can_write = true;
  if ($new) {
    $fileno++;      
    while (file_exists(chk_slash($data_dir).$fileno)) {$fileno++;}
  } else {
    if (! file_exists(chk_slash($data_dir).$fileno)) { $can_write = false; }
  }
  	
  if ($can_write) {
    ksort($entry_data);
    $fhandle = fopen(chk_slash($data_dir).$fileno, "w");
    if ($fhandle) {
   	  while(list($key,$val) = each($entry_data)) {
        flock($fhandle, "2");
   	    fwrite($fhandle,$key."||".$val."||EOL\r\n");
        flock($fhandle, "3");
   	  }
  	  @fclose($fhandle);
      $result = $fileno;
    }
  }
  
  return $result;	
}

/**
* Delete entry and itīs answers
*@param string $data_dir data directory 
*@param integer $entry_nr number of entry
*@return integer true or false
*@access public
*/
function fast_text_delete_entries($data_dir="./data/",$entry_nr) { 
  $entries_list = fast_text_read_entries($data_dir);
  if (gettype($entries_list) == "array") {
    $entries = optimize_data($entry_nr,$entries_list);
  }
  $result = fast_text_delete_entry($data_dir,$entry_nr,$entries_list); 
  unset ($entries_list);
  return $result;
}

/**
* Delete one entry 
*@param string $data_dir data directory 
*@param integer $entry_nr number of entry
*@param array $entries_list list of entries
*@return integer true or false
*/
function fast_text_delete_entry($data_dir="./data/",$entry_nr,$entries_list) {
  if (gettype($entries_list) == "array") {
    while (list($key,$entry) = each($entries_list)) {
	  if (($entry["PREV"] > 0) and ($entry["PREV"] == $entry_nr)) {
        fast_text_delete_entry($data_dir,$entry["FILE"],$entries_list);
	  }
    }
  } 
  if (file_exists ($data_dir.$entry_nr)) {
    $result = unlink ($data_dir.$entry_nr);
    if (! $result) {
      chdir("$data_dir");
      $result = exec("del $entry_nr");
    }
  }
  return $result; 
}

/**
* Load last entry 
*@param string $data_dir data directory 
*@return array last entry
*@access public
*/
function fast_text_read_lastentry($data_dir) {
  $entry = false;
  $entries = fast_text_read_entries($data_dir);
  if (gettype($entries) == "array") {
    usort($entries, date_sort);
    reset($entries);
    $entry = current($entries);
    $entry = fast_text_read_entry($data_dir,$entry["FILE"]);
  }
  return $entry;
}

?>