Microsoft_WindowsAzure_Storage
[ class tree: Microsoft_WindowsAzure_Storage ] [ index: Microsoft_WindowsAzure_Storage ] [ all elements ]

Source for file Stream.php

Documentation is available at Stream.php

  1. <?php
  2. /**
  3.  * Copyright (c) 2009, RealDolmen
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions are met:
  8.  *     * Redistributions of source code must retain the above copyright
  9.  *       notice, this list of conditions and the following disclaimer.
  10.  *     * Redistributions in binary form must reproduce the above copyright
  11.  *       notice, this list of conditions and the following disclaimer in the
  12.  *       documentation and/or other materials provided with the distribution.
  13.  *     * Neither the name of RealDolmen nor the
  14.  *       names of its contributors may be used to endorse or promote products
  15.  *       derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
  18.  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20.  * DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
  21.  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22.  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  *
  28.  * @category   Microsoft
  29.  * @package    Microsoft_WindowsAzure_Storage
  30.  * @subpackage Blob
  31.  * @copyright  Copyright (c) 2009, RealDolmen (http://www.realdolmen.com)
  32.  * @license    http://todo     name_todo
  33.  * @version    $Id: Blob.php 24511 2009-07-28 09:17:56Z unknown $
  34.  */
  35.  
  36. /**
  37.  * @see Microsoft_WindowsAzure_Storage_Blob
  38.  */
  39. require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
  40.  
  41. /**
  42.  * @see Microsoft_WindowsAzure_Exception
  43.  */
  44. require_once 'Microsoft/WindowsAzure/Exception.php';
  45.  
  46.  
  47. /**
  48.  * @category   Microsoft
  49.  * @package    Microsoft_WindowsAzure_Storage
  50.  * @subpackage Blob
  51.  * @copyright  Copyright (c) 2009, RealDolmen (http://www.realdolmen.com)
  52.  * @license    http://phpazure.codeplex.com/license
  53.  */
  54. {
  55.     /**
  56.      * Current file name
  57.      * 
  58.      * @var string 
  59.      */
  60.     private $_fileName null;
  61.     
  62.     /**
  63.      * Temporary file name
  64.      * 
  65.      * @var string 
  66.      */
  67.     private $_temporaryFileName null;
  68.     
  69.     /**
  70.      * Temporary file handle
  71.      * 
  72.      * @var resource 
  73.      */
  74.     private $_temporaryFileHandle null;
  75.     
  76.     /**
  77.      * Blob storage client
  78.      * 
  79.      * @var Microsoft_WindowsAzure_Storage_Blob 
  80.      */
  81.     private $_storageClient null;
  82.     
  83.     /**
  84.      * Write mode?
  85.      * 
  86.      * @var boolean 
  87.      */
  88.     private $_writeMode false;
  89.     
  90.     /**
  91.      * List of blobs
  92.      * 
  93.      * @var array 
  94.      */
  95.     private $_blobs null;
  96.     
  97.     /**
  98.      * Retrieve storage client for this stream type
  99.      * 
  100.      * @param string $path 
  101.      * @return Microsoft_WindowsAzure_Storage_Blob 
  102.      */
  103.     protected function getStorageClient($path '')
  104.     {
  105.         if (is_null($this->_storageClient))
  106.         {
  107.             $url explode(':'$path);
  108.             if (!$url)
  109.             {
  110.                 throw new Microsoft_WindowsAzure_Exception('Could not parse path "' $path '".');
  111.             }
  112.  
  113.             $this->_storageClient Microsoft_WindowsAzure_Storage_Blob::getWrapperClient($url[0]);
  114.             if (!$this->_storageClient)
  115.             {
  116.                 throw new Microsoft_WindowsAzure_Exception('No storage client registered for stream type "' $url[0'://".');
  117.             }
  118.         }
  119.         
  120.         return $this->_storageClient;
  121.     }
  122.     
  123.     /**
  124.      * Extract container name
  125.      *
  126.      * @param string $path 
  127.      * @return string 
  128.      */
  129.     protected function getContainerName($path)
  130.     {
  131.         $url parse_url($path);
  132.         if ($url['host']{
  133.             return $url['host'];
  134.         }
  135.  
  136.         return '';
  137.     }
  138.     
  139.     /**
  140.      * Extract file name
  141.      *
  142.      * @param string $path 
  143.      * @return string 
  144.      */
  145.     protected function getFileName($path)
  146.     {
  147.         $url parse_url($path);
  148.         if ($url['host']{
  149.             $fileName = isset($url['path']$url['path'$url['host'];
  150.             if (strpos($fileName'/'=== 0)
  151.                 $fileName substr($fileName1);
  152.             return $fileName;
  153.         }
  154.  
  155.         return '';
  156.     }
  157.        
  158.     /**
  159.      * Open the stream
  160.      *
  161.      * @param  string  $path 
  162.      * @param  string  $mode 
  163.      * @param  integer $options 
  164.      * @param  string  $opened_path 
  165.      * @return boolean 
  166.      */
  167.     public function stream_open($path$mode$options$opened_path)
  168.     {
  169.         $this->_fileName $path;
  170.         $this->_temporaryFileName tempnam(sys_get_temp_dir()'azure');
  171.         
  172.         // Check the file can be opened
  173.         $fh @fopen($this->_temporaryFileName$mode);
  174.         if ($fh === false)
  175.             return false;
  176.         fclose($fh);
  177.         
  178.         // Write mode?
  179.         if (strpbrk($mode'wax+'))
  180.             $this->_writeMode true;
  181.         else
  182.             $this->_writeMode false;
  183.         
  184.         // If read/append, fetch the file
  185.         if (!$this->_writeMode || strpbrk($mode'ra+'))
  186.         {
  187.             $this->getStorageClient($this->_fileName)->getBlob(
  188.                 $this->getContainerName($this->_fileName),
  189.                 $this->getFileName($this->_fileName),
  190.                 $this->_temporaryFileName
  191.             );
  192.         }
  193.         
  194.         // Open temporary file handle
  195.         $this->_temporaryFileHandle fopen($this->_temporaryFileName$mode);
  196.         
  197.         // Ok!
  198.         return true;
  199.     }
  200.  
  201.     /**
  202.      * Close the stream
  203.      *
  204.      * @return void 
  205.      */
  206.     public function stream_close()
  207.     {
  208.         @fclose($this->_temporaryFileHandle);
  209.         
  210.         // Upload the file?
  211.         if ($this->_writeMode)
  212.         {
  213.             // Make sure the container exists
  214.             $containerExists $this->getStorageClient($this->_fileName)->containerExists(
  215.                 $this->getContainerName($this->_fileName)
  216.             );
  217.             if (!$containerExists)
  218.             {
  219.                 $this->getStorageClient($this->_fileName)->createContainer(
  220.                     $this->getContainerName($this->_fileName)
  221.                 );
  222.             }
  223.             
  224.             // Upload the file
  225.             try
  226.             {
  227.                 $this->getStorageClient($this->_fileName)->putBlob(
  228.                     $this->getContainerName($this->_fileName),
  229.                     $this->getFileName($this->_fileName),
  230.                     $this->_temporaryFileName
  231.                 );
  232.             }
  233.             catch (Microsoft_WindowsAzure_Exception $ex)
  234.             {
  235.                 @unlink($this->_temporaryFileName);
  236.                 unset($this->_storageClient);
  237.                 
  238.                 throw $ex;
  239.             }
  240.         }
  241.         
  242.         @unlink($this->_temporaryFileName);
  243.         unset($this->_storageClient);
  244.     }
  245.  
  246.     /**
  247.      * Read from the stream
  248.      *
  249.      * @param  integer $count 
  250.      * @return string 
  251.      */
  252.     public function stream_read($count)
  253.     {
  254.         if (!$this->_temporaryFileHandle)
  255.         {
  256.             return false;
  257.         }
  258.  
  259.         return fread($this->_temporaryFileHandle$count);
  260.     }
  261.  
  262.     /**
  263.      * Write to the stream
  264.      *
  265.      * @param  string $data 
  266.      * @return integer 
  267.      */
  268.     public function stream_write($data)
  269.     {
  270.         if (!$this->_temporaryFileHandle)
  271.         {
  272.             return 0;
  273.         }
  274.         
  275.         $len strlen($data);
  276.         fwrite($this->_temporaryFileHandle$data$len);
  277.         return $len;
  278.     }
  279.  
  280.     /**
  281.      * End of the stream?
  282.      *
  283.      * @return boolean 
  284.      */
  285.     public function stream_eof()
  286.     {
  287.         if (!$this->_temporaryFileHandle)
  288.         {
  289.             return true;
  290.         }
  291.  
  292.         return feof($this->_temporaryFileHandle);
  293.     }
  294.  
  295.     /**
  296.      * What is the current read/write position of the stream?
  297.      *
  298.      * @return integer 
  299.      */
  300.     public function stream_tell()
  301.     {
  302.         return ftell($this->_temporaryFileHandle);
  303.     }
  304.  
  305.     /**
  306.      * Update the read/write position of the stream
  307.      *
  308.      * @param  integer $offset 
  309.      * @param  integer $whence 
  310.      * @return boolean 
  311.      */
  312.     public function stream_seek($offset$whence)
  313.     {
  314.         if (!$this->_temporaryFileHandle)
  315.         {
  316.             return false;
  317.         }
  318.         
  319.         return (fseek($this->_temporaryFileHandle$offset$whence=== 0);
  320.     }
  321.  
  322.     /**
  323.      * Flush current cached stream data to storage
  324.      *
  325.      * @return boolean 
  326.      */
  327.     public function stream_flush()
  328.     {
  329.         $result fflush($this->_temporaryFileHandle);
  330.         
  331.          // Upload the file?
  332.         if ($this->_writeMode)
  333.         {
  334.             // Make sure the container exists
  335.             $containerExists $this->getStorageClient($this->_fileName)->containerExists(
  336.                 $this->getContainerName($this->_fileName)
  337.             );
  338.             if (!$containerExists)
  339.             {
  340.                 $this->getStorageClient($this->_fileName)->createContainer(
  341.                     $this->getContainerName($this->_fileName)
  342.                 );
  343.             }
  344.             
  345.             // Upload the file
  346.             try
  347.             {
  348.                 $this->getStorageClient($this->_fileName)->putBlob(
  349.                     $this->getContainerName($this->_fileName),
  350.                     $this->getFileName($this->_fileName),
  351.                     $this->_temporaryFileName
  352.                 );
  353.             }
  354.             catch (Microsoft_WindowsAzure_Exception $ex)
  355.             {
  356.                 @unlink($this->_temporaryFileName);
  357.                 unset($this->_storageClient);
  358.                 
  359.                 throw $ex;
  360.             }
  361.         }
  362.         
  363.         return $result;
  364.     }
  365.  
  366.     /**
  367.      * Returns data array of stream variables
  368.      *
  369.      * @return array 
  370.      */
  371.     public function stream_stat()
  372.     {
  373.         if (!$this->_temporaryFileHandle)
  374.         {
  375.             return false;
  376.         }
  377.  
  378.         $stat array();
  379.         $stat['dev'0;
  380.         $stat['ino'0;
  381.         $stat['mode'0;
  382.         $stat['nlink'0;
  383.         $stat['uid'0;
  384.         $stat['gid'0;
  385.         $stat['rdev'0;
  386.         $stat['size'0;
  387.         $stat['atime'0;
  388.         $stat['mtime'0;
  389.         $stat['ctime'0;
  390.         $stat['blksize'0;
  391.         $stat['blocks'0;
  392.  
  393.         $info null;
  394.         try {
  395.             $info $this->getStorageClient($this->_fileName)->getBlobInstance(
  396.                         $this->getContainerName($this->_fileName),
  397.                         $this->getFileName($this->_fileName)
  398.                     );
  399.         }
  400.         catch (Microsoft_WindowsAzure_Exception $ex)
  401.         {
  402.             // Unexisting file...
  403.         }
  404.         if (!is_null($info))
  405.         {
  406.             $stat['size']  $info->Size;
  407.             $stat['atime'time();
  408.         }     
  409.         
  410.         return $stat;
  411.     }
  412.  
  413.     /**
  414.      * Attempt to delete the item
  415.      *
  416.      * @param  string $path 
  417.      * @return boolean 
  418.      */
  419.     public function unlink($path)
  420.     {
  421.         $this->getStorageClient($path)->deleteBlob(
  422.             $this->getContainerName($path),
  423.             $this->getFileName($path)
  424.         );
  425.     }
  426.  
  427.     /**
  428.      * Attempt to rename the item
  429.      *
  430.      * @param  string  $path_from 
  431.      * @param  string  $path_to 
  432.      * @return boolean False
  433.      */
  434.     public function rename($path_from$path_to)
  435.     {
  436.         if ($this->getContainerName($path_from!= $this->getContainerName($path_to))
  437.             throw new Microsoft_WindowsAzure_Exception('Container name can not be changed.');
  438.         
  439.         if ($this->getFileName($path_from== $this->getContainerName($path_to))
  440.             return true;
  441.             
  442.         $this->getStorageClient($path_from)->copyBlob(
  443.             $this->getContainerName($path_from),
  444.             $this->getFileName($path_from),
  445.             $this->getContainerName($path_to),
  446.             $this->getFileName($path_to)
  447.         );
  448.         $this->getStorageClient($path_from)->deleteBlob(
  449.             $this->getContainerName($path_from),
  450.             $this->getFileName($path_from)
  451.         );
  452.         return true;
  453.     }
  454.     
  455.     /**
  456.      * Return array of URL variables
  457.      *
  458.      * @param  string $path 
  459.      * @param  integer $flags 
  460.      * @return array 
  461.      */
  462.     public function url_stat($path$flags)
  463.     {
  464.         $stat array();
  465.         $stat['dev'0;
  466.         $stat['ino'0;
  467.         $stat['mode'0;
  468.         $stat['nlink'0;
  469.         $stat['uid'0;
  470.         $stat['gid'0;
  471.         $stat['rdev'0;
  472.         $stat['size'0;
  473.         $stat['atime'0;
  474.         $stat['mtime'0;
  475.         $stat['ctime'0;
  476.         $stat['blksize'0;
  477.         $stat['blocks'0;
  478.  
  479.         $info null;
  480.         try {
  481.             $info $this->getStorageClient($path)->getBlobInstance(
  482.                         $this->getContainerName($path),
  483.                         $this->getFileName($path)
  484.                     );
  485.         }
  486.         catch (Microsoft_WindowsAzure_Exception $ex)
  487.         {
  488.             // Unexisting file...
  489.         }
  490.         if (!is_null($info))
  491.         {
  492.             $stat['size']  $info->Size;
  493.             $stat['atime'time();
  494.         
  495.  
  496.         return $stat;
  497.     }
  498.  
  499.     /**
  500.      * Create a new directory
  501.      *
  502.      * @param  string  $path 
  503.      * @param  integer $mode 
  504.      * @param  integer $options 
  505.      * @return boolean 
  506.      */
  507.     public function mkdir($path$mode$options)
  508.     {
  509.         if ($this->getContainerName($path== $this->getFileName($path))
  510.         {
  511.             // Create container
  512.             try
  513.             {
  514.                 $this->getStorageClient($path)->createContainer(
  515.                     $this->getContainerName($path)
  516.                 );
  517.             }
  518.             catch (Microsoft_WindowsAzure_Exception $ex)
  519.             {
  520.                 return false;
  521.             }
  522.         }
  523.         else
  524.         {
  525.             throw new Microsoft_WindowsAzure_Exception('mkdir() with multiple levels is not supported on Windows Azure Blob Storage.');
  526.         }
  527.     }
  528.  
  529.     /**
  530.      * Remove a directory
  531.      *
  532.      * @param  string  $path 
  533.      * @param  integer $options 
  534.      * @return boolean 
  535.      */
  536.     public function rmdir($path$options)
  537.     {
  538.         if ($this->getContainerName($path== $this->getFileName($path))
  539.         {
  540.             // Delete container
  541.             try
  542.             {
  543.                 $this->getStorageClient($path)->deleteContainer(
  544.                     $this->getContainerName($path)
  545.                 );
  546.             }
  547.             catch (Microsoft_WindowsAzure_Exception $ex)
  548.             {
  549.                 return false;
  550.             }
  551.         }
  552.         else
  553.         {
  554.             throw new Microsoft_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.');
  555.         }
  556.     }
  557.  
  558.     /**
  559.      * Attempt to open a directory
  560.      *
  561.      * @param  string $path 
  562.      * @param  integer $options 
  563.      * @return boolean 
  564.      */
  565.     public function dir_opendir($path$options)
  566.     {
  567.         $this->_blobs $this->getStorageClient($path)->listBlobs(
  568.             $this->getContainerName($path)
  569.         );
  570.         return is_array($this->_blobs);
  571.     }
  572.  
  573.     /**
  574.      * Return the next filename in the directory
  575.      *
  576.      * @return string 
  577.      */
  578.     public function dir_readdir()
  579.     {
  580.         $object current($this->_blobs);
  581.         if ($object !== false{
  582.             next($this->_blobs);
  583.             return $object->Name;
  584.         }
  585.         return false;
  586.     }
  587.  
  588.     /**
  589.      * Reset the directory pointer
  590.      *
  591.      * @return boolean True
  592.      */
  593.     public function dir_rewinddir()
  594.     {
  595.         reset($this->_blobs);
  596.         return true;
  597.     }
  598.  
  599.     /**
  600.      * Close a directory
  601.      *
  602.      * @return boolean True
  603.      */
  604.     public function dir_closedir()
  605.     {
  606.         $this->_blobs null;
  607.         return true;
  608.     }
  609. }

Documentation generated on Thu, 26 Nov 2009 08:05:27 +0100 by phpDocumentor 1.4.3