~singpolyma/biboumi

e8f22efe34415db0e1e5cb94635b089b18efe055 — Florent Le Coz 7 years ago df006a1
XmlNodes are now always closed

Remove the close() method and closed attribute. Remove all the calls to
close().  (Save one bool per XmlNode, yay, and save a few ifs and some
useless function calls. At best it should be unnoticeably faster and lighter
and save a few keystrokes in the future)
M louloulibs/xmpp/adhoc_command.cpp => louloulibs/xmpp/adhoc_command.cpp +0 -10
@@ 25,7 25,6 @@ void PingStep1(XmppComponent*, AdhocSession&, XmlNode& command_node)
  XmlNode note("note");
  note["type"] = "info";
  note.set_inner("Pong");
  note.close();
  command_node.add_child(std::move(note));
}



@@ 35,22 34,17 @@ void HelloStep1(XmppComponent*, AdhocSession&, XmlNode& command_node)
  x["type"] = "form";
  XmlNode title("title");
  title.set_inner("Configure your name.");
  title.close();
  x.add_child(std::move(title));
  XmlNode instructions("instructions");
  instructions.set_inner("Please provide your name.");
  instructions.close();
  x.add_child(std::move(instructions));
  XmlNode name_field("field");
  name_field["var"] = "name";
  name_field["type"] = "text-single";
  name_field["label"] = "Your name";
  XmlNode required("required");
  required.close();
  name_field.add_child(std::move(required));
  name_field.close();
  x.add_child(std::move(name_field));
  x.close();
  command_node.add_child(std::move(x));
}



@@ 75,7 69,6 @@ void HelloStep2(XmppComponent*, AdhocSession& session, XmlNode& command_node)
              XmlNode note("note");
              note["type"] = "info";
              note.set_inner("Hello "s + value->get_inner() + "!"s);
              note.close();
              command_node.delete_all_children();
              command_node.add_child(std::move(note));
              return;


@@ 86,9 79,7 @@ void HelloStep2(XmppComponent*, AdhocSession& session, XmlNode& command_node)
  XmlNode error(ADHOC_NS":error");
  error["type"] = "modify";
  XmlNode condition(STANZA_NS":bad-request");
  condition.close();
  error.add_child(std::move(condition));
  error.close();
  command_node.add_child(std::move(error));
  session.terminate();
}


@@ 100,6 91,5 @@ void Reload(XmppComponent*, AdhocSession&, XmlNode& command_node)
  XmlNode note("note");
  note["type"] = "info";
  note.set_inner("Configuration reloaded.");
  note.close();
  command_node.add_child(std::move(note));
}

M louloulibs/xmpp/adhoc_commands_handler.cpp => louloulibs/xmpp/adhoc_commands_handler.cpp +0 -10
@@ 36,9 36,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, Xm
      XmlNode error(ADHOC_NS":error");
      error["type"] = "cancel";
      XmlNode condition(STANZA_NS":item-not-found");
      condition.close();
      error.add_child(std::move(condition));
      error.close();
      command_node.add_child(std::move(error));
    }
  else if (command_it->second.is_admin_only() &&


@@ 47,9 45,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, Xm
      XmlNode error(ADHOC_NS":error");
      error["type"] = "cancel";
      XmlNode condition(STANZA_NS":forbidden");
      condition.close();
      error.add_child(std::move(condition));
      error.close();
      command_node.add_child(std::move(error));
    }
  else


@@ 72,9 68,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, Xm
          XmlNode error(ADHOC_NS":error");
          error["type"] = "modify";
          XmlNode condition(STANZA_NS":bad-request");
          condition.close();
          error.add_child(std::move(condition));
          error.close();
          command_node.add_child(std::move(error));
        }
      else if (action == "execute" || action == "next" || action == "complete")


@@ 95,9 89,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, Xm
              command_node["status"] = "executing";
              XmlNode actions("actions");
              XmlNode next("next");
              next.close();
              actions.add_child(std::move(next));
              actions.close();
              command_node.add_child(std::move(actions));
            }
        }


