MapField.php 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. // Protocol Buffers - Google's data interchange format
  3. // Copyright 2008 Google Inc. All rights reserved.
  4. // https://developers.google.com/protocol-buffers/
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are
  8. // met:
  9. //
  10. // * Redistributions of source code must retain the above copyright
  11. // notice, this list of conditions and the following disclaimer.
  12. // * Redistributions in binary form must reproduce the above
  13. // copyright notice, this list of conditions and the following disclaimer
  14. // in the documentation and/or other materials provided with the
  15. // distribution.
  16. // * Neither the name of Google Inc. nor the names of its
  17. // contributors may be used to endorse or promote products derived from
  18. // this software without specific prior written permission.
  19. //
  20. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. /**
  32. * MapField and MapFieldIter are used by generated protocol message classes to
  33. * manipulate map fields.
  34. */
  35. namespace Google\Protobuf\Internal;
  36. /**
  37. * MapField is used by generated protocol message classes to manipulate map
  38. * fields. It can be used like native PHP array.
  39. */
  40. class MapField implements \ArrayAccess, \IteratorAggregate, \Countable
  41. {
  42. /**
  43. * @ignore
  44. */
  45. private $container;
  46. /**
  47. * @ignore
  48. */
  49. private $key_type;
  50. /**
  51. * @ignore
  52. */
  53. private $value_type;
  54. /**
  55. * @ignore
  56. */
  57. private $klass;
  58. /**
  59. * @ignore
  60. */
  61. private $legacy_klass;
  62. /**
  63. * Constructs an instance of MapField.
  64. *
  65. * @param long $key_type Type of the stored key element.
  66. * @param long $value_type Type of the stored value element.
  67. * @param string $klass Message/Enum class name of value instance
  68. * (message/enum fields only).
  69. * @ignore
  70. */
  71. public function __construct($key_type, $value_type, $klass = null)
  72. {
  73. $this->container = [];
  74. $this->key_type = $key_type;
  75. $this->value_type = $value_type;
  76. $this->klass = $klass;
  77. if ($this->value_type == GPBType::MESSAGE) {
  78. $pool = DescriptorPool::getGeneratedPool();
  79. $desc = $pool->getDescriptorByClassName($klass);
  80. if ($desc == NULL) {
  81. new $klass; // No msg class instance has been created before.
  82. $desc = $pool->getDescriptorByClassName($klass);
  83. }
  84. $this->klass = $desc->getClass();
  85. $this->legacy_klass = $desc->getLegacyClass();
  86. }
  87. }
  88. /**
  89. * @ignore
  90. */
  91. public function getKeyType()
  92. {
  93. return $this->key_type;
  94. }
  95. /**
  96. * @ignore
  97. */
  98. public function getValueType()
  99. {
  100. return $this->value_type;
  101. }
  102. /**
  103. * @ignore
  104. */
  105. public function getValueClass()
  106. {
  107. return $this->klass;
  108. }
  109. /**
  110. * @ignore
  111. */
  112. public function getLegacyValueClass()
  113. {
  114. return $this->legacy_klass;
  115. }
  116. /**
  117. * Return the element at the given key.
  118. *
  119. * This will also be called for: $ele = $arr[$key]
  120. *
  121. * @param object $key The key of the element to be fetched.
  122. * @return object The stored element at given key.
  123. * @throws \ErrorException Invalid type for index.
  124. * @throws \ErrorException Non-existing index.
  125. */
  126. public function offsetGet($key)
  127. {
  128. return $this->container[$key];
  129. }
  130. /**
  131. * Assign the element at the given key.
  132. *
  133. * This will also be called for: $arr[$key] = $value
  134. *
  135. * @param object $key The key of the element to be fetched.
  136. * @param object $value The element to be assigned.
  137. * @return void
  138. * @throws \ErrorException Invalid type for key.
  139. * @throws \ErrorException Invalid type for value.
  140. * @throws \ErrorException Non-existing key.
  141. */
  142. public function offsetSet($key, $value)
  143. {
  144. $this->checkKey($this->key_type, $key);
  145. switch ($this->value_type) {
  146. case GPBType::SFIXED32:
  147. case GPBType::SINT32:
  148. case GPBType::INT32:
  149. case GPBType::ENUM:
  150. GPBUtil::checkInt32($value);
  151. break;
  152. case GPBType::FIXED32:
  153. case GPBType::UINT32:
  154. GPBUtil::checkUint32($value);
  155. break;
  156. case GPBType::SFIXED64:
  157. case GPBType::SINT64:
  158. case GPBType::INT64:
  159. GPBUtil::checkInt64($value);
  160. break;
  161. case GPBType::FIXED64:
  162. case GPBType::UINT64:
  163. GPBUtil::checkUint64($value);
  164. break;
  165. case GPBType::FLOAT:
  166. GPBUtil::checkFloat($value);
  167. break;
  168. case GPBType::DOUBLE:
  169. GPBUtil::checkDouble($value);
  170. break;
  171. case GPBType::BOOL:
  172. GPBUtil::checkBool($value);
  173. break;
  174. case GPBType::STRING:
  175. GPBUtil::checkString($value, true);
  176. break;
  177. case GPBType::MESSAGE:
  178. if (is_null($value)) {
  179. trigger_error("Map element cannot be null.", E_USER_ERROR);
  180. }
  181. GPBUtil::checkMessage($value, $this->klass);
  182. break;
  183. default:
  184. break;
  185. }
  186. $this->container[$key] = $value;
  187. }
  188. /**
  189. * Remove the element at the given key.
  190. *
  191. * This will also be called for: unset($arr)
  192. *
  193. * @param object $key The key of the element to be removed.
  194. * @return void
  195. * @throws \ErrorException Invalid type for key.
  196. */
  197. public function offsetUnset($key)
  198. {
  199. $this->checkKey($this->key_type, $key);
  200. unset($this->container[$key]);
  201. }
  202. /**
  203. * Check the existence of the element at the given key.
  204. *
  205. * This will also be called for: isset($arr)
  206. *
  207. * @param object $key The key of the element to be removed.
  208. * @return bool True if the element at the given key exists.
  209. * @throws \ErrorException Invalid type for key.
  210. */
  211. public function offsetExists($key)
  212. {
  213. $this->checkKey($this->key_type, $key);
  214. return isset($this->container[$key]);
  215. }
  216. /**
  217. * @ignore
  218. */
  219. public function getIterator()
  220. {
  221. return new MapFieldIter($this->container, $this->key_type);
  222. }
  223. /**
  224. * Return the number of stored elements.
  225. *
  226. * This will also be called for: count($arr)
  227. *
  228. * @return integer The number of stored elements.
  229. */
  230. public function count()
  231. {
  232. return count($this->container);
  233. }
  234. /**
  235. * @ignore
  236. */
  237. private function checkKey($key_type, &$key)
  238. {
  239. switch ($key_type) {
  240. case GPBType::SFIXED32:
  241. case GPBType::SINT32:
  242. case GPBType::INT32:
  243. GPBUtil::checkInt32($key);
  244. break;
  245. case GPBType::FIXED32:
  246. case GPBType::UINT32:
  247. GPBUtil::checkUint32($key);
  248. break;
  249. case GPBType::SFIXED64:
  250. case GPBType::SINT64:
  251. case GPBType::INT64:
  252. GPBUtil::checkInt64($key);
  253. break;
  254. case GPBType::FIXED64:
  255. case GPBType::UINT64:
  256. GPBUtil::checkUint64($key);
  257. break;
  258. case GPBType::BOOL:
  259. GPBUtil::checkBool($key);
  260. break;
  261. case GPBType::STRING:
  262. GPBUtil::checkString($key, true);
  263. break;
  264. default:
  265. trigger_error(
  266. "Given type cannot be map key.",
  267. E_USER_ERROR);
  268. break;
  269. }
  270. }
  271. }