|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00003 // This file is part of Moodle - http://moodle.org/ 00004 // 00005 // Moodle is free software: you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation, either version 3 of the License, or 00008 // (at your option) any later version. 00009 // 00010 // Moodle is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 // GNU General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License 00016 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00017 00038 abstract class xml_output { 00039 00040 const DEFAULT_BUFFER_SIZE = 4096; // Use a default buffer size of 4K 00041 00042 protected $inittime; // Initial microtime 00043 protected $sentbytes; // Bytes sent to output 00044 00045 protected $usebuffer; // Boolean to specify if output supports buffer (true) or no (false) 00046 protected $buffersize;// Size, in bytes, of the buffer. 00047 protected $currentbuffer; // Buffer contents 00048 protected $currentbuffersize;// Current buffer size 00049 00050 protected $running; // To know if output is running 00051 00052 public function __construct($usebuffer = true) { 00053 $this->inittime = microtime(true); 00054 $this->finishtime = $this->inittime;; 00055 $this->sentbytes = 0; 00056 00057 $this->usebuffer = $usebuffer; 00058 $this->buffersize = $this->usebuffer ? self::DEFAULT_BUFFER_SIZE : 0; 00059 00060 $this->running = null; 00061 } 00062 00063 public function set_buffersize($buffersize) { 00064 if ($this->running) { 00065 throw new xml_output_exception('xml_output_already_started'); 00066 } 00067 if (!$this->usebuffer) { 00068 throw new xml_output_exception('xml_output_buffer_nosupport'); 00069 } 00070 // TODO: check it is integer > 0 00071 $this->buffersize = $buffersize; 00072 } 00073 00074 public function start() { 00075 if ($this->running === true) { 00076 throw new xml_output_exception('xml_output_already_started'); 00077 } 00078 if ($this->running === false) { 00079 throw new xml_output_exception('xml_output_already_stopped'); 00080 } 00081 $this->inittime = microtime(true); 00082 $this->sentbytes = 0; 00083 $this->running = true; 00084 $this->currentbuffer = ''; 00085 $this->currentbuffersize = 0; 00086 $this->init(); 00087 } 00088 00089 public function stop() { 00090 if (!$this->running) { 00091 throw new xml_output_exception('xml_output_not_started'); 00092 } 00093 $this->finishtime = microtime(true); 00094 if ($this->usebuffer && $this->currentbuffersize > 0) { // Have pending contents in buffer 00095 $this->send($this->currentbuffer); // Send them 00096 $this->currentbuffer = ''; 00097 $this->currentbuffersize = 0; 00098 } 00099 $this->running = false; 00100 $this->finish(); 00101 } 00102 00106 public function write($content) { 00107 if (!$this->running) { 00108 throw new xml_output_exception('xml_output_not_started'); 00109 } 00110 $lenc = strlen($content); // Get length in bytes 00111 if ($lenc == 0) { // 0 length contents, nothing to do 00112 return; 00113 } 00114 // Buffer handling if available 00115 $tooutput = true; // By default, perform output 00116 if ($this->usebuffer) { // Buffer 00117 $this->currentbuffer .= $content; 00118 $this->currentbuffersize += $lenc; 00119 if ($this->currentbuffersize < $this->buffersize) { 00120 $tooutput = false; // Still within the buffer, don't output 00121 } else { 00122 $content = $this->currentbuffer; // Prepare for output 00123 $lenc = $this->currentbuffersize; 00124 $this->currentbuffer = ''; 00125 $this->currentbuffersize = 0; 00126 } 00127 } 00128 // Output 00129 if ($tooutput) { 00130 $this->send($content); // Efectively send the contents 00131 $this->sentbytes += $lenc; 00132 } 00133 } 00134 00135 public function debug_info() { 00136 if ($this->running !== false) { 00137 throw new xml_output_exception('xml_output_not_stopped'); 00138 } 00139 return array('memory' => memory_get_peak_usage(true), 00140 'time' => $this->finishtime - $this->inittime, 00141 'sent' => $this->sentbytes); 00142 } 00143 00144 // Implementable API starts here 00145 00146 abstract protected function init(); 00147 00148 abstract protected function finish(); 00149 00150 abstract protected function send($content); 00151 } 00152 00153 /* 00154 * Exception class used by all the @xml_output stuff 00155 */ 00156 class xml_output_exception extends moodle_exception { 00157 00158 public function __construct($errorcode, $a=NULL, $debuginfo=null) { 00159 parent::__construct($errorcode, 'error', '', $a, null, $debuginfo); 00160 } 00161 }