<?php
/* This class is part of the XP framework
 * 
 * $Id$
 */
 
  
uses('io.cca.Archive''io.File');

  
/**
   * Wrapper for using uses() with cca-Archives.
   *
   * Note: This is NOT a general purpose wrapper, it supports reading
   * of files only!
   *
   * @see      php://stream
   * @purpose  Stream wrapper
   */
  
class ArchiveWrapper extends Object {
    var
      
$buffer     '',
      
$offset     0;

    
/**
     * Callback for when a stream is opened
     *
     * @access  public
     * @param   string path
     * @param   string mode
     * @param   int options
     * @param   &string open
     * @return  bool success
     */
    
function stream_open($path$mode$options, &$open) {
      static 
$archives= array();

      
$urlparse_url($path);
      
$cca$url['host'];
      if (!isset(
$archives[$cca])) {
        
$archives[$cca]= &new Archive(new File($cca));
        
$archives[$cca]->open(ARCHIVE_READ);
      }

      
$opensubstr($url['path'], 1);
      if (!
$archives[$cca]->contains($open)) return FALSE;

      
$this->buffer$archives[$cca]->extract($open);
      return 
TRUE;
    }
    
    
/**
     * Callback for reading from stream
     *
     * @access  public
     * @param   int count number of bytes to read.
     * @param   string chunk
     */
    
function stream_read($count) {
      
$chunksubstr($this->buffer$this->offset$count);
      
$this->offset+= $count;
      return 
$chunk;
    }
    
    
/**
     * Callback for stream end-of-file marker
     *
     * @access  public
     * @return  bool TRUE when end has been reached
     */
    
function stream_eof() {
      return 
$this->offset strlen($this->buffer);
    }
    
    
/**
     * Static initializer
     *
     * @model   static
     * @access  public
     */
    
function __static() {
      
stream_wrapper_register('cca+xp'__CLASS__);
    }
  } 
?>