@@ 112,9 104,7 @@ XmlNode AdhocCommandsHandler::handle_request(const std::string& executor_jid, Xm
          XmlNode error(ADHOC_NS":error");
          error["type"] = "modify";
          XmlNode condition(STANZA_NS":bad-request");
          condition.close();
          error.add_child(std::move(condition));
          error.close();
          command_node.add_child(std::move(error));
        }
    }

M louloulibs/xmpp/xmpp_component.cpp => louloulibs/xmpp/xmpp_component.cpp +6 -72
@@ 89,12 89,9 @@ void XmppComponent::on_connected()
{
  log_info("connected to XMPP server");
  this->first_connection_try = true;
  XmlNode node("", nullptr);
  node.set_name("stream:stream");
  node["xmlns"] = COMPONENT_NS;
  node["xmlns:stream"] = STREAM_NS;
  node["to"] = this->served_hostname;
  this->send_stanza(node);
  this->send_data("<stream:stream to='");
  this->send_data(std::string{this->served_hostname});
  this->send_data("' xmlns:stream='http://etherx.jabber.org/streams' xmlns='" COMPONENT_NS "'>");
  this->doc_open = true;
  // We may have some pending data to send: this happens when we try to send
  // some data before we are actually connected.  We send that data right now, if any


@@ 152,10 149,9 @@ void XmppComponent::on_remote_stream_open(const XmlNode& node)
    sprintf(digest + (i*2), "%02x", result[i]);
  digest[HASH_LENGTH * 2] = '\0';

  Stanza handshake(COMPONENT_NS":handshake");
  handshake.set_inner(digest);
  handshake.close();
  this->send_stanza(handshake);
  this->send_data("<handshake xmlns='" COMPONENT_NS "'>");
  this->send_data(digest);
  this->send_data("</handshake>");
}

void XmppComponent::on_remote_stream_close(const XmlNode& node)


@@ 192,9 188,7 @@ void XmppComponent::send_stream_error(const std::string& name, const std::string
  error["xmlns"] = STREAM_NS;
  if (!explanation.empty())
    error.set_inner(explanation);
  error.close();
  node.add_child(std::move(error));
  node.close();
  this->send_stanza(node);
}



@@ 220,19 214,15 @@ void XmppComponent::send_stanza_error(const std::string& kind, const std::string
  error["type"] = error_type;
  XmlNode inner_error(defined_condition);
  inner_error["xmlns"] = STANZA_NS;
  inner_error.close();
  error.add_child(std::move(inner_error));
  if (!text.empty())
    {
      XmlNode text_node("text");
      text_node["xmlns"] = STANZA_NS;
      text_node.set_inner(text);
      text_node.close();
      error.add_child(std::move(text_node));
    }
  error.close();
  node.add_child(std::move(error));
  node.close();
  this->send_stanza(node);
}



@@ 295,7 285,6 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con
    node["type"] = type;
  XmlNode body_node("body");
  body_node.set_inner(std::get<0>(body));
  body_node.close();
  node.add_child(std::move(body_node));
  if (std::get<1>(body))
    {


@@ 303,10 292,8 @@ void XmppComponent::send_message(const std::string& from, Xmpp::body&& body, con
      html["xmlns"] = XHTMLIM_NS;
      // Pass the ownership of the pointer to this xmlnode
      html.add_child(std::get<1>(body).release());
      html.close();
      node.add_child(std::move(html));
    }
  node.close();
  this->send_stanza(node);
}



@@ 336,19 323,15 @@ void XmppComponent::send_user_join(const std::string& from,
      if (!preped_jid.empty())
        item["jid"] = preped_jid;
    }
  item.close();
  x.add_child(std::move(item));

  if (self)
    {
      XmlNode status("status");
      status["code"] = "110";
      status.close();
      x.add_child(std::move(status));
    }
  x.close();
  node.add_child(std::move(x));
  node.close();
  this->send_stanza(node);
}



