Pārlūkot izejas kodu

doxygen doc

master
root pirms 5 gadiem
vecāks
revīzija
8cb2a854bb
47 mainītis faili ar 4165 papildinājumiem un 0 dzēšanām
  1. Binārs
      doc/html/bc_s.png
  2. Binārs
      doc/html/bdwn.png
  3. Binārs
      doc/html/closed.png
  4. Binārs
      doc/html/doc.png
  5. 1596
    0
      doc/html/doxygen.css
  6. Binārs
      doc/html/doxygen.png
  7. 97
    0
      doc/html/dynsections.js
  8. Binārs
      doc/html/folderclosed.png
  9. Binārs
      doc/html/folderopen.png
  10. 102
    0
      doc/html/graph_legend.html
  11. 1
    0
      doc/html/graph_legend.md5
  12. Binārs
      doc/html/graph_legend.png
  13. 73
    0
      doc/html/index.html
  14. 87
    0
      doc/html/jquery.js
  15. 133
    0
      doc/html/md_README.html
  16. 26
    0
      doc/html/menu.js
  17. 3
    0
      doc/html/menudata.js
  18. Binārs
      doc/html/nav_f.png
  19. Binārs
      doc/html/nav_g.png
  20. Binārs
      doc/html/nav_h.png
  21. Binārs
      doc/html/open.png
  22. 78
    0
      doc/html/pages.html
  23. 26
    0
      doc/html/search/all_0.html
  24. 4
    0
      doc/html/search/all_0.js
  25. Binārs
      doc/html/search/close.png
  26. Binārs
      doc/html/search/mag_sel.png
  27. 12
    0
      doc/html/search/nomatches.html
  28. 26
    0
      doc/html/search/pages_0.html
  29. 4
    0
      doc/html/search/pages_0.js
  30. 271
    0
      doc/html/search/search.css
  31. 791
    0
      doc/html/search/search.js
  32. Binārs
      doc/html/search/search_l.png
  33. Binārs
      doc/html/search/search_m.png
  34. Binārs
      doc/html/search/search_r.png
  35. 18
    0
      doc/html/search/searchdata.js
  36. Binārs
      doc/html/splitbar.png
  37. Binārs
      doc/html/sync_off.png
  38. Binārs
      doc/html/sync_on.png
  39. Binārs
      doc/html/tab_a.png
  40. Binārs
      doc/html/tab_b.png
  41. Binārs
      doc/html/tab_h.png
  42. Binārs
      doc/html/tab_s.png
  43. 1
    0
      doc/html/tabs.css
  44. 21
    0
      doc/latex/Makefile
  45. 503
    0
      doc/latex/doxygen.sty
  46. 137
    0
      doc/latex/md_README.tex
  47. 155
    0
      doc/latex/refman.tex

Binārs
doc/html/bc_s.png Parādīt failu


Binārs
doc/html/bdwn.png Parādīt failu


Binārs
doc/html/closed.png Parādīt failu


Binārs
doc/html/doc.png Parādīt failu


+ 1596
- 0
doc/html/doxygen.css
Failā izmaiņas netiks attēlotas, jo tās ir par lielu
Parādīt failu


Binārs
doc/html/doxygen.png Parādīt failu


+ 97
- 0
doc/html/dynsections.js Parādīt failu

