2.2. doc.cc


2.2.1
#include "doc.hh"
#include <cstring>
#include <errno.h>
#include <netdb.h>

namespace libdoc {

2.2.2

A constructor for the ExceptionSystemError class. As well as the message given explicitly it also stores the error code in errno.

ExceptionSystemError::ExceptionSystemError (const string &msg)
   : Exception (msg)
{
   err = errno;
}

2.2.3

Return an explanation of the error which caused the exception.

string
ExceptionSystemError::explain () const
{
   string s = what();
   if (err ≠ 0)
   {
      s += '\n';
      s += strerror (err);
   }

   return s;
}

2.2.4

A constructor for the ExceptionGDBMError class. As well as the message given explicitly it also stores the error code in gdbm_errno.

ExceptionGDBMError::ExceptionGDBMError (const string &msg)
   : Exception (msg)
{
   err = gdbm_errno;
}

2.2.5

Return an explanation of the error which caused the exception.

string
ExceptionGDBMError::explain () const
{
   string s = what();
   if (err ≠ 0)
   {
      s += '\n';
      s += gdbm_strerror (err);
   }

   return s;
}

2.2.6

An equivalent of the Perl `chomp' function.

void
chomp (string &s)
{
   if (not s.empty() and s[s.size() - 1] == '\n')
      s.resize (s.size() - 1);
}

2.2.7
void
split (vector <string> &results, const string &s, char delim)
{
   if (not s.empty())
   {
      string::size_type pos = 0, oldpos = 0;
      while ((pos = s.find (delim, oldpos)) ≠ string::npos)
      {
         results.push_back (s.substr (oldpos, pos - oldpos));
         oldpos = pos + 1;
      }
      results.push_back (s.substr (oldpos));
   }
}

2.2.8
bool
check_extension (const string &s, const string &ext)
{
   if (ext.size() > s.size())
      return false;

   return s.substr (s.size() - ext.size()) == ext;
}

2.2.9
void
perform_search (int s, const string &query, vector <SearchResult> &sr)
{
   sock_send_char (s, 'c');
   sock_send_str_nl (s, query);

   string numstr;
   sock_read_string (s, numstr);
   unsigned int n = 0;
   sscanf (numstr.c_str(), "%u", &n);
   sr.clear();
   sr.resize (n);

   for (size_t i = 0; i < n; ++i)
   {
      sock_read_string (s, sr[i].document_filename);
      sock_read_string (s, sr[i].document_title);
      sock_read_string (s, sr[i].section_title);
      sock_read_string (s, sr[i].section_ref);
      sock_read_string (s, sr[i].format_icon);
      sock_read_string (s, sr[i].format_name);
      sock_read_string (s, sr[i].format_viewers);
   }
}

2.2.10

Work out our host's IP address.

in_addr
find_hostip ()
{
   char hostname[MAXHOSTNAMELEN + 1];
   gethostname (hostname, sizeof (hostname));

   struct hostent *hp = gethostbyname (hostname);
   if (hp == 0)
      throw ExceptionSystemError ("couldn't work out my hostname");

   return *(struct in_addr *) hp->h_addr_list[0];
}

2.2.11

Copy a string into dynamically allocated memory (allocated with new).

char *
x_strdup (const char *s)
{
   char *new_s = new char[strlen (s) + 1];
   strcpy (new_s, s);

   return new_s;
}

2.2.12
int
open_connection_to_docd (const char *hostname, int port)
{
   int s = socket (PF_INET, SOCK_STREAM, 0);
   if (s == -1)
      throw ExceptionSystemError ("can't open socket to talk to docd");

   sockaddr_in addr;
   addr.sin_family = AF_INET;
   addr.sin_port = htons (port);
   addr.sin_addr.s_addr = inet_addr (hostname);

   if (connect (s, (sockaddr *) &addr, sizeof (addr)))
      throw ExceptionSystemError ("can't connect to socket to talk to docd");

   return s;
}

2.2.13
void
sock_read_string (int sock, string &s)
{
   int rc;
   char c;

   rc = recv (sock, &c, 1, 0);
   while (rc == 1 && c ≠ '\n')
   {
      s += c;
      rc = recv (sock, &c, 1, 0);
   }

   if (!s.empty() && s[s.size() - 1] == '\r')
      s.resize (s.size() - 1);
}

2.2.14
void
sock_send_str (int s, const string &str)
{
   const char *cs = str.c_str();

   if (send (s, cs, str.size(), 0) ≠ int (str.size()))
      throw Exception ("Error sending string to client");
}

2.2.15
void
sock_send_str_nl (int s, const string &str)
{
   sock_send_str (s, str);
   sock_send_char (s, '\n');
}

2.2.16
void
sock_send_char (int s, char c)
{
   if (send (s, &c, 1, 0) ≠ 1)
      throw Exception ("Error sending character to client");
}

}  // namespace libdoc