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.
sems/core/AmMimeBody.h

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