@@ -0,0 +1,97 @@
function toggleVisibility(linkObj)
{
var base = $(linkObj).attr('id');
var summary = $('#'+base+'-summary');
var content = $('#'+base+'-content');
var trigger = $('#'+base+'-trigger');
var src=$(trigger).attr('src');
if (content.is(':visible')===true) {
content.hide();
summary.show();
$(linkObj).addClass('closed').removeClass('opened');
$(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
content.show();
summary.hide();
$(linkObj).removeClass('closed').addClass('opened');
$(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
}
return false;
}

function updateStripes()
{
$('table.directory tr').
removeClass('even').filter(':visible:even').addClass('even');
}

function toggleLevel(level)
{
$('table.directory tr').each(function() {
var l = this.id.split('_').length-1;
var i = $('#img'+this.id.substring(3));
var a = $('#arr'+this.id.substring(3));
if (l<level+1) {
i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
a.html('&#9660;');
$(this).show();
} else if (l==level+1) {
i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
a.html('&#9658;');
$(this).show();
} else {
$(this).hide();
}
});
updateStripes();
}

function toggleFolder(id)
{
// the clicked row
var currentRow = $('#row_'+id);

// all rows after the clicked row
var rows = currentRow.nextAll("tr");

var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub

// only match elements AFTER this one (can't hide elements before)
var childRows = rows.filter(function() { return this.id.match(re); });

// first row is visible we are HIDING
if (childRows.filter(':first').is(':visible')===true) {
// replace down arrow by right arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
currentRowSpans.filter(".arrow").html('&#9658;');
rows.filter("[id^=row_"+id+"]").hide(); // hide all children
} else { // we are SHOWING
// replace right arrow by down arrow for current row
var currentRowSpans = currentRow.find("span");
currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
currentRowSpans.filter(".arrow").html('&#9660;');
// replace down arrows by right arrows for child rows
var childRowsSpans = childRows.find("span");
childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
childRowsSpans.filter(".arrow").html('&#9658;');
childRows.show(); //show all children
}
updateStripes();
}


function toggleInherit(id)
{
var rows = $('tr.inherit.'+id);
var img = $('tr.inherit_header.'+id+' img');
var src = $(img).attr('src');
if (rows.filter(':first').is(':visible')===true) {
rows.css('display','none');
$(img).attr('src',src.substring(0,src.length-8)+'closed.png');
} else {
rows.css('display','table-row'); // using show() causes jump in firefox
$(img).attr('src',src.substring(0,src.length-10)+'open.png');
}
}


Binārs
doc/html/folderclosed.png Parādīt failu


Binārs
doc/html/folderopen.png Parādīt failu


+ 102
- 0
doc/html/graph_legend.html Parādīt failu

@@ -0,0 +1,102 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>libchat6: Graph Legend</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">libchat6
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
<div class="headertitle">
<div class="title">Graph Legend</div> </div>
</div><!--header-->
<div class="contents">
<p>This page explains how to interpret the graphs that are generated by doxygen.</p>
<p>Consider the following example: </p><div class="fragment"><div class="line">/*! Invisible class because of truncation */</div><div class="line">class Invisible { };</div><div class="line"></div><div class="line">/*! Truncated class, inheritance relation is hidden */</div><div class="line">class Truncated : public Invisible { };</div><div class="line"></div><div class="line">/* Class not documented with doxygen comments */</div><div class="line">class Undocumented { };</div><div class="line"></div><div class="line">/*! Class that is inherited using public inheritance */</div><div class="line">class PublicBase : public Truncated { };</div><div class="line"></div><div class="line">/*! A template class */</div><div class="line">template&lt;class T&gt; class Templ { };</div><div class="line"></div><div class="line">/*! Class that is inherited using protected inheritance */</div><div class="line">class ProtectedBase { };</div><div class="line"></div><div class="line">/*! Class that is inherited using private inheritance */</div><div class="line">class PrivateBase { };</div><div class="line"></div><div class="line">/*! Class that is used by the Inherited class */</div><div class="line">class Used { };</div><div class="line"></div><div class="line">/*! Super class that inherits a number of other classes */</div><div class="line">class Inherited : public PublicBase,</div><div class="line"> protected ProtectedBase,</div><div class="line"> private PrivateBase,</div><div class="line"> public Undocumented,</div><div class="line"> public Templ&lt;int&gt;</div><div class="line">{</div><div class="line"> private:</div><div class="line"> Used *m_usedClass;</div><div class="line">};</div></div><!-- fragment --><p> This will result in the following graph:</p>
<center><div class="image">
<img src="graph_legend.png"/>
</div>
</center><p>The boxes in the above graph have the following meaning: </p>
<ul>
<li>
A filled gray box represents the struct or class for which the graph is generated. </li>
<li>
A box with a black border denotes a documented struct or class. </li>
<li>
A box with a gray border denotes an undocumented struct or class. </li>
<li>
A box with a red border denotes a documented struct or class forwhich not all inheritance/containment relations are shown. A graph is truncated if it does not fit within the specified boundaries. </li>
</ul>
<p>The arrows have the following meaning: </p>
<ul>
<li>
A dark blue arrow is used to visualize a public inheritance relation between two classes. </li>
<li>
A dark green arrow is used for protected inheritance. </li>
<li>
A dark red arrow is used for private inheritance. </li>
<li>
A purple dashed arrow is used if a class is contained or used by another class. The arrow is labelled with the variable(s) through which the pointed class or struct is accessible. </li>
<li>
A yellow dashed arrow denotes a relation between a template instance and the template class it was instantiated from. The arrow is labelled with the template parameters of the instance. </li>
</ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>

+ 1
- 0
doc/html/graph_legend.md5 Parādīt failu

@@ -0,0 +1 @@
387ff8eb65306fa251338d3c9bd7bfff

Binārs
doc/html/graph_legend.png Parādīt failu


+ 73
- 0
doc/html/index.html Parādīt failu

@@ -0,0 +1,73 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>libchat6: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">libchat6
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
<div class="headertitle">
<div class="title">libchat6 Documentation</div> </div>
</div><!--header-->
<div class="contents">
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>

+ 87
- 0
doc/html/jquery.js
Failā izmaiņas netiks attēlotas, jo tās ir par lielu
Parādīt failu


+ 133
- 0
doc/html/md_README.html Parādīt failu

@@ -0,0 +1,133 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>libchat6: libchat6</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">libchat6
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>

</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">libchat6 </div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h2>About</h2>
<p>libchat6 is a complete library that handles an IPv6 only, peer-to-peer, end-to-end encrypted, decentralised, chat client.</p>
<h2>Ideas</h2>
<ul>
<li>Transport is IPv6, but some fallback mechanism to help IPv4 client may be implemented.</li>
<li>all clients are identical and no server is needed (some clients might run to act as bootstrap servers but all clients do that as well.)</li>
<li>clients have a built-in bootstrap list of IPv6 addresses. This list gets updated when the client connects to the network. This allows the client to always have a recent list of bootstraping IPs.</li>
<li>There's no central registration site, therefor users just choose a nickname and have a private/public key pair (generated by the client). Clients are identified by their public key.</li>
<li>Friends can be searched by their nickname or public key. If a client changes the nickname without changing the key pair, the friend can still be found using the public key. This process is completely handled by the library and is transparent to the user. Is a friend changes the key pair, a new friend request will have to be sent.</li>
<li>The interconnection of clients is handled over other clients. The network builds up and paths between clients are calculated similar as a routing protocol for routes. The network is anarchic and no rules, except the protocol, leads it.</li>
<li>A client may connect to multiple clients, the network of clients will adjust the routing paths according to a metric and select the best path. The metric is the delay in miliseconds on each connection. A regular keepalive is used to measure the delay and the routing information is adjusted accordingly.</li>
<li>To avoid dead paths, a relatively short keepalive timeout is used.</li>
<li>The network does not allow store-and-forward of messages. If the friend is offline, messages cannot be send and the client has to store the message until the friend is available. For mobile clients, notifications might be integrated to wakup the client (no clue how? anyone?)</li>
<li>The network allows users to find other users by nickname. Nickname collisions are possible.</li>
<li>Chat groups require to send the message to all the clients.</li>
<li>Each client will randomly add a certain amount of time to its own metric to avoid disclosing its identifiy to any incoming connection.</li>
<li>... ?</li>
</ul>
<h2>Bootstrapping</h2>
<p>To bootstrap a node, a node will have a list of hardcoded nodes and a list of the last known nodes. The hardcoded list is a list of nodes that are put in place by the initiators of this library. Anyone willing to run a permanent node is welcome to contact us to add a node to the hardcoded list.</p>
<h2>Protocol</h2>
<h3>Principles</h3>
<p>A client is the user. A person or a bot using the network to exchange messages. A node is the entity transporting messages for clients. Both are within the same library but use different identities (keypairs). Nodes sending messages to its peer node(s) will use a temporary keypair generated on startup. This keypair changes at every startup and is not stored. A client, on the other side, will generate a keypair once and will use it to generate a temporary keypair for each chat partner to ensure forward secrecy. The temporary keypair is never stored.</p>
<h3>Messages format</h3>
<div class="fragment"><div class="line">&lt;MSGSIGNATURE&gt; &lt;MSGHASH&gt; &lt;TIMESTAMP&gt; &lt;MSGTYPE&gt; [&lt;name&gt;=&lt;value&gt;] ...</div></div><!-- fragment --><ul>
<li>MSGSIGNATURE: An authenticated MSGHASH to prove the origin of the msg. This is signed by the client for client-to-client messages and by the node key for node-to-node messages. The first HELLO message has the signature set to all zeroes.</li>
<li>MSGHASH: A hash of the complete message starting at the timestamp. If the name=value pairs contain a 'metric' option, the hash must be calculated with the metric set to 0.</li>
<li>TIMESTAMP: The timestamp at the creation of the message, formatted "YYYY-mm-dd HH:MM:SS.sss". The timestamp is always in UTC.</li>
<li>MSGTYPE: The msgtime is the type of message that is sent. See below.</li>
<li>name=value: name=value pairs transport all the message informations and vary depending on the msgtype. See description of msgtypes below.</li>
</ul>
<h3>name=value pairs</h3>
<p>NOTE: All 'value' transporting binary or UTF-8 data is represented as base64.</p>
<ul>
<li>chatid: a uuid defining the chat group.</li>
<li>clientkey: the public key of the sending client.</li>
<li>icon: base64 encoded png.</li>
<li>message: a base64 encoded message, encrypted with the target's session key.</li>
<li>metric: a 32 bits unsigned integer representing the sum of all latencies between the client and the announcing client. An originating client will set a random value between 1000 and 2000 to avoid localisation.</li>
<li>msgid: a uuid defining a message unique to a chatid.</li>
<li>mtype: A closed supported list of media types {text, png, jpeg, gif, webm, vcard, ??} (text is always UTF-8)</li>
<li>neighbour: ipv6,port[,ipv4] (IPv4 can be optionally disclosed)</li>
<li>nickname: the nickname chosen by the client (UTF-8 string).</li>
<li>nodekey: the public key of the sending node.</li>
<li>nonce: random bytes, also known as initialisation vector. Must be new for every message.</li>
<li>sessionkey: a session temporary public key.</li>
<li>target_hash: a hash of the target public key. Mainly used for routing.</li>
<li>version: currenlty has the value of 1.</li>
</ul>
<h3>begin and end of session (node-to-node)</h3>
<p>This is the very first message both nodes will send after connecting. The connecting node will send it's HELLO first. If the connected node agrees it will reply with its own HELLO. If it doesn't it will reply with a BYE msg and close the connection. Both nodes may send a BYE message at any time to terminate the connection.</p>
<div class="fragment"><div class="line">HELLO {version,nodekey}</div><div class="line">BYE</div></div><!-- fragment --><h3>path anouncement and withdrawal</h3>
<p>Clients can announce, withdraw or update their presence. A node will keep all client information and inform any new node of the state of all known clients. The metric must be updated when a ONLINE or UPDATE msg is received.</p>
<div class="fragment"><div class="line">CLIENT_ONLINE {clientkey, nickname, icon, metric}</div><div class="line">CLIENT_UPDATE {nonce, nickname, icon, metric}</div><div class="line">CLIENT_OFFLINE</div></div><!-- fragment --><h3>KEEPALIVE</h3>
<p>Keepalive and node-to-node only and are originated by both nodes on a connection. The interval is 15s and if a node doesn't receive a timeout for 30s, it must shutdown the connection. The interval betweeen the request and the response is used to calculate the metric. The metric is caculcated as an average value of the last 10 messages.</p>
<div class="fragment"><div class="line">KEEPALIVE_REQUEST</div><div class="line">KEEPALIVE_RESPONSE</div></div><!-- fragment --><h3>FRIENDS &amp; MESSAGES</h3>
<p>The friend request message has two purposes. First, for a new friend, is will ask the friend to confirm to actually be friends. Secondly, it will exchange temporary session keys. This means that everytime a client comes online and wants to initiate a chat with an existing friend, it will have to send a friend request and get a friend confirm message back in order to exchange new temporary keys. If a friend request from an existing friend comes in, the confim message will automatically be sent back without user confirmation. If the friend is unknown, a user confirmation is required.</p>
<div class="fragment"><div class="line">FRIEND_REQUEST {target_hash, sessionkey}</div><div class="line">FRIEND_CONFIRM {target_hash, sessionkey}</div></div><!-- fragment --><p>client-to-client messages are exchanged using those three message types. Message received and read are only confirmations. A UI may implement a visual aid to show those. Message send, sends a message using the name=value pair 'message'. The message is encrypted using the temporary session key of the friend. Messages must be confirmed received, if they don't, the client will retry sending it after a timeout of 30s until a recv is received or a CLIENT_OFFLINE message is received. Messages can only be sent to online friends. If a friend is offline, the client will have to store the message until the friend is online.</p>
<div class="fragment"><div class="line">MESSAGE_SEND {target_hash, chatid, msgid, mtype, message}</div><div class="line">MESSAGE_RECV {target_hash, chatid, msgid}</div><div class="line">MESSAGE_READ {target_hash, chatid, msgid}</div></div><!-- fragment --><h3>NEIGHBOURS</h3>
<p>In order to discover other nodes, a node may request the directly connected nodes of a neighbor node. The list will be sent back to the requesting node with one or multiple name=value pairs of 'neighbor'. The value is composed of the IP of the node and the TCP port separated by a comma. A neighbor will only be disclosed to another neighbor if it is relaying messages for others (showed more than one CLIENT_ONLINE msg).</p>
<div class="fragment"><div class="line">NEIGHBORS_REQUEST # request the neighbours of your neighbour</div><div class="line">NEIGHBORS_RESPONSE {neighbour,..} # neighbours list, multiple time the same key</div></div><!-- fragment --> </div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>

+ 26
- 0
doc/html/menu.js Parādīt failu

@@ -0,0 +1,26 @@
function initMenu(relPath,searchEnabled,serverSide,searchPage,search) {
function makeTree(data,relPath) {
var result='';
if ('children' in data) {
result+='<ul>';
for (var i in data.children) {
result+='<li><a href="'+relPath+data.children[i].url+'">'+
data.children[i].text+'</a>'+
makeTree(data.children[i],relPath)+'</li>';
}
result+='</ul>';
}
return result;
}

$('#main-nav').append(makeTree(menudata,relPath));
$('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu');
if (searchEnabled) {
if (serverSide) {
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><div class="left"><form id="FSearchBox" action="'+searchPage+'" method="get"><img id="MSearchSelect" src="'+relPath+'search/mag.png" alt=""/><input type="text" id="MSearchField" name="query" value="'+search+'" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)"></form></div><div class="right"></div></div></li>');
} else {
$('#main-menu').append('<li style="float:right"><div id="MSearchBox" class="MSearchBoxInactive"><span class="left"><img id="MSearchSelect" src="'+relPath+'search/mag_sel.png" onmouseover="return searchBox.OnSearchSelectShow()" onmouseout="return searchBox.OnSearchSelectHide()" alt=""/><input type="text" id="MSearchField" value="'+search+'" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" onblur="searchBox.OnSearchFieldFocus(false)" onkeyup="searchBox.OnSearchFieldChange(event)"/></span><span class="right"><a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="'+relPath+'search/close.png" alt=""/></a></span></div></li>');
}
}
$('#main-menu').smartmenus();
}

+ 3
- 0
doc/html/menudata.js Parādīt failu

@@ -0,0 +1,3 @@
var menudata={children:[
{text:"Main Page",url:"index.html"},
{text:"Related Pages",url:"pages.html"}]}

Binārs
doc/html/nav_f.png Parādīt failu


Binārs
doc/html/nav_g.png Parādīt failu


Binārs
doc/html/nav_h.png Parādīt failu


Binārs
doc/html/open.png Parādīt failu


+ 78
- 0
doc/html/pages.html Parādīt failu

@@ -0,0 +1,78 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>libchat6: Related Pages</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">libchat6
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="header">
<div class="headertitle">
<div class="title">Related Pages</div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock">Here is a list of all related documentation pages:</div><div class="directory">
<table class="directory">
<tr id="row_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><a class="el" href="md_README.html" target="_self">libchat6</a></td><td class="desc"></td></tr>
</table>
</div><!-- directory -->
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>

+ 26
- 0
doc/html/search/all_0.html Parādīt failu

@@ -0,0 +1,26 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="all_0.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

+ 4
- 0
doc/html/search/all_0.js Parādīt failu

@@ -0,0 +1,4 @@
var searchData=
[
['libchat6',['libchat6',['../md_README.html',1,'']]]
];

Binārs
doc/html/search/close.png Parādīt failu


Binārs
doc/html/search/mag_sel.png Parādīt failu


+ 12
- 0
doc/html/search/nomatches.html Parādīt failu

@@ -0,0 +1,12 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="NoMatches">No Matches</div>
</div>
</body>
</html>

+ 26
- 0
doc/html/search/pages_0.html Parādīt failu

@@ -0,0 +1,26 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><title></title>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<link rel="stylesheet" type="text/css" href="search.css"/>
<script type="text/javascript" src="pages_0.js"></script>
<script type="text/javascript" src="search.js"></script>
</head>
<body class="SRPage">
<div id="SRIndex">
<div class="SRStatus" id="Loading">Loading...</div>
<div id="SRResults"></div>
<script type="text/javascript"><!--
createResults();
--></script>
<div class="SRStatus" id="Searching">Searching...</div>
<div class="SRStatus" id="NoMatches">No Matches</div>
<script type="text/javascript"><!--
document.getElementById("Loading").style.display="none";
document.getElementById("NoMatches").style.display="none";
var searchResults = new SearchResults("searchResults");
searchResults.Search();
--></script>
</div>
</body>
</html>

+ 4
- 0
doc/html/search/pages_0.js Parādīt failu

@@ -0,0 +1,4 @@
var searchData=
[
['libchat6',['libchat6',['../md_README.html',1,'']]]
];

+ 271
- 0
doc/html/search/search.css Parādīt failu

@@ -0,0 +1,271 @@
/*---------------- Search Box */

#FSearchBox {
float: left;
}

