1 #ifndef _AmMimeBody_h_ 2 #define _AmMimeBody_h_ 3 4 #include "AmArg.h" 5 6 #include <string> 7 #include <list> 8 #include <map> 9 10 using std::string; 11 using std::list; 12 using std::map; 13 14 struct AmContentType 15 { 16 struct Param 17 { 18 19 enum Type { 20 UNPARSED=0, 21 BOUNDARY, 22 OTHER 23 }; 24 25 Type type; 26 string name; 27 string value; 28 29 Param(const string& name, const string& value) 30 : type(UNPARSED), name(name), value(value) {} 31 32 int parseType(); 33 }; 34 35 typedef list<Param*> Params; 36 37 string type; 38 string subtype; 39 Params params; 40 Param* mp_boundary; 41 42 AmContentType(); 43 AmContentType(const AmContentType& ct); 44 ~AmContentType(); 45 46 const AmContentType& operator = (const AmContentType& r_ct); 47 48 int parse(const string& ct); 49 int parseParams(const char* c, const char* end); 50 51 void setType(const string& t); 52 void setSubType(const string& st); 53 54 bool isType(const string& t) const; 55 bool isSubType(const string& st) const; 56 bool hasContentType(const string& content_type) const; 57 58 /** get content-type without any parameters */ 59 string getStr() const; 60 61 /** get content-type with parameters */ 62 string getHdr() const; 63 64 /** Clear and free param list */ 65 void clearParams(); 66 67 /** set a random boundary string */ 68 void resetBoundary(); 69 }; 70 71 class AmMimeBody 72 : public AmObject 73 { 74 public: 75 typedef list<AmMimeBody*> Parts; 76 77 private: 78 AmContentType ct; 79 string hdrs; 80 unsigned int content_len; 81 unsigned char* payload; 82 83 Parts parts; 84 85 void clearParts(); 86 void clearPart(Parts::iterator position); 87 void clearPayload(); 88 89 int parseMultipart(const unsigned char* buf, unsigned int len); 90 int findNextBoundary(unsigned char** beg, unsigned char** end); 91 int parseSinglePart(unsigned char* buf, unsigned int len); 92 93 void convertToMultipart(); 94 void convertToSinglepart(); 95 96 public: 97 /** Empty constructor */ 98 AmMimeBody(); 99 100 /** Deep-copy constructor */ 101 AmMimeBody(const AmMimeBody& body); 102 103 /** Destuctor */ 104 ~AmMimeBody(); 105 106 /** Deep copy operator */ 107 const AmMimeBody& operator = (const AmMimeBody& r_body); 108 109 /** Parse a body (single & multi-part) */ 110 int parse(const string& content_type, 111 const unsigned char* buf, 112 unsigned int len); 113 114 /** Set the payload of this body */ 115 void setPayload(const unsigned char* buf, unsigned int len); 116 117 /** Set part headers (intended for sub-parts)*/ 118 void setHeaders(const string& hdrs); 119 120 /** 121 * Add a new part to this body, possibly 122 * converting to multi-part if necessary. 123 * @return a pointer to the new empty part. 124 */ 125 AmMimeBody* addPart(const string& content_type); 126 127 /** 128 * Delete a body part, converting resulting body to single-part if necessary. 129 */ 130 int deletePart(const string& content_type); 131 132 /** Get content-type without any parameters */ 133 string getCTStr() const { return ct.getStr(); } 134 135 /** Get content-type with parameters */ 136 string getCTHdr() const { return ct.getHdr(); } 137 138 /** @return the list of sub-parts */ 139 const Parts& getParts() const { return parts; } 140 141 /** @return the sub-part headers */ 142 const string& getHeaders() const { return hdrs; } 143 144 /** 145 * @return a pointer to the payload of this part. 146 * in case of multi-part, NULL is returned. 147 */ 148 const unsigned char* getPayload() const { return payload; } 149 150 /** 151 * @return the payload length of this part. 152 * in case of multi-part, 0 is returned. 153 */ 154 unsigned int getLen() const { return content_len; } 155 156 /** @return true if no payload assigned and no sub-parts available */ 157 bool empty() const; 158 159 /** @return true if this part has the provided content-type */ 160 bool isContentType(const string& content_type) const; 161 162 /** 163 * @return a pointer to a part of the coresponding 164 * content-type (if available). 165 * This could be a pointer to this body. 166 */ 167 AmMimeBody* hasContentType(const string& content_type); 168 169 /** 170 * @return a const pointer to a part of the coresponding 171 * content-type (if available). 172 * This could be a pointer to this body. 173 */ 174 const AmMimeBody* hasContentType(const string& content_type) const; 175 176 /** 177 * Print the body including sub-parts suitable for sending 178 * within the body of a SIP message. 179 */ 180 void print(string& buf) const; 181 182 const AmContentType &getContentType() { return ct; } 183 void setContentType(const AmContentType &_ct) { ct = _ct; } 184 void addPart(const AmMimeBody &part) { parts.push_back(new AmMimeBody(part)); } 185 }; 186 187 #endif 188