mirror of https://github.com/sipwise/sems.git
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.
188 lines
4.4 KiB
188 lines
4.4 KiB
#ifndef _AmMimeBody_h_
|
|
#define _AmMimeBody_h_
|
|
|
|
#include "AmArg.h"
|
|
|
|
#include <string>
|
|
#include <list>
|
|
#include <map>
|
|
|
|
using std::string;
|
|
using std::list;
|
|
using std::map;
|
|
|
|
struct AmContentType
|
|
{
|
|
struct Param
|
|
{
|
|
|
|
enum Type {
|
|
UNPARSED=0,
|
|
BOUNDARY,
|
|
OTHER
|
|
};
|
|
|
|
Type type;
|
|
string name;
|
|
string value;
|
|
|
|
Param(const string& name, const string& value)
|
|
: type(UNPARSED), name(name), value(value) {}
|
|
|
|
int parseType();
|
|
};
|
|
|
|
typedef list<Param*> Params;
|
|
|
|
string type;
|
|
string subtype;
|
|
Params params;
|
|
Param* mp_boundary;
|
|
|
|
AmContentType();
|
|
AmContentType(const AmContentType& ct);
|
|
~AmContentType();
|
|
|
|
const AmContentType& operator = (const AmContentType& r_ct);
|
|
|
|
int parse(const string& ct);
|
|
int parseParams(const char* c, const char* end);
|
|
|
|
void setType(const string& t);
|
|
void setSubType(const string& st);
|
|
|
|
bool isType(const string& t) const;
|
|
bool isSubType(const string& st) const;
|
|
bool hasContentType(const string& content_type) const;
|
|
|
|
/** get content-type without any parameters */
|
|
string getStr() const;
|
|
|
|
/** get content-type with parameters */
|
|
string getHdr() const;
|
|
|
|
/** Clear and free param list */
|
|
void clearParams();
|
|
|
|
/** set a random boundary string */
|
|
void resetBoundary();
|
|
};
|
|
|
|
class AmMimeBody
|
|
: public AmObject
|
|
{
|
|
public:
|
|
typedef list<AmMimeBody*> Parts;
|
|
|
|
private:
|
|
AmContentType ct;
|
|
string hdrs;
|
|
unsigned int content_len;
|
|
unsigned char* payload;
|
|
|
|
Parts parts;
|
|
|
|
void clearParts();
|
|
void clearPart(Parts::iterator position);
|
|
void clearPayload();
|
|
|
|
int parseMultipart(const unsigned char* buf, unsigned int len);
|
|
int findNextBoundary(unsigned char** beg, unsigned char** end);
|
|
int parseSinglePart(unsigned char* buf, unsigned int len);
|
|
|
|
void convertToMultipart();
|
|
void convertToSinglepart();
|
|
|
|
public:
|
|
/** Empty constructor */
|
|
AmMimeBody();
|
|
|
|
/** Deep-copy constructor */
|
|
AmMimeBody(const AmMimeBody& body);
|
|
|
|
/** Destuctor */
|
|
~AmMimeBody();
|
|
|
|
/** Deep copy operator */
|
|
const AmMimeBody& operator = (const AmMimeBody& r_body);
|
|
|
|
/** Parse a body (single & multi-part) */
|
|
int parse(const string& content_type,
|
|
const unsigned char* buf,
|
|
unsigned int len);
|
|
|
|
/** Set the payload of this body */
|
|
void setPayload(const unsigned char* buf, unsigned int len);
|
|
|
|
/** Set part headers (intended for sub-parts)*/
|
|
void setHeaders(const string& hdrs);
|
|
|
|
/**
|
|
* Add a new part to this body, possibly
|
|
* converting to multi-part if necessary.
|
|
* @return a pointer to the new empty part.
|
|
*/
|
|
AmMimeBody* addPart(const string& content_type);
|
|
|
|
/**
|
|
* Delete a body part, converting resulting body to single-part if necessary.
|
|
*/
|
|
int deletePart(const string& content_type);
|
|
|
|
/** Get content-type without any parameters */
|
|
string getCTStr() const { return ct.getStr(); }
|
|
|
|
/** Get content-type with parameters */
|
|
string getCTHdr() const { return ct.getHdr(); }
|
|
|
|
/** @return the list of sub-parts */
|
|
const Parts& getParts() const { return parts; }
|
|
|
|
/** @return the sub-part headers */
|
|
const string& getHeaders() const { return hdrs; }
|
|
|
|
/**
|
|
* @return a pointer to the payload of this part.
|
|
* in case of multi-part, NULL is returned.
|
|
*/
|
|
const unsigned char* getPayload() const { return payload; }
|
|
|
|
/**
|
|
* @return the payload length of this part.
|
|
* in case of multi-part, 0 is returned.
|
|
*/
|
|
unsigned int getLen() const { return content_len; }
|
|
|
|
/** @return true if no payload assigned and no sub-parts available */
|
|
bool empty() const;
|
|
|
|
/** @return true if this part has the provided content-type */
|
|
bool isContentType(const string& content_type) const;
|
|
|
|
/**
|
|
* @return a pointer to a part of the coresponding
|
|
* content-type (if available).
|
|
* This could be a pointer to this body.
|
|
*/
|
|
AmMimeBody* hasContentType(const string& content_type);
|
|
|
|
/**
|
|
* @return a const pointer to a part of the coresponding
|
|
* content-type (if available).
|
|
* This could be a pointer to this body.
|
|
*/
|
|
const AmMimeBody* hasContentType(const string& content_type) const;
|
|
|
|
/**
|
|
* Print the body including sub-parts suitable for sending
|
|
* within the body of a SIP message.
|
|
*/
|
|
void print(string& buf) const;
|
|
|
|
const AmContentType &getContentType() { return ct; }
|
|
void setContentType(const AmContentType &_ct) { ct = _ct; }
|
|
void addPart(const AmMimeBody &part) { parts.push_back(new AmMimeBody(part)); }
|
|
};
|
|
|
|
#endif
|