#MSearchBox {
white-space : nowrap;
float: none;
margin-top: 8px;
right: 0px;
width: 170px;
height: 24px;
z-index: 102;
}

#MSearchBox .left
{
display:block;
position:absolute;
left:10px;
width:20px;
height:19px;
background:url('search_l.png') no-repeat;
background-position:right;
}

#MSearchSelect {
display:block;
position:absolute;
width:20px;
height:19px;
}

.left #MSearchSelect {
left:4px;
}

.right #MSearchSelect {
right:5px;
}

#MSearchField {
display:block;
position:absolute;
height:19px;
background:url('search_m.png') repeat-x;
border:none;
width:115px;
margin-left:20px;
padding-left:4px;
color: #909090;
outline: none;
font: 9pt Arial, Verdana, sans-serif;
-webkit-border-radius: 0px;
}

#FSearchBox #MSearchField {
margin-left:15px;
}

#MSearchBox .right {
display:block;
position:absolute;
right:10px;
top:8px;
width:20px;
height:19px;
background:url('search_r.png') no-repeat;
background-position:left;
}

#MSearchClose {
display: none;
position: absolute;
top: 4px;
background : none;
border: none;
margin: 0px 4px 0px 0px;
padding: 0px 0px;
outline: none;
}

.left #MSearchClose {
left: 6px;
}

.right #MSearchClose {
right: 2px;
}

.MSearchBoxActive #MSearchField {
color: #000000;
}

/*---------------- Search filter selection */

#MSearchSelectWindow {
display: none;
position: absolute;
left: 0; top: 0;
border: 1px solid #90A5CE;
background-color: #F9FAFC;
z-index: 10001;
padding-top: 4px;
padding-bottom: 4px;
-moz-border-radius: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
}

.SelectItem {
font: 8pt Arial, Verdana, sans-serif;
padding-left: 2px;
padding-right: 12px;
border: 0px;
}

span.SelectionMark {
margin-right: 4px;
font-family: monospace;
outline-style: none;
text-decoration: none;
}

a.SelectItem {
display: block;
outline-style: none;
color: #000000;
text-decoration: none;
padding-left: 6px;
padding-right: 12px;
}

a.SelectItem:focus,
a.SelectItem:active {
color: #000000;
outline-style: none;
text-decoration: none;
}

a.SelectItem:hover {
color: #FFFFFF;
background-color: #3D578C;
outline-style: none;
text-decoration: none;
cursor: pointer;
display: block;
}

/*---------------- Search results window */

iframe#MSearchResults {
width: 60ex;
height: 15em;
}

#MSearchResultsWindow {
display: none;
position: absolute;
left: 0; top: 0;
border: 1px solid #000;
background-color: #EEF1F7;
z-index:10000;
}

/* ----------------------------------- */


#SRIndex {
clear:both;
padding-bottom: 15px;
}

.SREntry {
font-size: 10pt;
padding-left: 1ex;
}

.SRPage .SREntry {
font-size: 8pt;
padding: 1px 5px;
}

body.SRPage {
margin: 5px 2px;
}

.SRChildren {
padding-left: 3ex; padding-bottom: .5em
}

.SRPage .SRChildren {
display: none;
}

.SRSymbol {
font-weight: bold;
color: #425E97;
font-family: Arial, Verdana, sans-serif;
text-decoration: none;
outline: none;
}

a.SRScope {
display: block;
color: #425E97;
font-family: Arial, Verdana, sans-serif;
text-decoration: none;
outline: none;
}

a.SRSymbol:focus, a.SRSymbol:active,
a.SRScope:focus, a.SRScope:active {
text-decoration: underline;
}

span.SRScope {
padding-left: 4px;
}

.SRPage .SRStatus {
padding: 2px 5px;
font-size: 8pt;
font-style: italic;
}

.SRResult {
display: none;
}

DIV.searchresults {
margin-left: 10px;
margin-right: 10px;
}

/*---------------- External search page results */

.searchresult {
background-color: #F0F3F8;
}

.pages b {
color: white;
padding: 5px 5px 3px 5px;
background-image: url("../tab_a.png");
background-repeat: repeat-x;
text-shadow: 0 1px 1px #000000;
}

.pages {
line-height: 17px;
margin-left: 4px;
text-decoration: none;
}

.hl {
font-weight: bold;
}

#searchresults {
margin-bottom: 20px;
}

.searchpages {
margin-top: 10px;
}


+ 791
- 0
doc/html/search/search.js Parādīt failu

@@ -0,0 +1,791 @@
function convertToId(search)
{
var result = '';
for (i=0;i<search.length;i++)
{
var c = search.charAt(i);
var cn = c.charCodeAt(0);
if (c.match(/[a-z0-9\u0080-\uFFFF]/))
{
result+=c;
}
else if (cn<16)
{
result+="_0"+cn.toString(16);
}
else
{
result+="_"+cn.toString(16);
}
}
return result;
}

function getXPos(item)
{
var x = 0;
if (item.offsetWidth)
{
while (item && item!=document.body)
{
x += item.offsetLeft;
item = item.offsetParent;
}
}
return x;
}

function getYPos(item)
{
var y = 0;
if (item.offsetWidth)
{
while (item && item!=document.body)
{
y += item.offsetTop;
item = item.offsetParent;
}
}
return y;
}

/* A class handling everything associated with the search panel.

Parameters:
name - The name of the global variable that will be
storing this instance. Is needed to be able to set timeouts.
resultPath - path to use for external files
*/
function SearchBox(name, resultsPath, inFrame, label)
{
if (!name || !resultsPath) { alert("Missing parameters to SearchBox."); }

// ---------- Instance variables
this.name = name;
this.resultsPath = resultsPath;
this.keyTimeout = 0;
this.keyTimeoutLength = 500;
this.closeSelectionTimeout = 300;
this.lastSearchValue = "";
this.lastResultsPage = "";
this.hideTimeout = 0;
this.searchIndex = 0;
this.searchActive = false;
this.insideFrame = inFrame;
this.searchLabel = label;

// ----------- DOM Elements

this.DOMSearchField = function()
{ return document.getElementById("MSearchField"); }

this.DOMSearchSelect = function()
{ return document.getElementById("MSearchSelect"); }

this.DOMSearchSelectWindow = function()
{ return document.getElementById("MSearchSelectWindow"); }

this.DOMPopupSearchResults = function()
{ return document.getElementById("MSearchResults"); }

this.DOMPopupSearchResultsWindow = function()
{ return document.getElementById("MSearchResultsWindow"); }

this.DOMSearchClose = function()
{ return document.getElementById("MSearchClose"); }

this.DOMSearchBox = function()
{ return document.getElementById("MSearchBox"); }

// ------------ Event Handlers

// Called when focus is added or removed from the search field.
this.OnSearchFieldFocus = function(isActive)
{
this.Activate(isActive);
}

this.OnSearchSelectShow = function()
{
var searchSelectWindow = this.DOMSearchSelectWindow();
var searchField = this.DOMSearchSelect();

if (this.insideFrame)
{
var left = getXPos(searchField);
var top = getYPos(searchField);
left += searchField.offsetWidth + 6;
top += searchField.offsetHeight;

// show search selection popup
searchSelectWindow.style.display='block';
left -= searchSelectWindow.offsetWidth;
searchSelectWindow.style.left = left + 'px';
searchSelectWindow.style.top = top + 'px';
}
else
{
var left = getXPos(searchField);
var top = getYPos(searchField);
top += searchField.offsetHeight;

// show search selection popup
searchSelectWindow.style.display='block';
searchSelectWindow.style.left = left + 'px';
searchSelectWindow.style.top = top + 'px';
}

// stop selection hide timer
if (this.hideTimeout)
{
clearTimeout(this.hideTimeout);
this.hideTimeout=0;
}
return false; // to avoid "image drag" default event
}

this.OnSearchSelectHide = function()
{
this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
this.closeSelectionTimeout);
}

// Called when the content of the search field is changed.
this.OnSearchFieldChange = function(evt)
{
if (this.keyTimeout) // kill running timer
{
clearTimeout(this.keyTimeout);
this.keyTimeout = 0;
}

var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==40 || e.keyCode==13)
{
if (e.shiftKey==1)
{
this.OnSearchSelectShow();
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
child.focus();
return;
}
}
return;
}
else if (window.frames.MSearchResults.searchResults)
{
var elem = window.frames.MSearchResults.searchResults.NavNext(0);
if (elem) elem.focus();
}
}
else if (e.keyCode==27) // Escape out of the search field
{
this.DOMSearchField().blur();
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.lastSearchValue = '';
this.Activate(false);
return;
}

// strip whitespaces
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");

if (searchValue != this.lastSearchValue) // search value has changed
{
if (searchValue != "") // non-empty search
{
// set timer for search update
this.keyTimeout = setTimeout(this.name + '.Search()',
this.keyTimeoutLength);
}
else // empty search field
{
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.lastSearchValue = '';
}
}
}

this.SelectItemCount = function(id)
{
var count=0;
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
count++;
}
}
return count;
}

this.SelectItemSet = function(id)
{
var i,j=0;
var win=this.DOMSearchSelectWindow();
for (i=0;i<win.childNodes.length;i++)
{
var child = win.childNodes[i]; // get span within a
if (child.className=='SelectItem')
{
var node = child.firstChild;
if (j==id)
{
node.innerHTML='&#8226;';
}
else
{
node.innerHTML='&#160;';
}
j++;
}
}
}

// Called when an search filter selection is made.
// set item with index id as the active item
this.OnSelectItem = function(id)
{
this.searchIndex = id;
this.SelectItemSet(id);
var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
if (searchValue!="" && this.searchActive) // something was found -> do a search
{
this.Search();
}
}

this.OnSearchSelectKey = function(evt)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
{
this.searchIndex++;
this.OnSelectItem(this.searchIndex);
}
else if (e.keyCode==38 && this.searchIndex>0) // Up
{
this.searchIndex--;
this.OnSelectItem(this.searchIndex);
}
else if (e.keyCode==13 || e.keyCode==27)
{
this.OnSelectItem(this.searchIndex);
this.CloseSelectionWindow();
this.DOMSearchField().focus();
}
return false;
}

// --------- Actions

// Closes the results window.
this.CloseResultsWindow = function()
{
this.DOMPopupSearchResultsWindow().style.display = 'none';
this.DOMSearchClose().style.display = 'none';
this.Activate(false);
}

this.CloseSelectionWindow = function()
{
this.DOMSearchSelectWindow().style.display = 'none';
}

// Performs a search.
this.Search = function()
{
this.keyTimeout = 0;

// strip leading whitespace
var searchValue = this.DOMSearchField().value.replace(/^ +/, "");

var code = searchValue.toLowerCase().charCodeAt(0);
var idxChar = searchValue.substr(0, 1).toLowerCase();
if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
{
idxChar = searchValue.substr(0, 2);
}

var resultsPage;
var resultsPageWithSearch;
var hasResultsPage;

var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
if (idx!=-1)
{
var hexCode=idx.toString(16);
resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html';
resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
hasResultsPage = true;
}
else // nothing available for this search term
{
resultsPage = this.resultsPath + '/nomatches.html';
resultsPageWithSearch = resultsPage;
hasResultsPage = false;
}

window.frames.MSearchResults.location = resultsPageWithSearch;
var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();

if (domPopupSearchResultsWindow.style.display!='block')
{
var domSearchBox = this.DOMSearchBox();
this.DOMSearchClose().style.display = 'inline';
if (this.insideFrame)
{
var domPopupSearchResults = this.DOMPopupSearchResults();
domPopupSearchResultsWindow.style.position = 'relative';
domPopupSearchResultsWindow.style.display = 'block';
var width = document.body.clientWidth - 8; // the -8 is for IE :-(
domPopupSearchResultsWindow.style.width = width + 'px';
domPopupSearchResults.style.width = width + 'px';
}
else
{
var domPopupSearchResults = this.DOMPopupSearchResults();
var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
var top = getYPos(domSearchBox) + 20; // domSearchBox.offsetHeight + 1;
domPopupSearchResultsWindow.style.display = 'block';
left -= domPopupSearchResults.offsetWidth;
domPopupSearchResultsWindow.style.top = top + 'px';
domPopupSearchResultsWindow.style.left = left + 'px';
}
}

this.lastSearchValue = searchValue;
this.lastResultsPage = resultsPage;
}

// -------- Activation Functions

// Activates or deactivates the search panel, resetting things to
// their default values if necessary.
this.Activate = function(isActive)
{
if (isActive || // open it
this.DOMPopupSearchResultsWindow().style.display == 'block'
)
{
this.DOMSearchBox().className = 'MSearchBoxActive';

var searchField = this.DOMSearchField();

if (searchField.value == this.searchLabel) // clear "Search" term upon entry
{
searchField.value = '';
this.searchActive = true;
}
}
else if (!isActive) // directly remove the panel
{
this.DOMSearchBox().className = 'MSearchBoxInactive';
this.DOMSearchField().value = this.searchLabel;
this.searchActive = false;
this.lastSearchValue = ''
this.lastResultsPage = '';
}
}
}

