Bibliothèque PHP de traitement de fichiers logs ADIF v2

Comme promis, je mets à disposition de la communauté ma version de la librairie de traitement (parser) de fichiers logs ADIF v2 (http://adif NULL.org/). Elle accepte les fichiers issus des logiciels les plus courants actuellement (N1MM, DXKeeper, HAM Radio Deluxe, WinLog…) et en extrait les différents champs.

Aucune vérification n’est faite sur la cohérence des informations et celle-ci dépend donc du logiciel de cahier de trafic qui a généré ces fichiers. Contrairement au parser ADIF de KJ4IWX depuis lequel j’étais parti au début, cette librairie n’a aucune limite de taille et elle peut tout à fait traiter des logs de plusieurs centaines de milliers de lignes. Tout dépend du traitement que vous faites ensuite, mais sur une machine aux performances actuelles, on peut facilement espérer insérer 2000 QSOs par minute dans une base de données. Sur QScope (http://www NULL.qscope NULL.org/) où la qualité d’origine des logs importés est très aléatoire de nombreuses vérifications sont nécessaires et la vitesse chute à environ 500 QSOs par minute.

<?php

/*

=== ADIF v2 Parser library v1.00 (2013-10-11) ===

   This Library his based on work by Jason Harris KJ4IWX but has been simplified and improvedfor better ADIF compatiblity by Yannick DEVOS XV4Y
   Copyright 2011-2013 Jason Harris KJ4IWX (Apache v2.00 License)
   Copyright 2013 Yannick DEVOS XV4Y (GNU GPL v3.00 License)
   Any commercial use is subject to authorization from the respective authors
	
	This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

---

	This PHP library is designed to work with the Jelix 1.5 PHP Framework and PHP 5.4.
	However, it can simply be called by any PHP program.
	
	Usage (with Jelix):
		$ADIFParser = jClasses::createInstance('yourmodule~ADIFParser');
		$file_handler = fopen($complete_path_to_the_file,'r');
		$ADIFParser->initialize($file_handler);

		while(($record = $ADIFParser->get_record($file_handler))!=-1) {	// Check for end of file
			if ($record!=false) {	// If line is empty we skip
				if(count($record) == 0) {
					break;
				};
				echo ($record['call']);
				echo ($record['qso_date']);
				echo ($record['mode']);
				// Do whatever you like with the ADIF fields...
			};
		};
		fclose($file_handler);

	Fore more infos find contacts at:

http://xv4y.radioclub.asia/


http://www.qscope.org/

*/

class ADIFParser
{

	var $data; //the adif data
	var $i; //the iterator
	var $headers = array();
	
	public function initialize($fhandler) //this function locates the <EOH>
	{
		$eoh=$eof=false;
		$this->data='';
		while (!$eoh && !$eof) {
			$newdata = fgets($fhandler);
			if (!$newdata) {
				$eof = true;
			} else {
				if (stripos($newdata, "<eoh>")===false) {
					$this->data .= $newdata;
				} else {
				$eoh = true;
				}
			};
		}
		if($eoh == false) //did we find the end of headers?
		{
			return 0;
		};
		
		
		//get headers
		
		$this->i = 0;
		$in_tag = false;
		$tag = "";
		$value_length = "";
		$value = "";
		$pos = strlen($this->data)-1;
				
		while($this->i < $pos)
		{
			//skip comments
			if($this->data[$this->i] == "#")
			{
				while($this->i < $pos)
				{
					if($this->data[$this->i] == "\n")
					{
						break;
					}
				
					$this->i++;
				}
			}else{
				//find the beginning of a tag
				if($this->data[$this->i] == "<")
				{
					$this->i++;
					//record the key
					while($this->data[$this->i] < $pos && $this->data[$this->i] != ':')
					{
						$tag = $tag.$this->data[$this->i];
						$this->i++;
					}
					
					$this->i++; //iterate past the :
					
					//find out how long the value is
					
					while($this->data[$this->i] < $pos && $this->data[$this->i] != '>')
					{
						$value_length = $value_length.$this->data[$this->i];
						$this->i++;
					}
					
					$this->i++; //iterate past the >
					
					$len = (int)$value_length;
					//copy the value into the buffer
					while($len > 0 && $this->i < $pos)
					{
						$value = $value.$this->data[$this->i];
						$len--;
						$this->i++;
					};

					$this->headers[strtolower(trim($tag))] = $value; //convert it to lowercase and trim it in case of \r
					//clear all of our variables
					$tag = "";
					$value_length = "";
					$value = "";
					
				}
			}
			
			$this->i++;
			
		};
		return 1;
	}
	
	//the following function does the processing of the array into its key and value pairs
	public function record_to_array(&$record)
	{
		$return = array();
		for($a = 0; $a < strlen($record); $a++)
		{
			if($record[$a] == '<') //find the start of the tag
			{
				$tag_name = "";
				$value = "";
				$len_str = "";
				$len = 0;
				$a++; //go past the <
				while($record[$a] != ':') //get the tag
				{
					$tag_name = $tag_name.$record[$a]; //append this char to the tag name
					$a++;
				};
				$a++; //iterate past the colon
				while($record[$a] != '>' && $record[$a] != ':')
				{
					$len_str = $len_str.$record[$a];
					$a++;
				};
				if($record[$a] == ':')
				{
					while($record[$a] != '>')
					{
						$a++;
					};
				};
				$len = (int)$len_str;
				while($len > 0)
				{
					$a++;
					$value = $value.$record[$a];
					$len--;
				};
				$return[strtolower($tag_name)] = $value;
			};
			//skip comments
			if($record[$a] == "#")
			{
				while($a < strlen($record))
				{
					if($record[$a] == "\n")
					{
						break;
					}
					$a++;
				}
			}
		};
		return $return;
	}
	
	
	//finds the next record in the file
	public function get_record($fhandle)
	{
		$record ='';
		$out_condition = false;
		while (!$out_condition) {
			$newdata = fgets($fhandle);
			if ($newdata===false) {
				$out_condition = true;
				return -1;	// This is the end of file
			} else {
				$end = stripos($newdata , "<eor>");
				if($end !== false) { //we got a full line
					$record .= substr($newdata, 0, $end);
					$out_condition = true;
					return $this->record_to_array($record); //process and return output
				} else {
				$record .= $newdata;	// The line is not complete and we need to fetch a new string
				}
			}
		}
 	}
	
	public function get_header($key)
	{
		if(array_key_exists(strtolower($key), $this->headers))
		{
			return $this->headers[strtolower($key)];
		}else{
			return NULL;
		}
	}
	
}
?>

Autres articles sur le même sujet:

Share

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *