Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
/**
19
 * @package    moodlecore
20
 * @subpackage backup-xml
21
 * @copyright  2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
/**
26
 * This abstract class outputs XML contents provided by @xml_writer
27
 *
28
 * Contains the common functionalities for all the xml_output_xxx classes
29
 * and the interface for them. Mainly it's in charge of:
30
 *   - Initialize the corresponding stream/handler (file, DB connection...)
31
 *   - Finalize the stream/handler
32
 *   - Provide one common buffer for all output implementations
33
 *   - Receive XML contents from the @xml_writer and output them
34
 *   - Some basic throughtput stats
35
 *
36
 * TODO: Finish phpdocs
37
 */
38
abstract class xml_output {
39
 
40
    const DEFAULT_BUFFER_SIZE = 4096; // Use a default buffer size of 4K
41
 
42
    protected $inittime;  // Initial microtime
43
    protected $sentbytes; // Bytes sent to output
44
 
45
    protected $usebuffer; // Boolean to specify if output supports buffer (true) or no (false)
46
    protected $buffersize;// Size, in bytes, of the buffer.
47
    protected $currentbuffer;    // Buffer contents
48
    protected $currentbuffersize;// Current buffer size
49
 
50
    protected $running; // To know if output is running
51
 
52
    /** @var string|float finish microtime. */
53
    protected $finishtime;
54
 
55
    public function __construct($usebuffer = true) {
56
        $this->inittime   = microtime(true);
57
        $this->finishtime = $this->inittime;
58
        $this->sentbytes  = 0;
59
 
60
        $this->usebuffer         = $usebuffer;
61
        $this->buffersize        = $this->usebuffer ? self::DEFAULT_BUFFER_SIZE : 0;
62
 
63
        $this->running = null;
64
    }
65
 
66
    public function set_buffersize($buffersize) {
67
        if ($this->running) {
68
            throw new xml_output_exception('xml_output_already_started');
69
        }
70
        if (!$this->usebuffer) {
71
            throw new xml_output_exception('xml_output_buffer_nosupport');
72
        }
73
        // TODO: check it is integer > 0
74
        $this->buffersize = $buffersize;
75
    }
76
 
77
    public function start() {
78
        if ($this->running === true) {
79
            throw new xml_output_exception('xml_output_already_started');
80
        }
81
        if ($this->running === false) {
82
            throw new xml_output_exception('xml_output_already_stopped');
83
        }
84
        $this->inittime  = microtime(true);
85
        $this->sentbytes = 0;
86
        $this->running = true;
87
        $this->currentbuffer     = '';
88
        $this->currentbuffersize = 0;
89
        $this->init();
90
    }
91
 
92
    public function stop() {
93
        if (!$this->running) {
94
            throw new xml_output_exception('xml_output_not_started');
95
        }
96
        $this->finishtime = microtime(true);
97
        if ($this->usebuffer && $this->currentbuffersize > 0) { // Have pending contents in buffer
98
            $this->send($this->currentbuffer); // Send them
99
            $this->currentbuffer = '';
100
            $this->currentbuffersize = 0;
101
        }
102
        $this->running = false;
103
        $this->finish();
104
    }
105
 
106
    /**
107
     * Get contents from @xml_writer and buffer/output them
108
     */
109
    public function write($content) {
110
        if (!$this->running) {
111
            throw new xml_output_exception('xml_output_not_started');
112
        }
113
        $lenc = strlen($content ?? ''); // Get length in bytes.
114
        if ($lenc == 0) { // 0 length contents, nothing to do
115
            return;
116
        }
117
        // Buffer handling if available
118
        $tooutput = true; // By default, perform output
119
        if ($this->usebuffer) { // Buffer
120
            $this->currentbuffer .= $content;
121
            $this->currentbuffersize += $lenc;
122
            if ($this->currentbuffersize < $this->buffersize) {
123
                $tooutput = false; // Still within the buffer, don't output
124
            } else {
125
                $content = $this->currentbuffer; // Prepare for output
126
                $lenc = $this->currentbuffersize;
127
                $this->currentbuffer = '';
128
                $this->currentbuffersize = 0;
129
            }
130
        }
131
        // Output
132
        if ($tooutput) {
133
            $this->send($content); // Efectively send the contents
134
            $this->sentbytes += $lenc;
135
        }
136
    }
137
 
138
    public function debug_info() {
139
        if ($this->running !== false) {
140
            throw new xml_output_exception('xml_output_not_stopped');
141
        }
142
        return array('memory' => memory_get_peak_usage(true),
143
                     'time'   => $this->finishtime - $this->inittime,
144
                     'sent'   => $this->sentbytes);
145
    }
146
 
147
// Implementable API starts here
148
 
149
    abstract protected function init();
150
 
151
    abstract protected function finish();
152
 
153
    abstract protected function send($content);
154
}
155
 
156
/*
157
 * Exception class used by all the @xml_output stuff
158
 */
159
class xml_output_exception extends moodle_exception {
160
 
161
    public function __construct($errorcode, $a=NULL, $debuginfo=null) {
162
        parent::__construct($errorcode, 'error', '', $a, null, $debuginfo);
163
    }
164
}