// -----------------------------------------------------------------------

// The class that handles everything on the search results page.
function SearchResults(name)
{
// The number of matches from the last run of <Search()>.
this.lastMatchCount = 0;
this.lastKey = 0;
this.repeatOn = false;

// Toggles the visibility of the passed element ID.
this.FindChildElement = function(id)
{
var parentElement = document.getElementById(id);
var element = parentElement.firstChild;

while (element && element!=parentElement)
{
if (element.nodeName == 'DIV' && element.className == 'SRChildren')
{
return element;
}

if (element.nodeName == 'DIV' && element.hasChildNodes())
{
element = element.firstChild;
}
else if (element.nextSibling)
{
element = element.nextSibling;
}
else
{
do
{
element = element.parentNode;
}
while (element && element!=parentElement && !element.nextSibling);

if (element && element!=parentElement)
{
element = element.nextSibling;
}
}
}
}

this.Toggle = function(id)
{
var element = this.FindChildElement(id);
if (element)
{
if (element.style.display == 'block')
{
element.style.display = 'none';
}
else
{
element.style.display = 'block';
}
}
}

// Searches for the passed string. If there is no parameter,
// it takes it from the URL query.
//
// Always returns true, since other documents may try to call it
// and that may or may not be possible.
this.Search = function(search)
{
if (!search) // get search word from URL
{
search = window.location.search;
search = search.substring(1); // Remove the leading '?'
search = unescape(search);
}

search = search.replace(/^ +/, ""); // strip leading spaces
search = search.replace(/ +$/, ""); // strip trailing spaces
search = search.toLowerCase();
search = convertToId(search);

var resultRows = document.getElementsByTagName("div");
var matches = 0;

var i = 0;
while (i < resultRows.length)
{
var row = resultRows.item(i);
if (row.className == "SRResult")
{
var rowMatchName = row.id.toLowerCase();
rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'

if (search.length<=rowMatchName.length &&
rowMatchName.substr(0, search.length)==search)
{
row.style.display = 'block';
matches++;
}
else
{
row.style.display = 'none';
}
}
i++;
}
document.getElementById("Searching").style.display='none';
if (matches == 0) // no results
{
document.getElementById("NoMatches").style.display='block';
}
else // at least one result
{
document.getElementById("NoMatches").style.display='none';
}
this.lastMatchCount = matches;
return true;
}

// return the first item with index index or higher that is visible
this.NavNext = function(index)
{
var focusItem;
while (1)
{
var focusName = 'Item'+index;
focusItem = document.getElementById(focusName);
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
{
break;
}
else if (!focusItem) // last element
{
break;
}
focusItem=null;
index++;
}
return focusItem;
}

this.NavPrev = function(index)
{
var focusItem;
while (1)
{
var focusName = 'Item'+index;
focusItem = document.getElementById(focusName);
if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
{
break;
}
else if (!focusItem) // last element
{
break;
}
focusItem=null;
index--;
}
return focusItem;
}

this.ProcessKeys = function(e)
{
if (e.type == "keydown")
{
this.repeatOn = false;
this.lastKey = e.keyCode;
}
else if (e.type == "keypress")
{
if (!this.repeatOn)
{
if (this.lastKey) this.repeatOn = true;
return false; // ignore first keypress after keydown
}
}
else if (e.type == "keyup")
{
this.lastKey = 0;
this.repeatOn = false;
}
return this.lastKey!=0;
}

this.Nav = function(evt,itemIndex)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==13) return true;
if (!this.ProcessKeys(e)) return false;

if (this.lastKey==38) // Up
{
var newIndex = itemIndex-1;
var focusItem = this.NavPrev(newIndex);
if (focusItem)
{
var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
if (child && child.style.display == 'block') // children visible
{
var n=0;
var tmpElem;
while (1) // search for last child
{
tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
if (tmpElem)
{
focusItem = tmpElem;
}
else // found it!
{
break;
}
n++;
}
}
}
if (focusItem)
{
focusItem.focus();
}
else // return focus to search field
{
parent.document.getElementById("MSearchField").focus();
}
}
else if (this.lastKey==40) // Down
{
var newIndex = itemIndex+1;
var focusItem;
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem && elem.style.display == 'block') // children visible
{
focusItem = document.getElementById('Item'+itemIndex+'_c0');
}
if (!focusItem) focusItem = this.NavNext(newIndex);
if (focusItem) focusItem.focus();
}
else if (this.lastKey==39) // Right
{
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem) elem.style.display = 'block';
}
else if (this.lastKey==37) // Left
{
var item = document.getElementById('Item'+itemIndex);
var elem = this.FindChildElement(item.parentNode.parentNode.id);
if (elem) elem.style.display = 'none';
}
else if (this.lastKey==27) // Escape
{
parent.searchBox.CloseResultsWindow();
parent.document.getElementById("MSearchField").focus();
}
else if (this.lastKey==13) // Enter
{
return true;
}
return false;
}

this.NavChild = function(evt,itemIndex,childIndex)
{
var e = (evt) ? evt : window.event; // for IE
if (e.keyCode==13) return true;
if (!this.ProcessKeys(e)) return false;

if (this.lastKey==38) // Up
{
if (childIndex>0)
{
var newIndex = childIndex-1;
document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
}
else // already at first child, jump to parent
{
document.getElementById('Item'+itemIndex).focus();
}
}
else if (this.lastKey==40) // Down
{
var newIndex = childIndex+1;
var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
if (!elem) // last child, jump to parent next parent
{
elem = this.NavNext(itemIndex+1);
}
if (elem)
{
elem.focus();
}
}
else if (this.lastKey==27) // Escape
{
parent.searchBox.CloseResultsWindow();
parent.document.getElementById("MSearchField").focus();
}
else if (this.lastKey==13) // Enter
{
return true;
}
return false;
}
}

function setKeyActions(elem,action)
{
elem.setAttribute('onkeydown',action);
elem.setAttribute('onkeypress',action);
elem.setAttribute('onkeyup',action);
}

function setClassAttr(elem,attr)
{
elem.setAttribute('class',attr);
elem.setAttribute('className',attr);
}

function createResults()
{
var results = document.getElementById("SRResults");
for (var e=0; e<searchData.length; e++)
{
var id = searchData[e][0];
var srResult = document.createElement('div');
srResult.setAttribute('id','SR_'+id);
setClassAttr(srResult,'SRResult');
var srEntry = document.createElement('div');
setClassAttr(srEntry,'SREntry');
var srLink = document.createElement('a');
srLink.setAttribute('id','Item'+e);
setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
setClassAttr(srLink,'SRSymbol');
srLink.innerHTML = searchData[e][1][0];
srEntry.appendChild(srLink);
if (searchData[e][1].length==2) // single result
{
srLink.setAttribute('href',searchData[e][1][1][0]);
if (searchData[e][1][1][1])
{
srLink.setAttribute('target','_parent');
}
var srScope = document.createElement('span');
setClassAttr(srScope,'SRScope');
srScope.innerHTML = searchData[e][1][1][2];
srEntry.appendChild(srScope);
}
else // multiple results
{
srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
var srChildren = document.createElement('div');
setClassAttr(srChildren,'SRChildren');
for (var c=0; c<searchData[e][1].length-1; c++)
{
var srChild = document.createElement('a');
srChild.setAttribute('id','Item'+e+'_c'+c);
setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
setClassAttr(srChild,'SRScope');
srChild.setAttribute('href',searchData[e][1][c+1][0]);
if (searchData[e][1][c+1][1])
{
srChild.setAttribute('target','_parent');
}
srChild.innerHTML = searchData[e][1][c+1][2];
srChildren.appendChild(srChild);
}
srEntry.appendChild(srChildren);
}
srResult.appendChild(srEntry);
results.appendChild(srResult);
}
}

function init_search()
{
var results = document.getElementById("MSearchSelectWindow");
for (var key in indexSectionLabels)
{
var link = document.createElement('a');
link.setAttribute('class','SelectItem');
link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
link.href='javascript:void(0)';
link.innerHTML='<span class="SelectionMark">&#160;</span>'+indexSectionLabels[key];
results.appendChild(link);
}
searchBox.OnSelectItem(0);
}


Binārs
doc/html/search/search_l.png Parādīt failu


Binārs
doc/html/search/search_m.png Parādīt failu


Binārs
doc/html/search/search_r.png Parādīt failu


+ 18
- 0
doc/html/search/searchdata.js Parādīt failu

@@ -0,0 +1,18 @@
var indexSectionsWithContent =
{
0: "l",
1: "l"
};

var indexSectionNames =
{
0: "all",
1: "pages"
};

var indexSectionLabels =
{
0: "All",
1: "Pages"
};


Binārs
doc/html/splitbar.png Parādīt failu