@@ 365,14 348,12 @@ void XmppComponent::send_invalid_room_error(const std::string& muc_name,
  presence["type"] = "error";
  XmlNode x("x");
  x["xmlns"] = MUC_NS;
  x.close();
  presence.add_child(std::move(x));
  XmlNode error("error");
  error["by"] = muc_name + "@" + this->served_hostname;
  error["type"] = "cancel";
  XmlNode item_not_found("item-not-found");
  item_not_found["xmlns"] = STANZA_NS;
  item_not_found.close();
  error.add_child(std::move(item_not_found));
  XmlNode text("text");
  text["xmlns"] = STANZA_NS;


@@ 380,11 361,8 @@ void XmppComponent::send_invalid_room_error(const std::string& muc_name,
  text.set_inner(muc_name +
                 " is not a valid IRC channel name. A correct room jid is of the form: #<chan>%<server>@" +
                 this->served_hostname);
  text.close();
  error.add_child(std::move(text));
  error.close();
  presence.add_child(std::move(error));
  presence.close();
  this->send_stanza(presence);
}



@@ 396,13 374,11 @@ void XmppComponent::send_invalid_user_error(const std::string& user_name, const 
  message["type"] = "error";
  XmlNode x("x");
  x["xmlns"] = MUC_NS;
  x.close();
  message.add_child(std::move(x));
  XmlNode error("error");
  error["type"] = "cancel";
  XmlNode item_not_found("item-not-found");
  item_not_found["xmlns"] = STANZA_NS;
  item_not_found.close();
  error.add_child(std::move(item_not_found));
  XmlNode text("text");
  text["xmlns"] = STANZA_NS;


@@ 410,11 386,8 @@ void XmppComponent::send_invalid_user_error(const std::string& user_name, const 
  text.set_inner(user_name +
                 " is not a valid IRC user name. A correct user jid is of the form: <nick>!<server>@" +
                 this->served_hostname);
  text.close();
  error.add_child(std::move(text));
  error.close();
  message.add_child(std::move(error));
  message.close();
  this->send_stanza(message);
}



@@ 426,9 399,7 @@ void XmppComponent::send_topic(const std::string& from, Xmpp::body&& topic, cons
  message["type"] = "groupchat";
  XmlNode subject("subject");
  subject.set_inner(std::get<0>(topic));
  subject.close();
  message.add_child(std::move(subject));
  message.close();
  this->send_stanza(message);
}



@@ 443,7 414,6 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
  message["type"] = "groupchat";
  XmlNode body("body");
  body.set_inner(std::get<0>(xmpp_body));
  body.close();
  message.add_child(std::move(body));
  if (std::get<1>(xmpp_body))
    {


@@ 451,10 421,8 @@ void XmppComponent::send_muc_message(const std::string& muc_name, const std::str
      html["xmlns"] = XHTMLIM_NS;
      // Pass the ownership of the pointer to this xmlnode
      html.add_child(std::get<1>(xmpp_body).release());
      html.close();
      message.add_child(std::move(html));
    }
  message.close();
  this->send_stanza(message);
}



@@ 471,19 439,15 @@ void XmppComponent::send_muc_leave(const std::string& muc_name, std::string&& ni
    {
      XmlNode status("status");
      status["code"] = "110";
      status.close();
      x.add_child(std::move(status));
    }
  x.close();
  presence.add_child(std::move(x));
  if (!message_str.empty())
    {
      XmlNode status("status");
      status.set_inner(message_str);
      status.close();
      presence.add_child(std::move(status));
    }
  presence.close();
  this->send_stanza(presence);
}



@@ 503,22 467,17 @@ void XmppComponent::send_nick_change(const std::string& muc_name,
  x["xmlns"] = MUC_USER_NS;
  XmlNode item("item");
  item["nick"] = new_nick;
  item.close();
  x.add_child(std::move(item));
  XmlNode status("status");
  status["code"] = "303";
  status.close();
  x.add_child(std::move(status));
  if (self)
    {
      XmlNode status2("status");
      status2["code"] = "110";
      status2.close();
      x.add_child(std::move(status2));
    }
  x.close();
  presence.add_child(std::move(x));
  presence.close();
  this->send_stanza(presence);

  this->send_user_join(muc_name, new_nick, "", affiliation, role, jid_to, self);


@@ 542,21 501,15 @@ void XmppComponent::kick_user(const std::string& muc_name,
  XmlNode actor("actor");
  actor["nick"] = author;
  actor["jid"] = author; // backward compatibility with old clients
  actor.close();
  item.add_child(std::move(actor));
  XmlNode reason("reason");
  reason.set_inner(txt);
  reason.close();
  item.add_child(std::move(reason));
  item.close();
  x.add_child(std::move(item));
  XmlNode status("status");
  status["code"] = "307";
  status.close();
  x.add_child(std::move(status));
  x.close();
  presence.add_child(std::move(x));
  presence.close();
  this->send_stanza(presence);
}



@@ 574,7 527,6 @@ void XmppComponent::send_presence_error(const std::string& muc_name,
  presence["type"] = "error";
  XmlNode x("x");
  x["xmlns"] = MUC_NS;
  x.close();
  presence.add_child(std::move(x));
  XmlNode error("error");
  error["by"] = muc_name + "@" + this->served_hostname;


@@ 583,11 535,8 @@ void XmppComponent::send_presence_error(const std::string& muc_name,
    error["code"] = error_code;
  XmlNode subnode(condition);
  subnode["xmlns"] = STANZA_NS;
  subnode.close();
  error.add_child(std::move(subnode));
  error.close();
  presence.add_child(std::move(error));
  presence.close();
  this->send_stanza(presence);
}



@@ 605,11 554,8 @@ void XmppComponent::send_affiliation_role_change(const std::string& muc_name,
  XmlNode item("item");
  item["affiliation"] = affiliation;
  item["role"] = role;
  item.close();
  x.add_child(std::move(item));
  x.close();
  presence.add_child(std::move(x));
  presence.close();
  this->send_stanza(presence);
}



@@ 627,27 573,21 @@ void XmppComponent::send_version(const std::string& id, const std::string& jid_t
    {
      XmlNode name("name");
      name.set_inner("biboumi");
      name.close();
      query.add_child(std::move(name));
      XmlNode version("version");
      version.set_inner(SOFTWARE_VERSION);
      version.close();
      query.add_child(std::move(version));
      XmlNode os("os");
      os.set_inner(SYSTEM_NAME);
      os.close();
      query.add_child(std::move(os));
    }
  else
    {
      XmlNode name("name");
      name.set_inner(version);
      name.close();
      query.add_child(std::move(name));
    }
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}



@@ 669,12 609,9 @@ void XmppComponent::send_adhoc_commands_list(const std::string& id, const std::s
      item["jid"] = this->served_hostname;
      item["node"] = kv.first;
      item["name"] = kv.second.name;
      item.close();
      query.add_child(std::move(item));
    }
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}



@@ 688,9 625,7 @@ void XmppComponent::send_iq_version_request(const std::string& from,
  iq["to"] = jid_to;
  XmlNode query("query");
  query["xmlns"] = VERSION_NS;
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}



@@ 704,7 639,6 @@ void XmppComponent::send_iq_result(const std::string& id, const std::string& to_
  iq["to"] = to_jid;
  iq["id"] = id;
  iq["type"] = "result";
  iq.close();
  this->send_stanza(iq);
}


M louloulibs/xmpp/xmpp_parser.cpp => louloulibs/xmpp/xmpp_parser.cpp +0 -1
@@ 104,7 104,6 @@ void XmppParser::end_element(const XML_Char* name)
{
  (void)name;
  level--;
  this->current_node->close();
  if (level == 1)
    {
      this->stanza_event(*this->current_node);

M louloulibs/xmpp/xmpp_stanza.cpp => louloulibs/xmpp/xmpp_stanza.cpp +3 -14
@@ 84,8 84,7 @@ std::string xml_unescape(const std::string& data)
}

XmlNode::XmlNode(const std::string& name, XmlNode* parent):
  parent(parent),
  closed(false)
  parent(parent)
{
  // split the namespace and the name
  auto n = name.rfind(":");


@@ 191,13 190,6 @@ XmlNode* XmlNode::get_last_child() const
  return this->children.back();
}

void XmlNode::close()
{
  if (this->closed)
    throw std::runtime_error("Closing an already closed XmlNode");
  this->closed = true;
}

XmlNode* XmlNode::get_parent() const
{
  return this->parent;


@@ 219,17 211,14 @@ std::string XmlNode::to_string() const
  res += this->name;
  for (const auto& it: this->attributes)
    res += " " + it.first + "='" + sanitize(it.second) + "'";
  if (this->closed && !this->has_children() && this->inner.empty())
  if (!this->has_children() && this->inner.empty())
    res += "/>";
  else
    {
      res += ">" + sanitize(this->inner);
      for (const auto& child: this->children)
        res += child->to_string();
      if (this->closed)
        {
          res += "</" + this->get_name() + ">";
        }
      res += "</" + this->get_name() + ">";
    }
  res += sanitize(this->tail);
  return res;

M louloulibs/xmpp/xmpp_stanza.hpp => louloulibs/xmpp/xmpp_stanza.hpp +0 -7
@@ 27,7 27,6 @@ public:
  XmlNode(XmlNode&& node):
    name(std::move(node.name)),
    parent(node.parent),
    closed(node.closed),
    attributes(std::move(node.attributes)),
    children(std::move(node.children)),
    inner(std::move(node.inner)),


@@ 42,7 41,6 @@ public:
  XmlNode(const XmlNode& node):
    name(node.name),
    parent(nullptr),
    closed(node.closed),
    attributes(node.attributes),
    children{},
    inner(node.inner),


@@ 106,10 104,6 @@ public:
   * by calling has_children() for example.
   */
  XmlNode* get_last_child() const;
  /**
   * Mark this node as closed, nothing else
   */
  void close();
  XmlNode* get_parent() const;
  void set_name(const std::string& name);
  const std::string get_name() const;


@@ 140,7 134,6 @@ public:
private:
  std::string name;
  XmlNode* parent;
  bool closed;
  std::unordered_map<std::string, std::string> attributes;
  std::vector<XmlNode*> children;
  std::string inner;

M src/bridge/colors.cpp => src/bridge/colors.cpp +1 -7
@@ 80,7 80,6 @@ Xmpp::body irc_format_to_xhtmlim(const std::string& s)
      else if (s[pos_end] == IRC_FORMAT_NEWLINE_CHAR)
        {
          XmlNode* br_node = new XmlNode("br");
          br_node->close();
          current_node->add_child(br_node);
          cleaned += '\n';
        }


@@ 126,7 125,6 @@ Xmpp::body irc_format_to_xhtmlim(const std::string& s)
      // close opened span, if any
      if (current_node != result.get())
        {
          current_node->close();
          result->add_child(current_node);
          current_node = result.get();
        }


@@ 163,12 161,8 @@ Xmpp::body irc_format_to_xhtmlim(const std::string& s)
    current_node->add_to_inner(txt);

  if (current_node != result.get())
    {
      current_node->close();
      result->add_child(current_node);
    }
    result->add_child(current_node);

  result->close();
  Xmpp::body body_res = std::make_tuple(cleaned, std::move(result));
  return body_res;
}

M src/xmpp/biboumi_adhoc_commands.cpp => src/xmpp/biboumi_adhoc_commands.cpp +0 -12
@@ 10,18 10,15 @@ void DisconnectUserStep1(XmppComponent* xmpp_component, AdhocSession&, XmlNode& 
  x["type"] = "form";
  XmlNode title("title");
  title.set_inner("Disconnect a user from the gateway");
  title.close();
  x.add_child(std::move(title));
  XmlNode instructions("instructions");
  instructions.set_inner("Choose a user JID and a quit message");
  instructions.close();
  x.add_child(std::move(instructions));
  XmlNode jids_field("field");
  jids_field["var"] = "jids";
  jids_field["type"] = "list-multi";
  jids_field["label"] = "The JIDs to disconnect";
  XmlNode required("required");
  required.close();
  jids_field.add_child(std::move(required));
  for (Bridge* bridge: biboumi_component->get_bridges())
    {


@@ 29,12 26,9 @@ void DisconnectUserStep1(XmppComponent* xmpp_component, AdhocSession&, XmlNode& 
      option["label"] = bridge->get_jid();
      XmlNode value("value");
      value.set_inner(bridge->get_jid());
      value.close();
      option.add_child(std::move(value));
      option.close();
      jids_field.add_child(std::move(option));
    }
  jids_field.close();
  x.add_child(std::move(jids_field));

  XmlNode message_field("field");


@@ 43,11 37,8 @@ void DisconnectUserStep1(XmppComponent* xmpp_component, AdhocSession&, XmlNode& 
  message_field["label"] = "Quit message";
  XmlNode message_value("value");
  message_value.set_inner("Disconnected by admin");
  message_value.close();
  message_field.add_child(std::move(message_value));
  message_field.close();
  x.add_child(std::move(message_field));
  x.close();
  command_node.add_child(std::move(x));
}



@@ 95,7 86,6 @@ void DisconnectUserStep2(XmppComponent* xmpp_component, AdhocSession& session, X
            note.set_inner("1 user has been disconnected.");
          else
            note.set_inner(std::to_string(num) + " users have been disconnected.");
          note.close();
          command_node.add_child(std::move(note));
          return;
        }


@@ 103,9 93,7 @@ void DisconnectUserStep2(XmppComponent* xmpp_component, AdhocSession& session, X
  XmlNode error(ADHOC_NS":error");
  error["type"] = "modify";
  XmlNode condition(STANZA_NS":bad-request");
  condition.close();
  error.add_child(std::move(condition));
  error.close();
  command_node.add_child(std::move(error));
  session.terminate();
}

M src/xmpp/biboumi_component.cpp => src/xmpp/biboumi_component.cpp +0 -12
@@ 321,7 321,6 @@ void BiboumiComponent::handle_iq(const Stanza& stanza)
          else
            response["type"] = "result";
          response.add_child(std::move(inner_node));
          response.close();
          this->send_stanza(response);
          stanza_error.disable();
        }


@@ 494,18 493,14 @@ void BiboumiComponent::send_self_disco_info(const std::string& id, const std::st
  identity["category"] = "conference";
  identity["type"] = "irc";
  identity["name"] = "Biboumi XMPP-IRC gateway";
  identity.close();
  query.add_child(std::move(identity));
  for (const std::string& ns: {DISCO_INFO_NS, MUC_NS, ADHOC_NS})
    {
      XmlNode feature("feature");
      feature["var"] = ns;
      feature.close();
      query.add_child(std::move(feature));
    }
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}



@@ 519,9 514,7 @@ void BiboumiComponent::send_iq_version_request(const std::string& from,
  iq["to"] = jid_to;
  XmlNode query("query");
  query["xmlns"] = VERSION_NS;
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}



@@ 536,9 529,7 @@ void BiboumiComponent::send_ping_request(const std::string& from,
  iq["to"] = jid_to;
  XmlNode ping("ping");
  ping["xmlns"] = PING_NS;
  ping.close();
  iq.add_child(std::move(ping));
  iq.close();
  this->send_stanza(iq);

  auto result_cb = [from, id](Bridge* bridge, const Stanza& stanza)


@@ 571,11 562,8 @@ void BiboumiComponent::send_iq_room_list_result(const std::string& id,
    {
      XmlNode item("item");
      item["jid"] = room.channel + "%" + from + "@" + this->served_hostname;
      item.close();
      query.add_child(std::move(item));
    }
  query.close();
  iq.add_child(std::move(query));
  iq.close();
  this->send_stanza(iq);
}