diff --git a/src/im/instant_messaging.cpp b/src/im/instant_messaging.cpp index 685cdd9ca87e1ea4cf98d10e15e3405d04ed727c..17a13105658fd38b3476cad1fd7384d5aca518e4 100644 --- a/src/im/instant_messaging.cpp +++ b/src/im/instant_messaging.cpp @@ -51,35 +51,28 @@ createMessageBody(pj_pool_t* pool, * 2. parse the first result by spliting by '/' into a type and subtype * 3. parse any following strings into arg=value by splitting by '=' */ - - // NOTE: we duplicate all the c_str when creating pj_str_t strings because we're potentially - // working with local vars which might be destroyed before the message is sent and thus the - // the mem they pointed to could be something else at the time the message is actually sent - - std::string mimeType, parameters; + std::string_view mimeType, parameters; auto sep = payload.first.find(';'); if (std::string::npos == sep) { mimeType = payload.first; } else { - mimeType = payload.first.substr(0, sep); - parameters = payload.first.substr(sep + 1); + mimeType = std::string_view(payload.first).substr(0, sep); + parameters = std::string_view(payload.first).substr(sep + 1); } // split mime type to type and subtype sep = mimeType.find('/'); if (std::string::npos == sep) { - JAMI_DBG("bad mime type: '%.30s'", mimeType.c_str()); + JAMI_DBG("bad mime type: '%.*s'", (int) mimeType.size(), mimeType.data()); throw im::InstantMessageException("invalid mime type"); } - const auto& type = mimeType.substr(0, sep); - const auto& subtype = mimeType.substr(sep + 1); + auto type = sip_utils::CONST_PJ_STR(mimeType.substr(0, sep)); + auto subtype = sip_utils::CONST_PJ_STR(mimeType.substr(sep + 1)); + auto message = sip_utils::CONST_PJ_STR(payload.second); // create part - auto type_pj = pj_strdup3(pool, type.c_str()); - auto subtype_pj = pj_strdup3(pool, subtype.c_str()); - auto message_pj = pj_strdup3(pool, payload.second.c_str()); - *body_p = pjsip_msg_body_create(pool, &type_pj, &subtype_pj, &message_pj); + *body_p = pjsip_msg_body_create(pool, &type, &subtype, &message); if (not parameters.size()) return; @@ -87,29 +80,25 @@ createMessageBody(pj_pool_t* pool, // now try to add parameters one by one do { sep = parameters.find(';'); - const auto& paramPair = parameters.substr(0, sep); - if (not paramPair.size()) + auto paramPair = parameters.substr(0, sep); + if (paramPair.empty()) break; // split paramPair into arg and value by '=' auto paramSplit = paramPair.find('='); if (std::string::npos == paramSplit) { - JAMI_DBG("bad parameter: '%.30s'", paramPair.c_str()); + JAMI_DBG("bad parameter: '%.*s'", (int)paramPair.size(), paramPair.data()); throw im::InstantMessageException("invalid parameter"); } - const auto& arg = paramPair.substr(0, paramSplit); - const auto& value = paramPair.substr(paramSplit + 1); - - // add to the body content type - auto arg_pj = pj_strdup3(pool, arg.c_str()); - pj_strtrim(&arg_pj); - auto value_pj = pj_strdup3(pool, value.c_str()); - pj_strtrim(&value_pj); - + auto arg = sip_utils::CONST_PJ_STR(paramPair.substr(0, paramSplit)); + auto value = sip_utils::CONST_PJ_STR(paramPair.substr(paramSplit + 1)); + pj_strtrim(&arg); + pj_strtrim(&value); + pj_str_t arg_pj, value_pj; pjsip_param* param = PJ_POOL_ALLOC_T(pool, pjsip_param); - param->name = arg_pj; - param->value = value_pj; + param->name = *pj_strdup(pool, &arg_pj, &arg); + param->value = *pj_strdup(pool, &value_pj, &value); pj_list_push_back(&(*body_p)->content_type.param, param); // next parameter? @@ -194,26 +183,19 @@ im::sendSipMessage(pjsip_inv_session* session, const std::map<std::string, std:: static std::pair<std::string, std::string> parseMessageBody(const pjsip_msg_body* body) { - const std::string type {body->content_type.type.ptr, (size_t) body->content_type.type.slen}; - const std::string subtype {body->content_type.subtype.ptr, - (size_t) body->content_type.subtype.slen}; - std::string header = type + "/" + subtype; + std::string header = sip_utils::as_view(body->content_type.type) + + "/" + sip_utils::as_view(body->content_type.subtype); // iterate over parameters auto param = body->content_type.param.next; while (param != &body->content_type.param) { - const std::string arg {param->name.ptr, (size_t) param->name.slen}; - const std::string value {param->value.ptr, (size_t) param->value.slen}; - - header += ";" + arg + "=" + value; - + header += ";" + sip_utils::as_view(param->name) + "=" + sip_utils::as_view(param->value); param = param->next; } // get the payload, assume we can interpret it as chars - const std::string payload {static_cast<char*>(body->data), body->len}; - - return std::make_pair(header, payload); + return {std::move(header), + std::string(static_cast<char*>(body->data), (size_t)body->len)}; } /** @@ -239,14 +221,14 @@ im::parseSipMessage(const pjsip_msg* msg) if (pj_strcmp(&typeMultipart, &msg->body->content_type.type) != 0) { // treat as single content type message - ret.insert(parseMessageBody(msg->body)); + ret.emplace(parseMessageBody(msg->body)); } else { /* multipart type message, we will treat it as multipart/mixed even if the subtype is * something else, eg: related */ auto part = pjsip_multipart_get_first_part(msg->body); while (part != nullptr) { - ret.insert(parseMessageBody(part->body)); + ret.emplace(parseMessageBody(part->body)); part = pjsip_multipart_get_next_part(msg->body, part); } }