PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/runtime/base/ini-setting.h

https://github.com/tstarling/hiphop-php
C Header | 255 lines | 185 code | 23 blank | 47 comment | 8 complexity | be010702fed61baf27d331fcb070928e MD5 | raw file
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010-2014 Facebook, Inc. (http://www.facebook.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. */
  16. #ifndef incl_HPHP_INI_SETTING_H_
  17. #define incl_HPHP_INI_SETTING_H_
  18. #include "hphp/runtime/base/type-variant.h"
  19. #include "folly/dynamic.h"
  20. #include <cstdint>
  21. #include <functional>
  22. #include <set>
  23. #include <string>
  24. namespace HPHP {
  25. ///////////////////////////////////////////////////////////////////////////////
  26. class Array;
  27. class Extension;
  28. class String;
  29. bool ini_on_update(const folly::dynamic& value, bool& p);
  30. bool ini_on_update(const folly::dynamic& value, double& p);
  31. bool ini_on_update(const folly::dynamic& value, int16_t& p);
  32. bool ini_on_update(const folly::dynamic& value, int32_t& p);
  33. bool ini_on_update(const folly::dynamic& value, int64_t& p);
  34. bool ini_on_update(const folly::dynamic& value, uint16_t& p);
  35. bool ini_on_update(const folly::dynamic& value, uint32_t& p);
  36. bool ini_on_update(const folly::dynamic& value, uint64_t& p);
  37. bool ini_on_update(const folly::dynamic& value, std::string& p);
  38. bool ini_on_update(const folly::dynamic& value, String& p);
  39. bool ini_on_update(const folly::dynamic& value, Array& p);
  40. bool ini_on_update(const folly::dynamic& value, std::set<std::string>& p);
  41. folly::dynamic ini_get(bool& p);
  42. folly::dynamic ini_get(double& p);
  43. folly::dynamic ini_get(int16_t& p);
  44. folly::dynamic ini_get(int32_t& p);
  45. folly::dynamic ini_get(int64_t& p);
  46. folly::dynamic ini_get(uint16_t& p);
  47. folly::dynamic ini_get(uint32_t& p);
  48. folly::dynamic ini_get(uint64_t& p);
  49. folly::dynamic ini_get(std::string& p);
  50. folly::dynamic ini_get(String& p);
  51. folly::dynamic ini_get(Array& p);
  52. folly::dynamic ini_get(std::set<std::string>& p);
  53. class IniSetting {
  54. struct CallbackData {
  55. Variant active_section;
  56. Variant arr;
  57. };
  58. public:
  59. static const Extension* CORE;
  60. enum ScannerMode {
  61. NormalScanner,
  62. RawScanner,
  63. };
  64. typedef folly::dynamic Map;
  65. class ParserCallback {
  66. public:
  67. virtual ~ParserCallback() {};
  68. virtual void onSection(const std::string &name, void *arg);
  69. virtual void onLabel(const std::string &name, void *arg);
  70. virtual void onEntry(const std::string &key, const std::string &value,
  71. void *arg);
  72. virtual void onPopEntry(const std::string &key, const std::string &value,
  73. const std::string &offset, void *arg);
  74. virtual void onConstant(std::string &result, const std::string &name);
  75. virtual void onVar(std::string &result, const std::string &name);
  76. virtual void onOp(std::string &result, char type, const std::string& op1,
  77. const std::string& op2);
  78. private:
  79. void makeArray(Variant &hash, const std::string &offset,
  80. const std::string &value);
  81. };
  82. class SectionParserCallback : public ParserCallback {
  83. public:
  84. virtual void onSection(const std::string &name, void *arg);
  85. virtual void onLabel(const std::string &name, void *arg);
  86. virtual void onEntry(const std::string &key, const std::string &value,
  87. void *arg);
  88. virtual void onPopEntry(const std::string &key, const std::string &value,
  89. const std::string &offset, void *arg);
  90. private:
  91. Variant* activeArray(CallbackData* data);
  92. };
  93. class SystemParserCallback : public ParserCallback {
  94. public:
  95. virtual void onSection(const std::string &name, void *arg);
  96. virtual void onLabel(const std::string &name, void *arg);
  97. virtual void onEntry(const std::string &key, const std::string &value,
  98. void *arg);
  99. virtual void onPopEntry(const std::string &key, const std::string &value,
  100. const std::string &offset, void *arg);
  101. virtual void onConstant(std::string &result, const std::string &name);
  102. private:
  103. void makeArray(Map &hash, const std::string &offset,
  104. const std::string &value);
  105. };
  106. enum Mode {
  107. PHP_INI_NONE = 0,
  108. // These 3 match zend
  109. PHP_INI_USER = (1u << 0),
  110. PHP_INI_PERDIR = (1u << 1),
  111. PHP_INI_SYSTEM = (1u << 2),
  112. PHP_INI_ONLY = (1u << 3),
  113. PHP_INI_ALL = (1u << 4),
  114. };
  115. public:
  116. static Variant FromString(const String& ini, const String& filename,
  117. bool process_sections, int scanner_mode);
  118. static Map FromStringAsMap(const std::string& ini,
  119. const std::string& filename);
  120. static bool Get(const std::string& name, folly::dynamic &value);
  121. static bool Get(const std::string& name, std::string &value);
  122. static bool Get(const String& name, Variant& value);
  123. static bool Get(const String& name, String& value);
  124. static std::string Get(const std::string& name);
  125. static Array GetAll(const String& extension, bool details);
  126. // Because folly::dynamic and Variant are too ambiguous
  127. enum class FollyDynamic {};
  128. /**
  129. * Change an INI setting as if it was in the php.ini file
  130. */
  131. static bool Set(const std::string& name, const folly::dynamic& value,
  132. FollyDynamic);
  133. static bool Set(const String& name, const Variant& value);
  134. /**
  135. * Change an INI setting as if there was a call to ini_set()
  136. */
  137. static bool SetUser(const std::string& name, const folly::dynamic& value,
  138. FollyDynamic);
  139. static bool SetUser(const String& name, const Variant& value);
  140. template<class T>
  141. struct SetAndGet {
  142. explicit SetAndGet(std::function<bool (const T&)> a, std::function<T ()> b)
  143. : setter(a), getter(b) {}
  144. explicit SetAndGet() {}
  145. std::function<bool (const T&)> setter;
  146. std::function<T ()> getter;
  147. };
  148. /**
  149. * The heavy lifting of creating ini settings. First of all, if you don't
  150. * have to use this method, please don't. Instead use the simpler:
  151. *
  152. * IniSetting::Bind(this, PHP_INI_SYSTEM, "my.ini", &some_global_var);
  153. * or
  154. * IniSetting::Bind(this, PHP_INI_ALL, "my.ini", &some_thread_local_var);
  155. *
  156. * If you have to do something special before your variable is set or gotten
  157. * then you can use this function to add callbacks. Both callbacks are
  158. * optional (but if you don't pass any, why are you using this method in the
  159. * first place?). If the setter callback returns "false" then the value will
  160. * not be saved into p. If the getter is not provided, the contents of p will
  161. * directly be used.
  162. */
  163. template<class T>
  164. static void Bind(const Extension* extension, const Mode mode,
  165. const char *name, const char *defaultValue,
  166. SetAndGet<T> callbacks, T* p = nullptr) {
  167. auto setter = [callbacks, p](const folly::dynamic &value) {
  168. T v;
  169. auto ret = ini_on_update(value, v);
  170. if (!ret) {
  171. return false;
  172. }
  173. if (callbacks.setter) {
  174. ret = callbacks.setter(v);
  175. if (!ret) {
  176. return false;
  177. }
  178. }
  179. if (p) {
  180. *p = v;
  181. }
  182. return true;
  183. };
  184. auto getter = [callbacks, p]() {
  185. T v;
  186. if (callbacks.getter) {
  187. v = callbacks.getter();
  188. } else if (p) {
  189. v = *p;
  190. }
  191. return ini_get(v);
  192. };
  193. Bind(extension, mode, name, setter, getter);
  194. if (defaultValue) {
  195. setter(defaultValue);
  196. }
  197. }
  198. template<class T>
  199. static void Bind(const Extension* extension, const Mode mode,
  200. const char *name, SetAndGet<T> callbacks, T* p = nullptr) {
  201. Bind(extension, mode, name, nullptr, callbacks, p);
  202. }
  203. /**
  204. * Prefer to use this method whenever possible (the non-default one is ok
  205. * too).
  206. */
  207. template<class T>
  208. static void Bind(const Extension* extension, const Mode mode,
  209. const char *name, const char *defaultValue, T *p) {
  210. Bind(extension, mode, name, defaultValue, SetAndGet<T>(), p);
  211. }
  212. template<class T>
  213. static void Bind(const Extension* extension, const Mode mode,
  214. const char *name, T *p) {
  215. Bind(extension, mode, name, nullptr, p);
  216. }
  217. static void Unbind(const char *name);
  218. // Used to allow you to Bind to PHP_INI_SYSTEM settings even after modules
  219. // have been initialized. This should only be used in rare cases that can't
  220. // be refactored into registration before extensions are done.
  221. static bool s_pretendExtensionsHaveNotBeenLoaded;
  222. private:
  223. static void Bind(const Extension* extension, const Mode mode,
  224. const char *name,
  225. std::function<bool(const folly::dynamic& value)>
  226. updateCallback,
  227. std::function<folly::dynamic()> getCallback);
  228. };
  229. int64_t convert_bytes_to_long(const std::string& value);
  230. ///////////////////////////////////////////////////////////////////////////////
  231. }
  232. #endif // incl_HPHP_INI_SETTING_H_