1 // This may look like C code, but it's really -*- C++ -*-
2 /*
3  * Copyright (C) Emweb bv, Herent, Belgium.
4  *
5  * See the LICENSE file for terms of use.
6  */
7 #ifndef WMEMORY_RESOURCE_H_
8 #define WMEMORY_RESOURCE_H_
9 
10 #include <mutex>
11 #include <string>
12 #include <thread>
13 
14 #include <Wt/WResource.h>
15 
16 namespace Wt {
17 
18 /*! \class WMemoryResource Wt/WMemoryResource.h Wt/WMemoryResource.h
19  *  \brief A resource which streams data from memory
20  *
21  * Use this resource if you want to serve resource data from memory. This
22  * is suitable for relatively small resources, which still require some
23  * computation.
24  *
25  * If creating the data requires computation which you would like to
26  * post-pone until the resource is served, then you may want to
27  * directly reimplement WResource instead and compute the data on the
28  * fly while streaming.
29  *
30  * Usage examples:
31  * \code
32  * auto imageResource = std::make_shared<Wt::WMemoryResource>("image/gif");
33  *
34  * static const unsigned char gifData[]
35  *    = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00,
36  *        0x80, 0x00, 0x00, 0xdb, 0xdf, 0xef, 0x00, 0x00, 0x00, 0x21,
37  *        0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00,
38  *        0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44,
39  *        0x01, 0x00, 0x3b };
40  *
41  * imageResource->setData(gifData, 43);
42  * auto image = std::make_unique<Wt::WImage>(Wt::WLink(imageResource), "1 transparent pixel");
43  * \endcode
44  *
45  * \sa WFileResource.
46  */
47 class WT_API WMemoryResource : public WResource
48 {
49 public:
50   /*! \brief Creates a new resource.
51    *
52    * You must call setMimeType() and setData() before using the resource.
53    */
54   WMemoryResource();
55 
56   /*! \brief Creates a new resource with given mime-type.
57    *
58    * You must call setData() before using the resource.
59    */
60   WMemoryResource(const std::string& mimeType);
61 
62   /*! \brief Creates a new resource with given mime-type and data
63    */
64   WMemoryResource(const std::string& mimeType,
65 		  const std::vector<unsigned char>& data);
66 
67   ~WMemoryResource();
68 
69   /*! \brief Sets new data for the resource to serve.
70    */
71   void setData(const std::vector<unsigned char> &data);
72 
73   /*! \brief Sets new data for the resource to serve.
74    *
75    * Sets the data from using the first \p count bytes from the
76    * C-style \p data array.
77    */
78   void setData(const unsigned char *data, int count);
79 
80   /*! \brief Returns the data this resource will serve.
81    */
82   const std::vector<unsigned char> data() const;
83 
84   /*! \brief Returns the mime-type.
85    */
mimeType()86   const std::string mimeType() const { return mimeType_; }
87 
88   /*! \brief Sets the mime-type.
89    */
90   void setMimeType(const std::string& mimeType);
91 
92   virtual void handleRequest(const Http::Request& request,
93                              Http::Response& response) override;
94 
95 private:
96   typedef std::shared_ptr< const std::vector<unsigned char> > DataPtr;
97 
98   std::string mimeType_;
99   DataPtr data_;
100 
101   std::shared_ptr<std::mutex> dataMutex_;
102 
103   void create();
104 };
105 
106 }
107 
108 #endif // WMEMORY_RESOURCE_H_
109