Skip to content

Code Examples & Integration Recipes

Ready-to-compile modern C++20 code examples demonstrating common sip2json parsing, serialization, and high-throughput streaming patterns.


Core Usage Examples

sip2json::parseAsync reads continuous TCP/TLS buffers, processes complete frames via zero-copy callbacks, and leaves partial frames intact for subsequent network reads.

#include <iostream>
#include <string>
#include "siddiqsoft/sip2json.hpp"

using namespace siddiqsoft;

void handleNetworkInput(std::string& socketReadBuffer)
{
    auto cursor = socketReadBuffer.begin();

    // Parse stream buffer in-place; invoke callback for each complete frame
    sip2json::parseAsync(
        cursor,
        socketReadBuffer.end(),
        [](sipmessage&& msg) {
            std::cout << "[SIP Message Received]\n"
                      << "  Type:    " << msg.type << "\n"
                      << "  Method:  " << msg.method << "\n"
                      << "  URI:     " << msg.uri << "\n"
                      << "  Call-ID: " << msg.callid << "\n";
        },
        [](sip2json_exception& ex, std::string::iterator& start, const std::string::iterator& end) {
            std::cerr << "[Parser Error] " << ex.what() << "\n";
        }
    );

    // Erase consumed frames; incomplete frames remain at front of buffer
    socketReadBuffer.erase(socketReadBuffer.begin(), cursor);
}

int main()
{
    std::string buffer =
        "REGISTER sip:example.com SIP/2.0\r\n"
        "Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-123\r\n"
        "From: <sip:user@example.com>;tag=111\r\n"
        "To: <sip:user@example.com>\r\n"
        "Call-ID: reg-101@192.168.1.1\r\n"
        "CSeq: 1 REGISTER\r\n"
        "Content-Length: 0\r\n\r\n";

    handleNetworkInput(buffer);
    return 0;
}

Construct standard RFC 3261 messages using fluent chaining, attach structured SDP bodies, and serialize directly to wire format.

#include <iostream>
#include "siddiqsoft/sip2json.hpp"

using namespace siddiqsoft;

int main()
{
    // 1. Construct INVITE request DTO
    sipmessage msg(siddiqsoft::METHOD_INVITE, "sip:bob@biloxi.example.com", "call-id-99812@atlanta", 1);

    // 2. Set headers using fluent chaining
    msg.setHeader(siddiqsoft::HF_FROM, "sip:alice@atlanta.example.com;tag=a831")
       .setHeader(siddiqsoft::HF_TO, "sip:bob@biloxi.example.com")
       .setHeader(siddiqsoft::HF_CONTACT, "<sip:alice@10.0.0.4:5060>")
       .setHeader(siddiqsoft::HF_CONTENT_TYPE, "application/sdp")
       .setHeader(siddiqsoft::HF_USER_AGENT, "sip2json/3.1.0");

    // 3. Attach SDP payload directly
    msg.body = {
        {"sdp", {
            {
                {"v", 0},
                {"o", {{"user", "alice"}, {"t1", "1000"}, {"t2", "1000"}, {"type", "IN"}, {"subtype", "IP4"}, {"host", "10.0.0.4"}}},
                {"s", "SIP Session"},
                {"c", {{"type", "IN"}, {"subtype", "IP4"}, {"dn", "10.0.0.4"}}},
                {"t", {0, 0}},
                {"m", "audio 49170 RTP/AVP 0 101"},
                {"a", {{"rtpmap", {"0 PCMU/8000", "101 telephone-event/8000"}}}}
            }
        }}
    };

    // 4. Serialize to wire format
    try {
        std::string wireText = sip2json::serialize(msg);
        std::cout << "Serialized SIP Wire Output:\n\n" << wireText << std::endl;
    } catch (const sip2json_exception& e) {
        std::cerr << "Serialization error: " << e.what() << std::endl;
    }

    return 0;
}

For UDP datagrams or pre-framed buffers where exactly one SIP message is expected.

#include <iostream>
#include <string_view>
#include "siddiqsoft/sip2json.hpp"

using namespace siddiqsoft;

int main()
{
    std::string_view datagram = 
        "SIP/2.0 200 OK\r\n"
        "Via: SIP/2.0/UDP 192.168.1.1:5060;branch=z9hG4bK-123\r\n"
        "From: <sip:user@example.com>;tag=111\r\n"
        "To: <sip:user@example.com>;tag=222\r\n"
        "Call-ID: reg-101@192.168.1.1\r\n"
        "CSeq: 1 REGISTER\r\n"
        "Content-Length: 0\r\n\r\n";

    try {
        auto cursor = datagram.begin();
        sipmessage msg = sip2json::parseFromBuffer(cursor, datagram.end());

        std::cout << "Status: " << msg.getResponseCode() << " " << msg.getReason() << "\n"
                  << "Call-ID: " << msg.getCallID() << "\n";
    } catch (const sip2json_exception& e) {
        std::cerr << "Parse failure: " << e.what() << "\n";
    }

    return 0;
}

Because sipmessage subclasses nlohmann::json, it converts natively to JSON documents for queuing into Kafka, RabbitMQ, DuckDB, or MongoDB.

#include <iostream>
#include "siddiqsoft/sip2json.hpp"

using namespace siddiqsoft;

void processSipAsJson(const sipmessage& msg)
{
    // 1. Direct conversion to nlohmann::json
    const nlohmann::json& doc = msg;

    // 2. Query compact metaphor schema: s (startline), h (headers), b (body)
    std::cout << "Method: " << doc["s"]["m"].get<std::string>() << "\n"
              << "CSeq:   " << doc["s"]["cs"].get<uint64_t>() << "\n"
              << "From:   " << doc["h"]["from"].get<std::string>() << "\n";

    // 3. Pretty-print or export
    std::cout << doc.dump(2) << "\n";
}