mirror of
				https://github.com/zeromq/cppzmq.git
				synced 2025-11-04 04:10:00 +01:00 
			
		
		
		
	Merge remote-tracking branch 'remotes/origin/master'
This commit is contained in:
		@@ -45,60 +45,72 @@ private:
 | 
				
			|||||||
    std::deque<message_t> m_parts;
 | 
					    std::deque<message_t> m_parts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    // Default constructor
 | 
				
			||||||
    multipart_t()
 | 
					    multipart_t()
 | 
				
			||||||
    {}
 | 
					    {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Construct from socket receive
 | 
				
			||||||
    multipart_t(socket_t& socket)
 | 
					    multipart_t(socket_t& socket)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        recv(socket);
 | 
					        recv(socket);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Construct from memory block
 | 
				
			||||||
    multipart_t(const void *src, size_t size)
 | 
					    multipart_t(const void *src, size_t size)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        addmem(src, size);
 | 
					        addmem(src, size);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Construct from string
 | 
				
			||||||
    multipart_t(const std::string& string)
 | 
					    multipart_t(const std::string& string)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        addstr(string);
 | 
					        addstr(string);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Construct from message part
 | 
				
			||||||
    multipart_t(message_t&& message)
 | 
					    multipart_t(message_t&& message)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        add(std::move(message));
 | 
					        add(std::move(message));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Move constructor
 | 
				
			||||||
    multipart_t(multipart_t&& other)
 | 
					    multipart_t(multipart_t&& other)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::swap(m_parts, other.m_parts);
 | 
					        m_parts = std::move(other.m_parts);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Move assignment operator
 | 
				
			||||||
    multipart_t& operator=(multipart_t&& other)
 | 
					    multipart_t& operator=(multipart_t&& other)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::swap(m_parts, other.m_parts);
 | 
					        m_parts = std::move(other.m_parts);
 | 
				
			||||||
        return *this;
 | 
					        return *this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Destructor
 | 
				
			||||||
    virtual ~multipart_t()
 | 
					    virtual ~multipart_t()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        clear();
 | 
					        clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Delete all parts
 | 
				
			||||||
    void clear()
 | 
					    void clear()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.clear();
 | 
					        m_parts.clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get number of parts
 | 
				
			||||||
    size_t size() const
 | 
					    size_t size() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return m_parts.size();
 | 
					        return m_parts.size();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if number of parts is zero
 | 
				
			||||||
    bool empty() const
 | 
					    bool empty() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return m_parts.empty();
 | 
					        return m_parts.empty();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Receive multipart message from socket
 | 
				
			||||||
    bool recv(socket_t& socket, int flags = 0)
 | 
					    bool recv(socket_t& socket, int flags = 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        clear();
 | 
					        clear();
 | 
				
			||||||
@@ -114,6 +126,7 @@ public:
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Send multipart message to socket
 | 
				
			||||||
    bool send(socket_t& socket, int flags = 0)
 | 
					    bool send(socket_t& socket, int flags = 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        flags &= ~(ZMQ_SNDMORE);
 | 
					        flags &= ~(ZMQ_SNDMORE);
 | 
				
			||||||
@@ -129,104 +142,115 @@ public:
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Concatenate other multipart to front
 | 
				
			||||||
    void prepend(multipart_t&& other)
 | 
					    void prepend(multipart_t&& other)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        while (!other.empty())
 | 
					        while (!other.empty())
 | 
				
			||||||
            push(other.remove());
 | 
					            push(other.remove());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Concatenate other multipart to back
 | 
				
			||||||
    void append(multipart_t&& other)
 | 
					    void append(multipart_t&& other)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        while (!other.empty())
 | 
					        while (!other.empty())
 | 
				
			||||||
            add(other.pop());
 | 
					            add(other.pop());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push memory block to front
 | 
				
			||||||
    void pushmem(const void *src, size_t size)
 | 
					    void pushmem(const void *src, size_t size)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_front(message_t(src, size));
 | 
					        m_parts.push_front(message_t(src, size));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push memory block to back
 | 
				
			||||||
    void addmem(const void *src, size_t size)
 | 
					    void addmem(const void *src, size_t size)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_back(message_t(src, size));
 | 
					        m_parts.push_back(message_t(src, size));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push string to front
 | 
				
			||||||
    void pushstr(const std::string& string)
 | 
					    void pushstr(const std::string& string)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_front(message_t(string.data(), string.size()));
 | 
					        m_parts.push_front(message_t(string.data(), string.size()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push string to back
 | 
				
			||||||
    void addstr(const std::string& string)
 | 
					    void addstr(const std::string& string)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_back(message_t(string.data(), string.size()));
 | 
					        m_parts.push_back(message_t(string.data(), string.size()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push type (fixed-size) to front
 | 
				
			||||||
    template<typename T>
 | 
					    template<typename T>
 | 
				
			||||||
    void pushtyp(const T& type)
 | 
					    void pushtyp(const T& type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        static_assert(!std::is_same<T, std::string>::value, "Use pushstr() instead of pushtyp<std::string>()");
 | 
				
			||||||
        m_parts.push_front(message_t(&type, sizeof(type)));
 | 
					        m_parts.push_front(message_t(&type, sizeof(type)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push type (fixed-size) to back
 | 
				
			||||||
    template<typename T>
 | 
					    template<typename T>
 | 
				
			||||||
    void addtyp(const T& type)
 | 
					    void addtyp(const T& type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        static_assert(!std::is_same<T, std::string>::value, "Use addstr() instead of addtyp<std::string>()");
 | 
				
			||||||
        m_parts.push_back(message_t(&type, sizeof(type)));
 | 
					        m_parts.push_back(message_t(&type, sizeof(type)));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push message part to front
 | 
				
			||||||
    void push(message_t&& message)
 | 
					    void push(message_t&& message)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_front(std::move(message));
 | 
					        m_parts.push_front(std::move(message));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Push message part to back
 | 
				
			||||||
    void add(message_t&& message)
 | 
					    void add(message_t&& message)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        m_parts.push_back(std::move(message));
 | 
					        m_parts.push_back(std::move(message));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pop string from front
 | 
				
			||||||
    std::string popstr()
 | 
					    std::string popstr()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (m_parts.empty())
 | 
					 | 
				
			||||||
            return "";
 | 
					 | 
				
			||||||
        std::string string(m_parts.front().data<char>(), m_parts.front().size());
 | 
					        std::string string(m_parts.front().data<char>(), m_parts.front().size());
 | 
				
			||||||
        m_parts.pop_front();
 | 
					        m_parts.pop_front();
 | 
				
			||||||
        return string;
 | 
					        return string;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pop type (fixed-size) from front
 | 
				
			||||||
    template<typename T>
 | 
					    template<typename T>
 | 
				
			||||||
    T poptyp()
 | 
					    T poptyp()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (m_parts.empty())
 | 
					        static_assert(!std::is_same<T, std::string>::value, "Use popstr() instead of poptyp<std::string>()");
 | 
				
			||||||
            return T();
 | 
					        if (sizeof(T) != m_parts.front().size())
 | 
				
			||||||
 | 
					            throw std::runtime_error("Invalid type, size does not match the message size");
 | 
				
			||||||
        T type = *m_parts.front().data<T>();
 | 
					        T type = *m_parts.front().data<T>();
 | 
				
			||||||
        m_parts.pop_front();
 | 
					        m_parts.pop_front();
 | 
				
			||||||
        return type;
 | 
					        return type;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pop message part from front
 | 
				
			||||||
    message_t pop()
 | 
					    message_t pop()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (m_parts.empty())
 | 
					 | 
				
			||||||
            return message_t(0);
 | 
					 | 
				
			||||||
        message_t message = std::move(m_parts.front());
 | 
					        message_t message = std::move(m_parts.front());
 | 
				
			||||||
        m_parts.pop_front();
 | 
					        m_parts.pop_front();
 | 
				
			||||||
        return message;
 | 
					        return message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Pop message part from back
 | 
				
			||||||
    message_t remove()
 | 
					    message_t remove()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (m_parts.empty())
 | 
					 | 
				
			||||||
            return message_t(0);
 | 
					 | 
				
			||||||
        message_t message = std::move(m_parts.back());
 | 
					        message_t message = std::move(m_parts.back());
 | 
				
			||||||
        m_parts.pop_back();
 | 
					        m_parts.pop_back();
 | 
				
			||||||
        return message;
 | 
					        return message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get pointer to a specific message part
 | 
				
			||||||
    const message_t* peek(size_t index) const
 | 
					    const message_t* peek(size_t index) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (index >= size())
 | 
					 | 
				
			||||||
            return nullptr;
 | 
					 | 
				
			||||||
        return &m_parts[index];
 | 
					        return &m_parts[index];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create multipart from type (fixed-size)
 | 
				
			||||||
    template<typename T>
 | 
					    template<typename T>
 | 
				
			||||||
    static multipart_t create(const T& type)
 | 
					    static multipart_t create(const T& type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -235,6 +259,7 @@ public:
 | 
				
			|||||||
        return multipart;
 | 
					        return multipart;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Copy multipart
 | 
				
			||||||
    multipart_t clone() const
 | 
					    multipart_t clone() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        multipart_t multipart;
 | 
					        multipart_t multipart;
 | 
				
			||||||
@@ -243,6 +268,7 @@ public:
 | 
				
			|||||||
        return multipart;
 | 
					        return multipart;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Dump content to string
 | 
				
			||||||
    std::string str() const
 | 
					    std::string str() const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::stringstream ss;
 | 
					        std::stringstream ss;
 | 
				
			||||||
@@ -278,6 +304,7 @@ public:
 | 
				
			|||||||
        return ss.str();
 | 
					        return ss.str();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check if equal to other multipart
 | 
				
			||||||
    bool equal(const multipart_t* other) const
 | 
					    bool equal(const multipart_t* other) const
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (size() != other->size())
 | 
					        if (size() != other->size())
 | 
				
			||||||
@@ -288,6 +315,7 @@ public:
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Self test
 | 
				
			||||||
    static int test()
 | 
					    static int test()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        bool ok = true;
 | 
					        bool ok = true;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user