Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2010 Michael Drake <tlsa@netsurf-browser.org>
  3.  *
  4.  * This file is part of NetSurf, http://www.netsurf-browser.org/
  5.  *
  6.  * NetSurf is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; version 2 of the License.
  9.  *
  10.  * NetSurf is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  */
  18.  
  19. /** \file
  20.  * Generate HTML content for displaying directory listings (implementation).
  21.  */
  22.  
  23. #include <stdbool.h>
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include "content/dirlist.h"
  28. #include "utils/messages.h"
  29.  
  30. static const char footer[] = "</div>\n</body>\n</html>\n";
  31.  
  32. static int dirlist_filesize_calculate(unsigned long *bytesize);
  33. static int dirlist_filesize_value(unsigned long bytesize);
  34. static char* dirlist_filesize_unit(unsigned long bytesize);
  35.  
  36.  
  37. /**
  38.  * Generates the top part of an HTML directory listing page
  39.  *
  40.  * \return  Top of directory listing HTML
  41.  *
  42.  * This is part of a series of functions.  To generate a complete page,
  43.  * call the following functions in order:
  44.  *
  45.  *     dirlist_generate_top()
  46.  *     dirlist_generate_hide_columns()  -- optional
  47.  *     dirlist_generate_title()
  48.  *     dirlist_generate_parent_link()   -- optional
  49.  *     dirlist_generate_headings()
  50.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  51.  *     dirlist_generate_bottom()
  52.  */
  53.  
  54. bool dirlist_generate_top(char *buffer, int buffer_length)
  55. {
  56.         int error = snprintf(buffer, buffer_length,
  57.                 "<html>\n"
  58.                 "<head>\n"
  59.                 "<link rel=\"stylesheet\" title=\"Standard\" "
  60.                         "type=\"text/css\" href=\"resource:internal.css\">\n"
  61.                 "<style>\n");
  62.         if (error < 0 || error >= buffer_length)
  63.                 /* Error or buffer too small */
  64.                 return false;
  65.         else
  66.                 /* OK */
  67.                 return true;
  68.  
  69. }
  70.  
  71.  
  72. /**
  73.  * Generates the part of an HTML directory listing page that can suppress
  74.  * particular columns
  75.  *
  76.  * \param  flags          flags for which cols to suppress. 0 to suppress none
  77.  * \param  buffer         buffer to fill with generated HTML
  78.  * \param  buffer_length  maximum size of buffer
  79.  * \return  true iff buffer filled without error
  80.  *
  81.  * This is part of a series of functions.  To generate a complete page,
  82.  * call the following functions in order:
  83.  *
  84.  *     dirlist_generate_top()
  85.  *     dirlist_generate_hide_columns()  -- optional
  86.  *     dirlist_generate_title()
  87.  *     dirlist_generate_parent_link()   -- optional
  88.  *     dirlist_generate_headings()
  89.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  90.  *     dirlist_generate_bottom()
  91.  */
  92.  
  93. bool dirlist_generate_hide_columns(int flags, char *buffer, int buffer_length)
  94. {
  95.         int error = snprintf(buffer, buffer_length,
  96.                         "%s\n%s\n%s\n%s\n%s\n",
  97.                         (flags & DIRLIST_NO_NAME_COLUMN) ?
  98.                                         "span.name { display: none; }\n" : "",
  99.                         (flags & DIRLIST_NO_TYPE_COLUMN) ?
  100.                                         "span.type { display: none; }\n" : "",
  101.                         (flags & DIRLIST_NO_SIZE_COLUMN) ?
  102.                                         "span.size { display: none; }\n" : "",
  103.                         (flags & DIRLIST_NO_DATE_COLUMN) ?
  104.                                         "span.date { display: none; }\n" : "",
  105.                         (flags & DIRLIST_NO_TIME_COLUMN) ?
  106.                                         "span.time { display: none; }\n" : "");
  107.         if (error < 0 || error >= buffer_length)
  108.                 /* Error or buffer too small */
  109.                 return false;
  110.         else
  111.                 /* OK */
  112.                 return true;
  113. }
  114.  
  115.  
  116. /**
  117.  * Generates the part of an HTML directory listing page that contains the title
  118.  *
  119.  * \param  title          title to use
  120.  * \param  buffer         buffer to fill with generated HTML
  121.  * \param  buffer_length  maximum size of buffer
  122.  * \return  true iff buffer filled without error
  123.  *
  124.  * This is part of a series of functions.  To generate a complete page,
  125.  * call the following functions in order:
  126.  *
  127.  *     dirlist_generate_top()
  128.  *     dirlist_generate_hide_columns()  -- optional
  129.  *     dirlist_generate_title()
  130.  *     dirlist_generate_parent_link()   -- optional
  131.  *     dirlist_generate_headings()
  132.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  133.  *     dirlist_generate_bottom()
  134.  */
  135.  
  136. bool dirlist_generate_title(const char *title, char *buffer, int buffer_length)
  137. {
  138.         int error;
  139.  
  140.         if (title == NULL)
  141.                 title = "";
  142.  
  143.         error = snprintf(buffer, buffer_length,
  144.                         "</style>\n"
  145.                         "<title>%s</title>\n"
  146.                         "</head>\n"
  147.                         "<body id=\"dirlist\">\n"
  148.                         "<h1>%s</h1>\n",
  149.                         title, title);
  150.         if (error < 0 || error >= buffer_length)
  151.                 /* Error or buffer too small */
  152.                 return false;
  153.         else
  154.                 /* OK */
  155.                 return true;
  156. }
  157.  
  158.  
  159. /**
  160.  * Generates the part of an HTML directory listing page that links to the parent
  161.  * directory
  162.  *
  163.  * \param  parent         url of parent directory
  164.  * \param  buffer         buffer to fill with generated HTML
  165.  * \param  buffer_length  maximum size of buffer
  166.  * \return  true iff buffer filled without error
  167.  *
  168.  * This is part of a series of functions.  To generate a complete page,
  169.  * call the following functions in order:
  170.  *
  171.  *     dirlist_generate_top()
  172.  *     dirlist_generate_hide_columns()  -- optional
  173.  *     dirlist_generate_title()
  174.  *     dirlist_generate_parent_link()   -- optional
  175.  *     dirlist_generate_headings()
  176.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  177.  *     dirlist_generate_bottom()
  178.  */
  179.  
  180. bool dirlist_generate_parent_link(const char *parent, char *buffer,
  181.                 int buffer_length)
  182. {
  183.         int error = snprintf(buffer, buffer_length,
  184.                         "<p><a href=\"%s\">%s</a></p>",
  185.                         parent, messages_get("FileParent"));
  186.         if (error < 0 || error >= buffer_length)
  187.                 /* Error or buffer too small */
  188.                 return false;
  189.         else
  190.                 /* OK */
  191.                 return true;
  192. }
  193.  
  194.  
  195. /**
  196.  * Generates the part of an HTML directory listing page that displays the column
  197.  * headings
  198.  *
  199.  * \param  buffer         buffer to fill with generated HTML
  200.  * \param  buffer_length  maximum size of buffer
  201.  * \return  true iff buffer filled without error
  202.  *
  203.  * This is part of a series of functions.  To generate a complete page,
  204.  * call the following functions in order:
  205.  *
  206.  *     dirlist_generate_top()
  207.  *     dirlist_generate_hide_columns()  -- optional
  208.  *     dirlist_generate_title()
  209.  *     dirlist_generate_parent_link()   -- optional
  210.  *     dirlist_generate_headings()
  211.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  212.  *     dirlist_generate_bottom()
  213.  */
  214.  
  215. bool dirlist_generate_headings(char *buffer, int buffer_length)
  216. {
  217.         int error = snprintf(buffer, buffer_length,
  218.                         "<div>\n"
  219.                         "<strong>\n"
  220.                         "\t<span class=\"name\">%s</span>\n"
  221.                         "\t<span class=\"type\">%s</span>\n"
  222.                         "\t<span class=\"size\">%s</span>"
  223.                         "<span class=\"size\"></span>\n"
  224.                         "\t<span class=\"date\">%s</span>\n"
  225.                         "\t<span class=\"time\">%s</span>\n"
  226.                         "</strong>\n",
  227.                         messages_get("FileName"), messages_get("FileType"),
  228.                         messages_get("FileSize"), messages_get("FileDate"),
  229.                         messages_get("FileTime"));
  230.         if (error < 0 || error >= buffer_length)
  231.                 /* Error or buffer too small */
  232.                 return false;
  233.         else
  234.                 /* OK */
  235.                 return true;
  236. }
  237.  
  238.  
  239. /**
  240.  * Generates the part of an HTML directory listing page that displays a row
  241.  * in the directory contents table
  242.  *
  243.  * \param  even           evenness of row number, for alternate row colouring
  244.  * \param  directory      whether this row is for a directory (or a file)
  245.  * \param  url            url for row entry
  246.  * \param  name           name of row entry
  247.  * \param  mimetype       MIME type of row entry
  248.  * \param  size           size of row entry.  If negative, size is left blank
  249.  * \param  date           date row entry was last modified
  250.  * \param  time           time row entry was last modified
  251.  * \param  buffer         buffer to fill with generated HTML
  252.  * \param  buffer_length  maximum size of buffer
  253.  * \return  true iff buffer filled without error
  254.  *
  255.  * This is part of a series of functions.  To generate a complete page,
  256.  * call the following functions in order:
  257.  *
  258.  *     dirlist_generate_top()
  259.  *     dirlist_generate_hide_columns()  -- optional
  260.  *     dirlist_generate_title()
  261.  *     dirlist_generate_parent_link()   -- optional
  262.  *     dirlist_generate_headings()
  263.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  264.  *     dirlist_generate_bottom()
  265.  */
  266.  
  267. bool dirlist_generate_row(bool even, bool directory, char *url, char *name,
  268.                 const char *mimetype, long long size, char *date, char *time,
  269.                 char *buffer, int buffer_length)
  270. {
  271.         const char *unit;
  272.         char size_string[100];
  273.         int error;
  274.  
  275.         if (size < 0) {
  276.                 unit = "";
  277.                 strncpy(size_string, "", sizeof size_string);
  278.         } else {
  279.                 unit = messages_get(dirlist_filesize_unit((unsigned long)size));
  280.                 snprintf(size_string, sizeof size_string, "%d",
  281.                                 dirlist_filesize_value((unsigned long)size));
  282.         }
  283.  
  284.         error = snprintf(buffer, buffer_length,
  285.                         "<a href=\"%s\" class=\"%s %s\">\n"
  286.                         "\t<span class=\"name\">%s</span>\n"
  287.                         "\t<span class=\"type\">%s</span>\n"
  288.                         "\t<span class=\"size\">%s</span>"
  289.                         "<span class=\"size\">%s</span>\n"
  290.                         "\t<span class=\"date\">%s</span>\n"
  291.                         "\t<span class=\"time\">%s</span>\n"
  292.                         "</a>\n",
  293.                         url, even ? "even" : "odd",
  294.                         directory ? "dir" : "file",
  295.                         name, mimetype, size_string, unit, date, time);
  296.         if (error < 0 || error >= buffer_length)
  297.                 /* Error or buffer too small */
  298.                 return false;
  299.         else
  300.                 /* OK */
  301.                 return true;
  302. }
  303.  
  304.  
  305. /**
  306.  * Generates the bottom part of an HTML directory listing page
  307.  *
  308.  * \return  Bottom of directory listing HTML
  309.  *
  310.  * This is part of a series of functions.  To generate a complete page,
  311.  * call the following functions in order:
  312.  *
  313.  *     dirlist_generate_top()
  314.  *     dirlist_generate_hide_columns()  -- optional
  315.  *     dirlist_generate_title()
  316.  *     dirlist_generate_parent_link()   -- optional
  317.  *     dirlist_generate_headings()
  318.  *     dirlist_generate_row()           -- call 'n' times for 'n' rows
  319.  *     dirlist_generate_bottom()
  320.  */
  321.  
  322. bool dirlist_generate_bottom(char *buffer, int buffer_length)
  323. {
  324.         int error = snprintf(buffer, buffer_length,
  325.                         "</div>\n"
  326.                         "</body>\n"
  327.                         "</html>\n");
  328.         if (error < 0 || error >= buffer_length)
  329.                 /* Error or buffer too small */
  330.                 return false;
  331.         else
  332.                 /* OK */
  333.                 return true;
  334. }
  335.  
  336.  
  337. /**
  338.  * Obtain display value and units for filesize after conversion to B/kB/MB/GB,
  339.  * as appropriate.  
  340.  *
  341.  * \param  bytesize  file size in bytes, updated to filesize in output units
  342.  * \return  number of times bytesize has been divided by 1024
  343.  */
  344.  
  345. int dirlist_filesize_calculate(unsigned long *bytesize)
  346. {
  347.         int i = 0;
  348.         while (*bytesize > 1024 * 4) {
  349.                 *bytesize /= 1024;
  350.                 i++;
  351.                 if (i == 3)
  352.                         break;
  353.         }
  354.         return i;
  355. }
  356.  
  357.  
  358. /**
  359.  * Obtain display value for filesize after conversion to B/kB/MB/GB,
  360.  * as appropriate
  361.  *
  362.  * \param  bytesize  file size in bytes
  363.  * \return  Value to display for file size, in units given by filesize_unit()
  364.  */
  365.  
  366. int dirlist_filesize_value(unsigned long bytesize)
  367. {
  368.         dirlist_filesize_calculate(&bytesize);
  369.         return (int)bytesize;
  370. }
  371.  
  372.  
  373. /**
  374.  * Obtain display units for filesize after conversion to B/kB/MB/GB,
  375.  * as appropriate
  376.  *
  377.  * \param  bytesize  file size in bytes
  378.  * \return  Units to display for file size, for value given by filesize_value()
  379.  */
  380.  
  381. char* dirlist_filesize_unit(unsigned long bytesize)
  382. {
  383.         const char* units[] = { "Bytes", "kBytes", "MBytes", "GBytes" };
  384.         return (char*)units[dirlist_filesize_calculate(&bytesize)];
  385. }
  386.