Binārs
doc/html/sync_off.png Parādīt failu


Binārs
doc/html/sync_on.png Parādīt failu


Binārs
doc/html/tab_a.png Parādīt failu


Binārs
doc/html/tab_b.png Parādīt failu


Binārs
doc/html/tab_h.png Parādīt failu


Binārs
doc/html/tab_s.png Parādīt failu


+ 1
- 0
doc/html/tabs.css
Failā izmaiņas netiks attēlotas, jo tās ir par lielu
Parādīt failu


+ 21
- 0
doc/latex/Makefile Parādīt failu

@@ -0,0 +1,21 @@
all: refman.pdf

pdf: refman.pdf

refman.pdf: clean refman.tex
pdflatex refman
makeindex refman.idx
pdflatex refman
latex_count=8 ; \
while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\
do \
echo "Rerunning latex...." ;\
pdflatex refman ;\
latex_count=`expr $$latex_count - 1` ;\
done
makeindex refman.idx
pdflatex refman


clean:
rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out *.brf *.blg *.bbl refman.pdf

+ 503
- 0
doc/latex/doxygen.sty Parādīt failu

@@ -0,0 +1,503 @@
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{doxygen}

% Packages used by this style file
\RequirePackage{alltt}
\RequirePackage{array}
\RequirePackage{calc}
\RequirePackage{float}
\RequirePackage{ifthen}
\RequirePackage{verbatim}
\RequirePackage[table]{xcolor}
\RequirePackage{longtable}
\RequirePackage{tabu}
\RequirePackage{tabularx}
\RequirePackage{multirow}

%---------- Internal commands used in this style file ----------------

