1<?php
2
3/*
4 * This file is part of SwiftMailer.
5 * (c) 2004-2009 Chris Corbyn
6 *
7 * For the full copyright and license information, please view the LICENSE
8 * file that was distributed with this source code.
9 */
10
11//@require 'Swift/KeyCache.php';
12//@require 'Swift/KeyCacheInputStream.php';
13//@require 'Swift/InputByteStream.php';
14//@require 'Swift/OutputByteStrean.php';
15//@require 'Swift/SwiftException.php';
16
17/**
18 * A basic KeyCache backed by an array.
19 * @package Swift
20 * @subpackage KeyCache
21 * @author Chris Corbyn
22 */
23class Swift_KeyCache_ArrayKeyCache implements Swift_KeyCache
24{
25
26  /**
27   * Cache contents.
28   * @var array
29   * @access private
30   */
31  private $_contents = array();
32
33  /**
34   * An InputStream for cloning.
35   * @var Swift_KeyCache_KeyCacheInputStream
36   * @access private
37   */
38  private $_stream;
39
40  /**
41   * Create a new ArrayKeyCache with the given $stream for cloning to make
42   * InputByteStreams.
43   * @param Swift_KeyCache_KeyCacheInputStream $stream
44   */
45  public function __construct(Swift_KeyCache_KeyCacheInputStream $stream)
46  {
47    $this->_stream = $stream;
48  }
49
50  /**
51   * Set a string into the cache under $itemKey for the namespace $nsKey.
52   * @param string $nsKey
53   * @param string $itemKey
54   * @param string $string
55   * @param int $mode
56   * @see MODE_WRITE, MODE_APPEND
57   */
58  public function setString($nsKey, $itemKey, $string, $mode)
59  {
60    $this->_prepareCache($nsKey);
61    switch ($mode)
62    {
63      case self::MODE_WRITE:
64        $this->_contents[$nsKey][$itemKey] = $string;
65        break;
66      case self::MODE_APPEND:
67        if (!$this->hasKey($nsKey, $itemKey))
68        {
69          $this->_contents[$nsKey][$itemKey] = '';
70        }
71        $this->_contents[$nsKey][$itemKey] .= $string;
72        break;
73      default:
74        throw new Swift_SwiftException(
75          'Invalid mode [' . $mode . '] used to set nsKey='.
76          $nsKey . ', itemKey=' . $itemKey
77          );
78    }
79  }
80
81  /**
82   * Set a ByteStream into the cache under $itemKey for the namespace $nsKey.
83   * @param string $nsKey
84   * @param string $itemKey
85   * @param Swift_OutputByteStream $os
86   * @param int $mode
87   * @see MODE_WRITE, MODE_APPEND
88   */
89  public function importFromByteStream($nsKey, $itemKey, Swift_OutputByteStream $os,
90    $mode)
91  {
92    $this->_prepareCache($nsKey);
93    switch ($mode)
94    {
95      case self::MODE_WRITE:
96        $this->clearKey($nsKey, $itemKey);
97      case self::MODE_APPEND:
98        if (!$this->hasKey($nsKey, $itemKey))
99        {
100          $this->_contents[$nsKey][$itemKey] = '';
101        }
102        while (false !== $bytes = $os->read(8192))
103        {
104          $this->_contents[$nsKey][$itemKey] .= $bytes;
105        }
106        break;
107      default:
108        throw new Swift_SwiftException(
109          'Invalid mode [' . $mode . '] used to set nsKey='.
110          $nsKey . ', itemKey=' . $itemKey
111          );
112    }
113  }
114
115  /**
116   * Provides a ByteStream which when written to, writes data to $itemKey.
117   * NOTE: The stream will always write in append mode.
118   * @param string $nsKey
119   * @param string $itemKey
120   * @return Swift_InputByteStream
121   */
122  public function getInputByteStream($nsKey, $itemKey,
123    Swift_InputByteStream $writeThrough = null)
124  {
125    $is = clone $this->_stream;
126    $is->setKeyCache($this);
127    $is->setNsKey($nsKey);
128    $is->setItemKey($itemKey);
129    if (isset($writeThrough))
130    {
131      $is->setWriteThroughStream($writeThrough);
132    }
133    return $is;
134  }
135
136  /**
137   * Get data back out of the cache as a string.
138   * @param string $nsKey
139   * @param string $itemKey
140   * @return string
141   */
142  public function getString($nsKey, $itemKey)
143  {
144    $this->_prepareCache($nsKey);
145    if ($this->hasKey($nsKey, $itemKey))
146    {
147      return $this->_contents[$nsKey][$itemKey];
148    }
149  }
150
151  /**
152   * Get data back out of the cache as a ByteStream.
153   * @param string $nsKey
154   * @param string $itemKey
155   * @param Swift_InputByteStream $is to write the data to
156   */
157  public function exportToByteStream($nsKey, $itemKey, Swift_InputByteStream $is)
158  {
159    $this->_prepareCache($nsKey);
160    $is->write($this->getString($nsKey, $itemKey));
161  }
162
163  /**
164   * Check if the given $itemKey exists in the namespace $nsKey.
165   * @param string $nsKey
166   * @param string $itemKey
167   * @return boolean
168   */
169  public function hasKey($nsKey, $itemKey)
170  {
171    $this->_prepareCache($nsKey);
172    return array_key_exists($itemKey, $this->_contents[$nsKey]);
173  }
174
175  /**
176   * Clear data for $itemKey in the namespace $nsKey if it exists.
177   * @param string $nsKey
178   * @param string $itemKey
179   */
180  public function clearKey($nsKey, $itemKey)
181  {
182    unset($this->_contents[$nsKey][$itemKey]);
183  }
184
185  /**
186   * Clear all data in the namespace $nsKey if it exists.
187   * @param string $nsKey
188   */
189  public function clearAll($nsKey)
190  {
191    unset($this->_contents[$nsKey]);
192  }
193
194  // -- Private methods
195
196  /**
197   * Initialize the namespace of $nsKey if needed.
198   * @param string $nsKey
199   * @access private
200   */
201  private function _prepareCache($nsKey)
202  {
203    if (!array_key_exists($nsKey, $this->_contents))
204    {
205      $this->_contents[$nsKey] = array();
206    }
207  }
208
209}
210