<?php

/*
 *    Debian Packages file parser
 *
 *    version: 0.1
 *    developed: Karoly Gossler
 *    mail: connor [at) connor (dot] hu
 *    web: blog.connor.hu
 *    licence: GPLv2 :: http://www.gnu.org/licenses/gpl.txt
 */

class packages_parser
{
    private 
$file_size 0;
    private 
$file_name null;
    private 
$fp null;

    public function 
__construct($file '')
    {
        
$this->open($file);
    }

    public function 
open($file)
    {
        if (
is_resource($this->fp))
        {
            
fclose($this->fp);
        }

        if (
$file && is_file($file) && is_readable($file))
        {
            
$this->fp fopen($file'rw');
            
$this->file_name $file;
            
$this->file_size filesize($file);
        }
    }

    private function 
parse_one($string)
    {
        
$package_data = array();

        while (
$string)
        {
            
$endline strpos($string"\n");
            if (
$endline === false)
            {
                
$line $string;
                
$string false;
            }
            else
            {
                
$line substr($stringstrlen($matches[0]), $endline);
                
$string substr($string$endline+1);
            }

            list(
$name$value) = explode(': '$line);
            switch (
$name)
            {
                case 
'Replaces':
                case 
'Depends':
                case 
'Recommends':
                case 
'Conflicts':
                    
$value explode(', '$value);
                    break;

                case 
'Description':
                    while (
substr($string01) == ' ')
                    {
                        
$endline strpos($string"\n");
                        
$line substr($stringstrlen($matches[0]), $endline);
                        
$string substr($string$endline+1);

                        
$value .= ("\n"$line);
                    }
                    break;
            }
            
$package_data[$name] = $value;
        }
        
        return 
$package_data;
    }

    private function 
get_next_string()
    {
        if (
ftell($this->fp) == $this->file_size)
        {
            return 
false;
        }

        
$content '';
        
$need_more true;
        
$read 1024;
        do
        {
            
$content .= fread($this->fp$read);

            if ((
$end_pos strpos($content"\n\n")) !== false)
            {
                
$need_more false;
            }
        }    while (
$need_more);

        
fseek($this->fp, (-1*(strlen($content)-$end_pos))+2SEEK_CUR);
        return 
substr($content0$end_pos);
    }

    public function 
get_next()
    {
        
$package $this->get_next_string();
        if (
$package !== false)
        {
            
$array $this->parse_one($package);
            return 
false;
        }
        return 
$array;
    }

    public function 
reset()
    {
        
rewind($this->fp);
    }

    public function 
fetch_into(&$array)
    {
        
$package $this->get_next_string();
        if (
$package !== false)
        {
            
$array $this->parse_one($package);
        }
        return (
$package !== false);
    }
}

?>