\newcommand{\ensurespace}[1]{%
\begingroup%
\setlength{\dimen@}{#1}%
\vskip\z@\@plus\dimen@%
\penalty -100\vskip\z@\@plus -\dimen@%
\vskip\dimen@%
\penalty 9999%
\vskip -\dimen@%
\vskip\z@skip% hide the previous |\vskip| from |\addvspace|
\endgroup%
}

\newcommand{\DoxyLabelFont}{}
\newcommand{\entrylabel}[1]{%
{%
\parbox[b]{\labelwidth-4pt}{%
\makebox[0pt][l]{\DoxyLabelFont#1}%
\vspace{1.5\baselineskip}%
}%
}%
}

\newenvironment{DoxyDesc}[1]{%
\ensurespace{4\baselineskip}%
\begin{list}{}{%
\settowidth{\labelwidth}{20pt}%
\setlength{\parsep}{0pt}%
\setlength{\itemsep}{0pt}%
\setlength{\leftmargin}{\labelwidth+\labelsep}%
\renewcommand{\makelabel}{\entrylabel}%
}%
\item[#1]%
}{%
\end{list}%
}

\newsavebox{\xrefbox}
\newlength{\xreflength}
\newcommand{\xreflabel}[1]{%
\sbox{\xrefbox}{#1}%
\setlength{\xreflength}{\wd\xrefbox}%
\ifthenelse{\xreflength>\labelwidth}{%
\begin{minipage}{\textwidth}%
\setlength{\parindent}{0pt}%
\hangindent=15pt\bfseries #1\vspace{1.2\itemsep}%
\end{minipage}%
}{%
\parbox[b]{\labelwidth}{\makebox[0pt][l]{\textbf{#1}}}%
}%
}

%---------- Commands used by doxygen LaTeX output generator ----------

% Used by <pre> ... </pre>
\newenvironment{DoxyPre}{%
\small%
\begin{alltt}%
}{%
\end{alltt}%
\normalsize%
}

% Used by @code ... @endcode
\newenvironment{DoxyCode}{%
\par%
\scriptsize%
\begin{alltt}%
}{%
\end{alltt}%
\normalsize%
}

% Used by @example, @include, @includelineno and @dontinclude
\newenvironment{DoxyCodeInclude}{%
\DoxyCode%
}{%
\endDoxyCode%
}

% Used by @verbatim ... @endverbatim
\newenvironment{DoxyVerb}{%
\footnotesize%
\verbatim%
}{%
\endverbatim%
\normalsize%
}

% Used by @verbinclude
\newenvironment{DoxyVerbInclude}{%
\DoxyVerb%
}{%
\endDoxyVerb%
}

% Used by numbered lists (using '-#' or <ol> ... </ol>)
\newenvironment{DoxyEnumerate}{%
\enumerate%
}{%
\endenumerate%
}

% Used by bullet lists (using '-', @li, @arg, or <ul> ... </ul>)
\newenvironment{DoxyItemize}{%
\itemize%
}{%
\enditemize%
}

% Used by description lists (using <dl> ... </dl>)
\newenvironment{DoxyDescription}{%
\description%
}{%
\enddescription%
}

% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
% (only if caption is specified)
\newenvironment{DoxyImage}{%
\begin{figure}[H]%
\begin{center}%
}{%
\end{center}%
\end{figure}%
}

% Used by @image, @dotfile, @dot ... @enddot, and @msc ... @endmsc
% (only if no caption is specified)
\newenvironment{DoxyImageNoCaption}{%
\begin{center}%
}{%
\end{center}%
}

% Used by @attention
\newenvironment{DoxyAttention}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @author and @authors
\newenvironment{DoxyAuthor}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @date
\newenvironment{DoxyDate}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @invariant
\newenvironment{DoxyInvariant}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @note
\newenvironment{DoxyNote}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @post
\newenvironment{DoxyPostcond}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @pre
\newenvironment{DoxyPrecond}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @copyright
\newenvironment{DoxyCopyright}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @remark
\newenvironment{DoxyRemark}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @return and @returns
\newenvironment{DoxyReturn}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @since
\newenvironment{DoxySince}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @see
\newenvironment{DoxySeeAlso}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @version
\newenvironment{DoxyVersion}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @warning
\newenvironment{DoxyWarning}[1]{%
\begin{DoxyDesc}{#1}%
}{%
\end{DoxyDesc}%
}

% Used by @internal
\newenvironment{DoxyInternal}[1]{%
\paragraph*{#1}%
}{%
}

% Used by @par and @paragraph
\newenvironment{DoxyParagraph}[1]{%
\begin{list}{}{%
\settowidth{\labelwidth}{40pt}%
\setlength{\leftmargin}{\labelwidth}%
\setlength{\parsep}{0pt}%
\setlength{\itemsep}{-4pt}%
\renewcommand{\makelabel}{\entrylabel}%
}%
\item[#1]%
}{%
\end{list}%
}

% Used by parameter lists
\newenvironment{DoxyParams}[2][]{%
\tabulinesep=1mm%
\par%
\ifthenelse{\equal{#1}{}}%
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|}}% name + description
{\ifthenelse{\equal{#1}{1}}%
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + name + desc
{\begin{longtabu} spread 0pt [l]{|X[-1,l]|X[-1,l]|X[-1,l]|X[-1,l]|}}% in/out + type + name + desc
}
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #2}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used for fields of simple structs
\newenvironment{DoxyFields}[1]{%
\tabulinesep=1mm%
\par%
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|X[-1,l]|}%
\multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{3}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used for fields simple class style enums
\newenvironment{DoxyEnumFields}[1]{%
\tabulinesep=1mm%
\par%
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used for parameters within a detailed function description
\newenvironment{DoxyParamCaption}{%
\renewcommand{\item}[2][]{\\ \hspace*{2.0cm} ##1 {\em ##2}}%
}{%
}

% Used by return value lists
\newenvironment{DoxyRetVals}[1]{%
\tabulinesep=1mm%
\par%
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used by exception lists
\newenvironment{DoxyExceptions}[1]{%
\tabulinesep=1mm%
\par%
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used by template parameter lists
\newenvironment{DoxyTemplParams}[1]{%
\tabulinesep=1mm%
\par%
\begin{longtabu} spread 0pt [l]{|X[-1,r]|X[-1,l]|}%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endfirsthead%
\multicolumn{2}{l}{\hspace{-6pt}\bfseries\fontseries{bc}\selectfont\color{darkgray} #1}\\[1ex]%
\hline%
\endhead%
}{%
\end{longtabu}%
\vspace{6pt}%
}

% Used for member lists
\newenvironment{DoxyCompactItemize}{%
\begin{itemize}%
\setlength{\itemsep}{-3pt}%
\setlength{\parsep}{0pt}%
\setlength{\topsep}{0pt}%
\setlength{\partopsep}{0pt}%
}{%
\end{itemize}%
}

% Used for member descriptions
\newenvironment{DoxyCompactList}{%
\begin{list}{}{%
\setlength{\leftmargin}{0.5cm}%
\setlength{\itemsep}{0pt}%
\setlength{\parsep}{0pt}%
\setlength{\topsep}{0pt}%
\renewcommand{\makelabel}{\hfill}%
}%
}{%
\end{list}%
}

% Used for reference lists (@bug, @deprecated, @todo, etc.)
\newenvironment{DoxyRefList}{%
\begin{list}{}{%
\setlength{\labelwidth}{10pt}%
\setlength{\leftmargin}{\labelwidth}%
\addtolength{\leftmargin}{\labelsep}%
\renewcommand{\makelabel}{\xreflabel}%
}%
}{%
\end{list}%
}

% Used by @bug, @deprecated, @todo, etc.
\newenvironment{DoxyRefDesc}[1]{%
\begin{list}{}{%
\renewcommand\makelabel[1]{\textbf{##1}}%
\settowidth\labelwidth{\makelabel{#1}}%
\setlength\leftmargin{\labelwidth+\labelsep}%
}%
}{%
\end{list}%
}

% Used by parameter lists and simple sections
\newenvironment{Desc}
{\begin{list}{}{%
\settowidth{\labelwidth}{20pt}%
\setlength{\parsep}{0pt}%
\setlength{\itemsep}{0pt}%
\setlength{\leftmargin}{\labelwidth+\labelsep}%
\renewcommand{\makelabel}{\entrylabel}%
}
}{%
\end{list}%
}

% Used by tables
\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp}%
\newenvironment{TabularC}[1]%
{\tabulinesep=1mm
\begin{longtabu} spread 0pt [c]{*#1{|X[-1]}|}}%
{\end{longtabu}\par}%

\newenvironment{TabularNC}[1]%
{\begin{tabu} spread 0pt [l]{*#1{|X[-1]}|}}%
{\end{tabu}\par}%

% Used for member group headers
\newenvironment{Indent}{%
\begin{list}{}{%
\setlength{\leftmargin}{0.5cm}%
}%
\item[]\ignorespaces%
}{%
\unskip%
\end{list}%
}

% Used when hyperlinks are turned off
\newcommand{\doxyref}[3]{%
\textbf{#1} (\textnormal{#2}\,\pageref{#3})%
}

% Used to link to a table when hyperlinks are turned on
\newcommand{\doxytablelink}[2]{%
\ref{#1}%
}

% Used to link to a table when hyperlinks are turned off
\newcommand{\doxytableref}[3]{%
\ref{#3}%
}

% Used by @addindex
\newcommand{\lcurly}{\{}
\newcommand{\rcurly}{\}}

% Colors used for syntax highlighting
\definecolor{comment}{rgb}{0.5,0.0,0.0}
\definecolor{keyword}{rgb}{0.0,0.5,0.0}
\definecolor{keywordtype}{rgb}{0.38,0.25,0.125}
\definecolor{keywordflow}{rgb}{0.88,0.5,0.0}
\definecolor{preprocessor}{rgb}{0.5,0.38,0.125}
\definecolor{stringliteral}{rgb}{0.0,0.125,0.25}
\definecolor{charliteral}{rgb}{0.0,0.5,0.5}
\definecolor{vhdldigit}{rgb}{1.0,0.0,1.0}
\definecolor{vhdlkeyword}{rgb}{0.43,0.0,0.43}
\definecolor{vhdllogic}{rgb}{1.0,0.0,0.0}
\definecolor{vhdlchar}{rgb}{0.0,0.0,0.0}

% Color used for table heading
\newcommand{\tableheadbgcolor}{lightgray}%

% Version of hypertarget with correct landing location
\newcommand{\Hypertarget}[1]{\Hy@raisedlink{\hypertarget{#1}{}}}

% Define caption that is also suitable in a table
\makeatletter
\def\doxyfigcaption{%
\refstepcounter{figure}%
\@dblarg{\@caption{figure}}}
\makeatother

+ 137
- 0
doc/latex/md_README.tex Parādīt failu

@@ -0,0 +1,137 @@
\subsection*{About}

libchat6 is a complete library that handles an I\+Pv6 only, peer-\/to-\/peer, end-\/to-\/end encrypted, decentralised, chat client.

\subsection*{Ideas}


\begin{DoxyItemize}
\item Transport is I\+Pv6, but some fallback mechanism to help I\+Pv4 client may be implemented.
\item all clients are identical and no server is needed (some clients might run to act as bootstrap servers but all clients do that as well.)
\item clients have a built-\/in bootstrap list of I\+Pv6 addresses. This list gets updated when the client connects to the network. This allows the client to always have a recent list of bootstraping I\+Ps.
\item There\textquotesingle{}s no central registration site, therefor users just choose a nickname and have a private/public key pair (generated by the client). Clients are identified by their public key.
\item Friends can be searched by their nickname or public key. If a client changes the nickname without changing the key pair, the friend can still be found using the public key. This process is completely handled by the library and is transparent to the user. Is a friend changes the key pair, a new friend request will have to be sent.
\item The interconnection of clients is handled over other clients. The network builds up and paths between clients are calculated similar as a routing protocol for routes. The network is anarchic and no rules, except the protocol, leads it.
\item A client may connect to multiple clients, the network of clients will adjust the routing paths according to a metric and select the best path. The metric is the delay in miliseconds on each connection. A regular keepalive is used to measure the delay and the routing information is adjusted accordingly.
\item To avoid dead paths, a relatively short keepalive timeout is used.
\item The network does not allow store-\/and-\/forward of messages. If the friend is offline, messages cannot be send and the client has to store the message until the friend is available. For mobile clients, notifications might be integrated to wakup the client (no clue how? anyone?)
\item The network allows users to find other users by nickname. Nickname collisions are possible.
\item Chat groups require to send the message to all the clients.
\item Each client will randomly add a certain amount of time to its own metric to avoid disclosing its identifiy to any incoming connection.
\item ... ?
\end{DoxyItemize}

\subsection*{Bootstrapping}

To bootstrap a node, a node will have a list of hardcoded nodes and a list of the last known nodes. The hardcoded list is a list of nodes that are put in place by the initiators of this library. Anyone willing to run a permanent node is welcome to contact us to add a node to the hardcoded list.

\subsection*{Protocol}

\subsubsection*{Principles}

A client is the user. A person or a bot using the network to exchange messages. A node is the entity transporting messages for clients. Both are within the same library but use different identities (keypairs). Nodes sending messages to its peer node(s) will use a temporary keypair generated on startup. This keypair changes at every startup and is not stored. A client, on the other side, will generate a keypair once and will use it to generate a temporary keypair for each chat partner to ensure forward secrecy. The temporary keypair is never stored.

\subsubsection*{Messages format}


\begin{DoxyCode}
<MSGSIGNATURE> <MSGHASH> <TIMESTAMP> <MSGTYPE> [<name>=<value>] ...
\end{DoxyCode}



\begin{DoxyItemize}
\item M\+S\+G\+S\+I\+G\+N\+A\+T\+U\+RE\+: An authenticated M\+S\+G\+H\+A\+SH to prove the origin of the msg. This is signed by the client for client-\/to-\/client messages and by the node key for node-\/to-\/node messages. The first H\+E\+L\+LO message has the signature set to all zeroes.
\item M\+S\+G\+H\+A\+SH\+: A hash of the complete message starting at the timestamp. If the name=value pairs contain a \textquotesingle{}metric\textquotesingle{} option, the hash must be calculated with the metric set to 0.
\item T\+I\+M\+E\+S\+T\+A\+MP\+: The timestamp at the creation of the message, formatted \char`\"{}\+Y\+Y\+Y\+Y-\/mm-\/dd H\+H\+:\+M\+M\+:\+S\+S.\+sss\char`\"{}. The timestamp is always in U\+TC.
\item M\+S\+G\+T\+Y\+PE\+: The msgtime is the type of message that is sent. See below.
\item name=value\+: name=value pairs transport all the message informations and vary depending on the msgtype. See description of msgtypes below.
\end{DoxyItemize}

\subsubsection*{name=value pairs}

N\+O\+TE\+: All \textquotesingle{}value\textquotesingle{} transporting binary or U\+T\+F-\/8 data is represented as base64.


\begin{DoxyItemize}
\item chatid\+: a uuid defining the chat group.
\item clientkey\+: the public key of the sending client.
\item icon\+: base64 encoded png.
\item message\+: a base64 encoded message, encrypted with the target\textquotesingle{}s session key.
\item metric\+: a 32 bits unsigned integer representing the sum of all latencies between the client and the announcing client. An originating client will set a random value between 1000 and 2000 to avoid localisation.
\item msgid\+: a uuid defining a message unique to a chatid.
\item mtype\+: A closed supported list of media types \{text, png, jpeg, gif, webm, vcard, ??\} (text is always U\+T\+F-\/8)
\item neighbour\+: ipv6,port\mbox{[},ipv4\mbox{]} (I\+Pv4 can be optionally disclosed)
\item nickname\+: the nickname chosen by the client (U\+T\+F-\/8 string).
\item nodekey\+: the public key of the sending node.
\item nonce\+: random bytes, also known as initialisation vector. Must be new for every message.
\item sessionkey\+: a session temporary public key.
\item target\+\_\+hash\+: a hash of the target public key. Mainly used for routing.
\item version\+: currenlty has the value of 1.
\end{DoxyItemize}

\subsubsection*{begin and end of session (node-\/to-\/node)}

This is the very first message both nodes will send after connecting. The connecting node will send it\textquotesingle{}s H\+E\+L\+LO first. If the connected node agrees it will reply with its own H\+E\+L\+LO. If it doesn\textquotesingle{}t it will reply with a B\+YE msg and close the connection. Both nodes may send a B\+YE message at any time to terminate the connection.


\begin{DoxyCode}
HELLO \{version,nodekey\}
BYE
\end{DoxyCode}


\subsubsection*{path anouncement and withdrawal}

Clients can announce, withdraw or update their presence. A node will keep all client information and inform any new node of the state of all known clients. The metric must be updated when a O\+N\+L\+I\+NE or U\+P\+D\+A\+TE msg is received.


\begin{DoxyCode}
CLIENT\_ONLINE \{clientkey, nickname, icon, metric\}
CLIENT\_UPDATE \{nonce, nickname, icon, metric\}
CLIENT\_OFFLINE
\end{DoxyCode}


\subsubsection*{K\+E\+E\+P\+A\+L\+I\+VE}

Keepalive and node-\/to-\/node only and are originated by both nodes on a connection. The interval is 15s and if a node doesn\textquotesingle{}t receive a timeout for 30s, it must shutdown the connection. The interval betweeen the request and the response is used to calculate the metric. The metric is caculcated as an average value of the last 10 messages.


\begin{DoxyCode}
KEEPALIVE\_REQUEST
KEEPALIVE\_RESPONSE
\end{DoxyCode}


\subsubsection*{F\+R\+I\+E\+N\+DS \& M\+E\+S\+S\+A\+G\+ES}

The friend request message has two purposes. First, for a new friend, is will ask the friend to confirm to actually be friends. Secondly, it will exchange temporary session keys. This means that everytime a client comes online and wants to initiate a chat with an existing friend, it will have to send a friend request and get a friend confirm message back in order to exchange new temporary keys. If a friend request from an existing friend comes in, the confim message will automatically be sent back without user confirmation. If the friend is unknown, a user confirmation is required.


\begin{DoxyCode}
FRIEND\_REQUEST \{target\_hash, sessionkey\}
FRIEND\_CONFIRM \{target\_hash, sessionkey\}
\end{DoxyCode}


client-\/to-\/client messages are exchanged using those three message types. Message received and read are only confirmations. A UI may implement a visual aid to show those. Message send, sends a message using the name=value pair \textquotesingle{}message\textquotesingle{}. The message is encrypted using the temporary session key of the friend. Messages must be confirmed received, if they don\textquotesingle{}t, the client will retry sending it after a timeout of 30s until a recv is received or a C\+L\+I\+E\+N\+T\+\_\+\+O\+F\+F\+L\+I\+NE message is received. Messages can only be sent to online friends. If a friend is offline, the client will have to store the message until the friend is online.


\begin{DoxyCode}
MESSAGE\_SEND \{target\_hash, chatid, msgid, mtype, message\}
MESSAGE\_RECV \{target\_hash, chatid, msgid\}
MESSAGE\_READ \{target\_hash, chatid, msgid\}
\end{DoxyCode}


\subsubsection*{N\+E\+I\+G\+H\+B\+O\+U\+RS}

In order to discover other nodes, a node may request the directly connected nodes of a neighbor node. The list will be sent back to the requesting node with one or multiple name=value pairs of \textquotesingle{}neighbor\textquotesingle{}. The value is composed of the IP of the node and the T\+CP port separated by a comma. A neighbor will only be disclosed to another neighbor if it is relaying messages for others (showed more than one C\+L\+I\+E\+N\+T\+\_\+\+O\+N\+L\+I\+NE msg).


\begin{DoxyCode}
NEIGHBORS\_REQUEST # request the neighbours of your neighbour
NEIGHBORS\_RESPONSE \{neighbour,..\} # neighbours list, multiple time the same key
\end{DoxyCode}

+ 155
- 0
doc/latex/refman.tex Parādīt failu

@@ -0,0 +1,155 @@
\documentclass[twoside]{book}

% Packages required by doxygen
\usepackage{fixltx2e}
\usepackage{calc}
\usepackage{doxygen}
\usepackage[export]{adjustbox} % also loads graphicx
\usepackage{graphicx}
\usepackage[utf8]{inputenc}
\usepackage{makeidx}
\usepackage{multicol}
\usepackage{multirow}
\PassOptionsToPackage{warn}{textcomp}
\usepackage{textcomp}
\usepackage[nointegrals]{wasysym}
\usepackage[table]{xcolor}

% Font selection
\usepackage[T1]{fontenc}
\usepackage[scaled=.90]{helvet}
\usepackage{courier}
\usepackage{amssymb}
\usepackage{sectsty}
\renewcommand{\familydefault}{\sfdefault}
\allsectionsfont{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\renewcommand{\DoxyLabelFont}{%
\fontseries{bc}\selectfont%
\color{darkgray}%
}
\newcommand{\+}{\discretionary{\mbox{\scriptsize$\hookleftarrow$}}{}{}}

% Page & text layout
\usepackage{geometry}
\geometry{%
a4paper,%
top=2.5cm,%
bottom=2.5cm,%
left=2.5cm,%
right=2.5cm%
}
\tolerance=750
\hfuzz=15pt
\hbadness=750
\setlength{\emergencystretch}{15pt}
\setlength{\parindent}{0cm}
\setlength{\parskip}{3ex plus 2ex minus 2ex}
\makeatletter
\renewcommand{\paragraph}{%
\@startsection{paragraph}{4}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@parafont%
}%
}
\renewcommand{\subparagraph}{%
\@startsection{subparagraph}{5}{0ex}{-1.0ex}{1.0ex}{%
\normalfont\normalsize\bfseries\SS@subparafont%
}%
}
\makeatother

% Headers & footers
\usepackage{fancyhdr}
\pagestyle{fancyplain}
\fancyhead[LE]{\fancyplain{}{\bfseries\thepage}}
\fancyhead[CE]{\fancyplain{}{}}
\fancyhead[RE]{\fancyplain{}{\bfseries\leftmark}}
\fancyhead[LO]{\fancyplain{}{\bfseries\rightmark}}
\fancyhead[CO]{\fancyplain{}{}}
\fancyhead[RO]{\fancyplain{}{\bfseries\thepage}}
\fancyfoot[LE]{\fancyplain{}{}}
\fancyfoot[CE]{\fancyplain{}{}}
\fancyfoot[RE]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
\fancyfoot[LO]{\fancyplain{}{\bfseries\scriptsize Generated by Doxygen }}
\fancyfoot[CO]{\fancyplain{}{}}
\fancyfoot[RO]{\fancyplain{}{}}
\renewcommand{\footrulewidth}{0.4pt}
\renewcommand{\chaptermark}[1]{%
\markboth{#1}{}%
}
\renewcommand{\sectionmark}[1]{%
\markright{\thesection\ #1}%
}

% Indices & bibliography
\usepackage{natbib}
\usepackage[titles]{tocloft}
\setcounter{tocdepth}{3}
\setcounter{secnumdepth}{5}
\makeindex

% Hyperlinks (required, but should be loaded last)
\usepackage{ifpdf}
\ifpdf
\usepackage[pdftex,pagebackref=true]{hyperref}
\else
\usepackage[ps2pdf,pagebackref=true]{hyperref}
\fi
\hypersetup{%
colorlinks=true,%
linkcolor=blue,%
citecolor=blue,%
unicode%
}

% Custom commands
\newcommand{\clearemptydoublepage}{%
\newpage{\pagestyle{empty}\cleardoublepage}%
}

\usepackage{caption}
\captionsetup{labelsep=space,justification=centering,font={bf},singlelinecheck=off,skip=4pt,position=top}

%===== C O N T E N T S =====

\begin{document}

% Titlepage & ToC
\hypersetup{pageanchor=false,
bookmarksnumbered=true,
pdfencoding=unicode
}
\pagenumbering{alph}
\begin{titlepage}
\vspace*{7cm}
\begin{center}%
{\Large libchat6 }\\
\vspace*{1cm}
{\large Generated by Doxygen 1.8.13}\\
\end{center}
\end{titlepage}
\clearemptydoublepage
\pagenumbering{roman}
\tableofcontents
\clearemptydoublepage
\pagenumbering{arabic}
\hypersetup{pageanchor=true}

%--- Begin generated contents ---
\chapter{libchat6}
\label{md_README}
\Hypertarget{md_README}
\input{md_README}
%--- End generated contents ---

% Index
\backmatter
\newpage
\phantomsection
\clearemptydoublepage
\addcontentsline{toc}{chapter}{Index}
\printindex

\end{document}

Notiek ielāde…
Atcelt
Saglabāt