You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
9.1 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: pantheios/util/backends/context.hpp
  3. *
  4. * Purpose: Implementation class to assist in the creation of back-ends.
  5. *
  6. * Created: 16th December 2006
  7. * Updated: 26th November 2010
  8. *
  9. * Home: http://www.pantheios.org/
  10. *
  11. * Copyright (c) 2006-2010, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are
  16. * met:
  17. *
  18. * - Redistributions of source code must retain the above copyright notice,
  19. * this list of conditions and the following disclaimer.
  20. * - Redistributions in binary form must reproduce the above copyright
  21. * notice, this list of conditions and the following disclaimer in the
  22. * documentation and/or other materials provided with the distribution.
  23. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  24. * names of any contributors may be used to endorse or promote products
  25. * derived from this software without specific prior written permission.
  26. *
  27. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  28. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  29. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  30. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  31. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  32. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  33. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  34. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  35. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  36. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. * ////////////////////////////////////////////////////////////////////// */
  40. /** \file pantheios/util/backends/context.hpp
  41. *
  42. * [C++ only] Implementation class to assist in the creation of back-ends.
  43. */
  44. #ifndef PANTHEIOS_INCL_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT
  45. #define PANTHEIOS_INCL_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT
  46. /* /////////////////////////////////////////////////////////////////////////
  47. * Version information
  48. */
  49. #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
  50. # define PANTHEIOS_VER_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT_MAJOR 3
  51. # define PANTHEIOS_VER_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT_MINOR 3
  52. # define PANTHEIOS_VER_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT_REVISION 2
  53. # define PANTHEIOS_VER_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT_EDIT 33
  54. #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
  55. /* /////////////////////////////////////////////////////////////////////////
  56. * Includes
  57. */
  58. #ifndef PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS
  59. # include <pantheios/pantheios.h>
  60. #endif /* !PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS */
  61. #ifndef PANTHEIOS_INCL_PANTHEIOS_QUALITY_H_CONTRACT
  62. # include <pantheios/quality/contract.h>
  63. #endif /* !PANTHEIOS_INCL_PANTHEIOS_QUALITY_H_CONTRACT */
  64. #ifndef __cplusplus
  65. # error This file can only be used in C++ compilation units
  66. #endif /* !__cplusplus */
  67. /* /////////////////////////////////////////////////////////////////////////
  68. * Namespace
  69. */
  70. #if !defined(PANTHEIOS_NO_NAMESPACE)
  71. namespace pantheios
  72. {
  73. namespace util
  74. {
  75. namespace backends
  76. {
  77. #endif /* !PANTHEIOS_NO_NAMESPACE */
  78. /* /////////////////////////////////////////////////////////////////////////
  79. * Classes
  80. */
  81. /** Framework class for assisting in the writing of \ref group__backend "Back-ends".
  82. *
  83. * To use pantheios::util::backends::Context, you derive from it, and override
  84. * the rawLogEntry() method, as in the implementation of be.speech:
  85. <pre>
  86. struct be_speech_context
  87. : public pantheios::util::backends::Context
  88. {
  89. public: // Member Types
  90. typedef pantheios::util::backends::Context parent_class_type;
  91. typedef be_speech_context class_type;
  92. typedef std::string string_type;
  93. typedef stlsoft::ref_ptr<ISpVoice> voice_type;
  94. public: // Construction
  95. be_speech_context(pan_char_t const* processIdentity, int id, pantheios::uint32_t flags, voice_type voice);
  96. ~be_speech_context() throw();
  97. private: // Overrides
  98. virtual int rawLogEntry(int severity, const pan_slice_t (&ar)[rawLogArrayDimension], size_t cchTotal);
  99. . . .
  100. };
  101. </pre>
  102. *
  103. * An instance of the derived class is created in the back-end
  104. * initialisation function, and destroyed in the uninitialisation function,
  105. * each of which are called a maximum of one time per program execution.
  106. *
  107. * Finally, in the implementation of the back-end's log entry function, the
  108. * logEntry() method is called, as in:
  109. <pre>
  110. static int pantheios_be_speech_logEntry( void* // feToken
  111. , void* beToken
  112. , int severity
  113. , pan_char_t const* entry
  114. , size_t cchEntry)
  115. {
  116. PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(NULL != beToken, "back-end token may not be null");
  117. be_speech_context* ctxt = static_cast<be_speech_context*>(beToken);
  118. return ctxt->logEntry(severity, entry, cchEntry);
  119. }
  120. </pre>
  121. *
  122. * \ingroup group__utility__backend
  123. */
  124. class Context
  125. {
  126. /// \name Member Types
  127. /// @{
  128. public:
  129. typedef Context class_type;
  130. /// @}
  131. /// \name Member Constants
  132. /// @{
  133. protected:
  134. enum { rawLogArrayDimension = 10 };
  135. /// @}
  136. /// \name Construction
  137. /// @{
  138. protected:
  139. /// Constructs an instance
  140. ///
  141. /// \param processIdentity The process identity. May not be NULL or
  142. /// empty
  143. /// \param id The back-end identifier
  144. /// \param flags Flags that control the elements presented in the
  145. /// log statements
  146. /// \param severityMask Mask that prescribes the valid range of the
  147. /// severity for the derived class. Must be either 0x07 or 0x0f
  148. Context(pan_char_t const* processIdentity, int id, pan_uint32_t flags, int severityMask);
  149. virtual ~Context() throw();
  150. /// @}
  151. /// \name Operations
  152. /// @{
  153. public:
  154. ///
  155. ///
  156. /// \note This method does not mutate any member data. It is not marked
  157. /// <code>const</code> solely because it invokes rawLogEntry(), which
  158. /// may need to mutate member data of the derived class (though this
  159. /// will not be the dominant form).
  160. ///
  161. /// \note Because the method does not, in and of itself, mutate data,
  162. /// backends using the class may only need to lock if the underlying
  163. /// transmission medium requires it, and this may only need to be
  164. /// inside the call to rawLogEntry(), on a back-end-specific basis.
  165. int logEntry(int severity, pan_char_t const* entry, size_t cchEntry);
  166. /// @}
  167. /// \name Overrides
  168. /// @{
  169. private:
  170. /// \param severity The severity at which the statement will be logged
  171. /// \param ar A reference to an array of 'rawLogArrayDimension' slices
  172. virtual int rawLogEntry(int severity4, int severityX, const pan_slice_t (&ar)[rawLogArrayDimension], size_t cchTotal) = 0;
  173. /// \param severity The severity at which the statement will be logged
  174. /// \param entry Pointer to the C-style string containing the entry
  175. /// \param cchEntry Number of characters in the entry, not including the
  176. /// nul-terminator
  177. virtual int rawLogEntry(int severity4, int severityX, pan_char_t const* entry, size_t cchEntry);
  178. /// @}
  179. /// \name Utilities
  180. /// @{
  181. protected:
  182. /// Concatenates the slices into the given destination
  183. static size_t concatenateSlices(pan_char_t* dest, size_t cchDest, size_t numSlices, pan_slice_t const* slices);
  184. /// @}
  185. /// \name Accessors
  186. /// @{
  187. public:
  188. /// The process identity
  189. ///
  190. /// \note In builds where exceptions are not enabled, or with compilers
  191. /// that do not throw std::bad_alloc on allocation failure, this will
  192. /// return NULL to indicate that construction has failed
  193. pan_char_t const* getProcessIdentity() const;
  194. int getBackEndId() const;
  195. /// @}
  196. /// \name Member Variables
  197. /// @{
  198. protected:
  199. pan_char_t* const m_processIdentity;
  200. int const m_id;
  201. pan_uint32_t const m_flags;
  202. int const m_severityMask;
  203. private:
  204. // 0: "["
  205. // 1: process Id
  206. // 2: "."
  207. // 3: thread Id
  208. // 4: "; "
  209. // 5: time
  210. // 6: "; "
  211. // 5: severity
  212. // 8: "]: "
  213. // 9: entry
  214. pan_slice_t m_slice0;
  215. pan_slice_t m_slice1;
  216. pan_slice_t m_slice2;
  217. pan_slice_t m_slice4;
  218. pan_slice_t m_slice6;
  219. pan_slice_t m_slice8;
  220. /// @}
  221. /// \name Not to be implemented
  222. /// @{
  223. private:
  224. Context(class_type const&);
  225. class_type& operator =(class_type const&);
  226. /// @}
  227. };
  228. /* /////////////////////////////////////////////////////////////////////////
  229. * Namespace
  230. */
  231. #if !defined(PANTHEIOS_NO_NAMESPACE)
  232. } // namespace backends
  233. } // namespace util
  234. } // namespace pantheios
  235. #endif /* !PANTHEIOS_NO_NAMESPACE */
  236. /* ////////////////////////////////////////////////////////////////////// */
  237. #endif /* !PANTHEIOS_INCL_PANTHEIOS_UTIL_BACKENDS_HPP_CONTEXT */
  238. /* ///////////////////////////// end of file //////////////////////////// */