diff --git a/examples/example3.cpp b/examples/example3.cpp index 038f3ba6..31e26534 100644 --- a/examples/example3.cpp +++ b/examples/example3.cpp @@ -86,12 +86,13 @@ int main() vmime::create (fileReader->getInputStream(), imageFile->getLength()); - const vmime::string cid = textPart.addObject(imageCts, - vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG)); + vmime::ref obj = textPart.addObject + (imageCts, vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG)); // -- message text textPart.setText(vmime::create - (vmime::string("This is the HTML text.
"))); + (vmime::string("This is the HTML text.
" + "getReferenceId() + vmime::string("\"/>"))); textPart.setPlainText(vmime::create ("This is the plain text (without HTML formatting).")); diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp index f0b07d9d..ebb6587c 100644 --- a/src/htmlTextPart.cpp +++ b/src/htmlTextPart.cpp @@ -162,7 +162,8 @@ void htmlTextPart::findEmbeddedParts(const bodyPart& part, } -void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id) +void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id, + const embeddedObject::ReferenceType refType) { // The object may already exists. This can happen if an object is // identified by both a Content-Id and a Content-Location. In this @@ -183,7 +184,7 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id) m_objects.push_back(vmime::create (part.getBody()->getContents()->clone().dynamicCast (), - part.getBody()->getEncoding(), id, type)); + part.getBody()->getEncoding(), id, type, refType)); } @@ -235,7 +236,7 @@ void htmlTextPart::parse(ref message, ref pare { // This part is referenced in the HTML text. // Add it to the embedded object list. - addEmbeddedObject(**p, mid.getId()); + addEmbeddedObject(**p, mid.getId(), embeddedObject::REFERENCED_BY_ID); } } @@ -251,7 +252,7 @@ void htmlTextPart::parse(ref message, ref pare { // This part is referenced in the HTML text. // Add it to the embedded object list. - addEmbeddedObject(**p, locStr); + addEmbeddedObject(**p, locStr, embeddedObject::REFERENCED_BY_LOCATION); } } @@ -353,7 +354,7 @@ void htmlTextPart::setCharset(const charset& ch) } -const ref htmlTextPart::getPlainText() const +ref htmlTextPart::getPlainText() const { return m_plainText; } @@ -383,20 +384,18 @@ size_t htmlTextPart::getObjectCount() const } -const ref htmlTextPart::getObjectAt(const size_t pos) const +ref htmlTextPart::getObjectAt(const size_t pos) const { return m_objects[pos]; } -const ref htmlTextPart::findObject(const string& id_) const +ref htmlTextPart::findObject(const string& id) const { - const string id = cleanId(id_); - for (std::vector >::const_iterator o = m_objects.begin() ; o != m_objects.end() ; ++o) { - if ((*o)->getId() == id) + if ((*o)->matchesId(id)) return *o; } @@ -404,14 +403,12 @@ const ref htmlTextPart::findObject(const st } -bool htmlTextPart::hasObject(const string& id_) const +bool htmlTextPart::hasObject(const string& id) const { - const string id = cleanId(id_); - for (std::vector >::const_iterator o = m_objects.begin() ; o != m_objects.end() ; ++o) { - if ((*o)->getId() == id) + if ((*o)->matchesId(id)) return true; } @@ -419,33 +416,99 @@ bool htmlTextPart::hasObject(const string& id_) const } -const string htmlTextPart::addObject(ref data, - const vmime::encoding& enc, const mediaType& type) +ref htmlTextPart::addObject + (ref data, const vmime::encoding& enc, const mediaType& type) { const messageId mid(messageId::generateId()); - const string id = mid.getId(); - m_objects.push_back(vmime::create (data, enc, id, type)); + ref obj = vmime::create + (data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID); - return "CID:" + id; + m_objects.push_back(obj); + + return obj; } -const string htmlTextPart::addObject(ref data, const mediaType& type) +ref htmlTextPart::addObject + (ref data, const mediaType& type) { return addObject(data, encoding::decide(data), type); } -const string htmlTextPart::addObject(const string& data, const mediaType& type) +ref htmlTextPart::addObject + (const string& data, const mediaType& type) { ref cts = vmime::create (data); return addObject(cts, encoding::decide(cts), type); } + +// +// htmlTextPart::embeddedObject +// + +htmlTextPart::embeddedObject::embeddedObject + (ref data, const encoding& enc, + const string& id, const mediaType& type, const ReferenceType refType) + : m_data(data->clone().dynamicCast ()), + m_encoding(enc), m_id(id), m_type(type), m_refType(refType) +{ +} + + +ref htmlTextPart::embeddedObject::getData() const +{ + return m_data; +} + + +const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const +{ + return m_encoding; +} + + +const string htmlTextPart::embeddedObject::getId() const +{ + return m_id; +} + + +const string htmlTextPart::embeddedObject::getReferenceId() const +{ + if (m_refType == REFERENCED_BY_ID) + return string("CID:") + m_id; + else + return m_id; +} + + +const mediaType htmlTextPart::embeddedObject::getType() const +{ + return m_type; +} + + +htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const +{ + return m_refType; +} + + +bool htmlTextPart::embeddedObject::matchesId(const string& id) const +{ + if (m_refType == REFERENCED_BY_ID) + return m_id == cleanId(id); + else + return m_id == id; +} + + // static -const string htmlTextPart::cleanId(const string& id) +const string htmlTextPart::embeddedObject::cleanId(const string& id) { if (id.length() >= 4 && (id[0] == 'c' || id[0] == 'C') && @@ -462,42 +525,4 @@ const string htmlTextPart::cleanId(const string& id) } - -// -// htmlTextPart::embeddedObject -// - -htmlTextPart::embeddedObject::embeddedObject - (ref data, const encoding& enc, - const string& id, const mediaType& type) - : m_data(data->clone().dynamicCast ()), - m_encoding(enc), m_id(id), m_type(type) -{ -} - - -const ref htmlTextPart::embeddedObject::getData() const -{ - return m_data; -} - - -const vmime::encoding& htmlTextPart::embeddedObject::getEncoding() const -{ - return m_encoding; -} - - -const string& htmlTextPart::embeddedObject::getId() const -{ - return m_id; -} - - -const mediaType& htmlTextPart::embeddedObject::getType() const -{ - return m_type; -} - - } // vmime diff --git a/tests/parser/htmlTextPartTest.cpp b/tests/parser/htmlTextPartTest.cpp index 732fcd8c..0eb7bbaf 100644 --- a/tests/parser/htmlTextPartTest.cpp +++ b/tests/parser/htmlTextPartTest.cpp @@ -157,12 +157,14 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) obj = htmlPart.findObject("image1@test"); + VASSERT_EQ("ref-type1", vmime::htmlTextPart::embeddedObject::REFERENCED_BY_ID, obj->getReferenceType()); VASSERT_EQ("id-obj1", "image1@test", obj->getId()); VASSERT_EQ("data-obj1", "Image1", extractContent(obj->getData())); VASSERT_EQ("type-obj1", "image/png", obj->getType().generate()); obj = htmlPart.findObject("image2@test"); + VASSERT_EQ("ref-type2", vmime::htmlTextPart::embeddedObject::REFERENCED_BY_ID, obj->getReferenceType()); VASSERT_EQ("id-obj2", "image2@test", obj->getId()); VASSERT_EQ("data-obj2", "Image2", extractContent(obj->getData())); VASSERT_EQ("type-obj2", "image/jpeg", obj->getType().generate()); @@ -223,6 +225,7 @@ VMIME_TEST_SUITE_BEGIN(htmlTextPartTest) obj = htmlPart.findObject("http://www.vmime.org/test/image1.png"); + VASSERT_EQ("ref-type", vmime::htmlTextPart::embeddedObject::REFERENCED_BY_LOCATION, obj->getReferenceType()); VASSERT_EQ("id-obj", "http://www.vmime.org/test/image1.png", obj->getId()); VASSERT_EQ("data-obj", "Image1", extractContent(obj->getData())); VASSERT_EQ("type-obj", "image/png", obj->getType().generate()); diff --git a/vmime/htmlTextPart.hpp b/vmime/htmlTextPart.hpp index 170c0546..77060565 100644 --- a/vmime/htmlTextPart.hpp +++ b/vmime/htmlTextPart.hpp @@ -51,7 +51,7 @@ public: const charset& getCharset() const; void setCharset(const charset& ch); - const ref getPlainText() const; + ref getPlainText() const; void setPlainText(ref plainText); const ref getText() const; @@ -63,41 +63,84 @@ public: { public: + /** The ways embedded objects can be referenced. */ + enum ReferenceType + { + REFERENCED_BY_ID, /**< Referenced by Content-Id. */ + REFERENCED_BY_LOCATION /**< Referenced by Content-Location. */ + }; + + /** Constructs an embedded object. + * + * @param data content of the object + * @param enc encoding of the data + * @param id object identifier + * @param type object content type + * @param refType reference type + * @return a reference to a new embedded object + */ embeddedObject(ref data, const encoding& enc, - const string& id, const mediaType& type); + const string& id, const mediaType& type, + const ReferenceType refType); /** Return data stored in this embedded object. * * @return stored data */ - const ref getData() const; + ref getData() const; /** Return the encoding used for data in this * embedded object. * * @return data encoding */ - const vmime::encoding& getEncoding() const; + const vmime::encoding getEncoding() const; - /** Return the identifier of this embedded object. + /** Returns the identifier of this embedded object (either a + * unique ID or a location). * * @return object identifier */ - const string& getId() const; + const string getId() const; + + /** Return the identifier used to reference this embedded object + * in a text document (for example, you can use the result as + * the "src" attribute of an <img> tag). + * + * @return object reference identifier + */ + const string getReferenceId() const; /** Return the content type of data stored in * this embedded object. * * @return data type */ - const mediaType& getType() const; + const mediaType getType() const; + + /** Returns the way this object is referenced. + * + * @return reference type (see ReferenceType enum) + */ + ReferenceType getReferenceType() const; + + /** Returns whether this object matches the specified identifier. + * + * @param id identifier to test + * @return true if the specified identifier references this + * object, or false otherwise + */ + bool matchesId(const string& id) const; private: + static const string cleanId(const string& id); + ref m_data; encoding m_encoding; string m_id; mediaType m_type; + ReferenceType m_refType; }; @@ -115,7 +158,7 @@ public: * @param id object identifier * @return embedded object with the specified identifier */ - const ref findObject(const string& id) const; + ref findObject(const string& id) const; /** Return the number of embedded objects. * @@ -128,7 +171,7 @@ public: * @param pos position of the embedded object * @return embedded object at position 'pos' */ - const ref getObjectAt(const size_t pos) const; + ref getObjectAt(const size_t pos) const; /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -142,7 +185,7 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - const string addObject(const string& data, const mediaType& type); + ref addObject(const string& data, const mediaType& type); /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -153,7 +196,7 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - const string addObject(ref data, const mediaType& type); + ref addObject(ref data, const mediaType& type); /** Embed an object and returns a string which identifies it. * The returned identifier is suitable for use in the 'src' attribute @@ -165,7 +208,7 @@ public: * @return an unique object identifier used to identify the new * object among all other embedded objects */ - const string addObject(ref data, const encoding& enc, const mediaType& type); + ref addObject(ref data, const encoding& enc, const mediaType& type); size_t getPartCount() const; @@ -182,11 +225,9 @@ private: std::vector > m_objects; void findEmbeddedParts(const bodyPart& part, std::vector >& cidParts, std::vector >& locParts); - void addEmbeddedObject(const bodyPart& part, const string& id); + void addEmbeddedObject(const bodyPart& part, const string& id, const embeddedObject::ReferenceType refType); bool findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart); - - static const string cleanId(const string& id); };