r3021 rjek - in /trunk/netsurf/utils: themes.c themes.h
by netsurf@semichrome.net
Author: rjek
Date: Tue Oct 31 16:19:21 2006
New Revision: 3021
URL: http://svn.semichrome.net?rev=3021&view=rev
Log:
Skeleton implementation of new themes API, complete with documentation, for discussion purposes.
Added:
trunk/netsurf/utils/themes.c
trunk/netsurf/utils/themes.h
Added: trunk/netsurf/utils/themes.c
URL: http://svn.semichrome.net/trunk/netsurf/utils/themes.c?rev=3021&view=auto
==============================================================================
--- trunk/netsurf/utils/themes.c (added)
+++ trunk/netsurf/utils/themes.c Tue Oct 31 16:19:21 2006
@@ -1,0 +1,134 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Rob Kendrick <rjek(a)rjek.com>
+ */
+
+#include "netsurf/utils/themes.h"
+
+struct theme_descriptor;
+
+/**
+ * Initialise the themes interface. This must be called once only before any
+ * other themes_ functions are called. It will enumerate all the themes
+ * found in the directory path names passed. Further themes can be added at
+ * runtime by using themes_add_new().
+ *
+ * \param directories An array of directory path names that will be scanned
+ * in turn to find installed themes. Earlier directories
+ * take precedence over ones mentioned later.
+ */
+void themes_initialise(const unsigned char *directories[])
+{
+
+}
+
+/**
+ * Close the themes system, freeing any open themes, and destroying any
+ * associated bitmaps that have been created from it.
+ */
+void themes_finalise(void)
+{
+
+}
+
+/**
+ * Add a new theme to the themes system. This is primarily of use to let
+ * NetSurf know about themes that were installed after NetSurf started - for
+ * example, from the "Install Theme" user interface.
+ *
+ * \param filename The filename, including full directory path, to the new
+ * theme. This theme will superceed any previous theme
+ * that has the same theme name.
+ */
+void themes_add_new(const unsigned char *filename);
+
+/**
+ * Open a theme for use. This increases the theme's use-count.
+ *
+ * \param themename Name of the theme to open. This is just the theme
+ * name, not the file name.
+ * \return struct theme_descriptor for use with other calls when refering to
+ * this theme. NULL if the theme is unknown to the theme system.
+ */
+struct theme_descriptor *themes_open(const unsigned char *themename)
+{
+
+}
+
+/**
+ * Decreases a theme's usage count, freeing memory assoicated with it should
+ * it reach zero. This will also destroy any bitmaps that have been created
+ * from it.
+ *
+ * \param theme Theme that the caller is finished with.
+ */
+void themes_close(struct theme_descriptor *theme)
+{
+
+}
+
+/**
+ * Enumerate known themes
+ * \param ctx Set to NULL for initial call. It will be updated after each call
+ * to point to the next result.
+ * \return struct theme_descriptor for use with other calls, or NULL if there
+ * are no more themes known. Note that this does not increase the
+ * theme's usage count - you should call themes_open() with the result
+ * of themes_get_name() if you wish to use this theme.
+ */
+struct theme_descriptor *themes_enumerate(void **ctx)
+{
+
+}
+
+/**
+ * Return a NetSurf bitmap structure for an image stored within the theme
+ * container. Note that this bitmap will become invalid if the theme's usage
+ * count reaches zero due to calls to themes_close()
+ *
+ * \param theme The theme you wish to retrieve an image from. If this is NULL,
+ * the default theme, as set by themes_set_default(), will be used.
+ * \param name The name of the image within the theme you wish to retrieve.
+ * \return struct bitmap containing the decoded image.
+ */
+struct bitmap *theme_get_image(struct theme_descriptor *theme,
+ const unsigned char *name)
+{
+
+}
+
+/**
+ * Set the default theme to use. This calls themes_open() to increase the
+ * theme's usage count. It will also call themes_close() on the previous
+ * default, if there was one.
+ *
+ * \param themename The name of the theme to set as the new default.
+ */
+void themes_set_default(const unsigned char *themename)
+{
+
+}
+
+/**
+ * Return the name of a theme from a struct theme_descriptor.
+ *
+ * \param theme The theme whose name to return
+ * \return Name of theme
+ */
+const unsigned char *themes_get_name(struct theme_descriptor *theme)
+{
+
+}
+
+/**
+ * Return the author of a theme from a struct theme_descriptor.
+ *
+ * \param theme The theme whose author to return
+ * \return Author of the theme.
+ */
+const unsigned char *themes_get_author(struct theme_descriptor *theme)
+{
+
+}
Added: trunk/netsurf/utils/themes.h
URL: http://svn.semichrome.net/trunk/netsurf/utils/themes.h?rev=3021&view=auto
==============================================================================
--- trunk/netsurf/utils/themes.h (added)
+++ trunk/netsurf/utils/themes.h Tue Oct 31 16:19:21 2006
@@ -1,0 +1,32 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Rob Kendrick <rjek(a)rjek.com>
+ */
+
+#ifndef __THEMES_H__
+#define __THEMES_H__
+
+#include "netsurf/image/bitmap.h"
+
+struct theme_descriptor;
+
+void themes_initialise(void);
+void themes_finalise(void);
+
+void themes_add_new(const unsigned char *filename);
+
+struct theme_descriptor *themes_open(const unsigned char *themename;
+void themes_close(struct theme_descriptor *theme);
+struct theme_descriptor *themes_enumerate(void **ctx);
+
+struct bitmap *theme_get_image(struct theme_descriptor *theme,
+ const unsigned char *name);
+
+void themes_set_default(const unsigned char *themename);
+
+const unsigned char *themes_get_name(struct theme_descriptor *theme);
+const unsigned char *themes_get_author(struct theme_descriptor *theme);
+
+#endif /* __THEMES_H__ */
16 years, 10 months
r3019 rjek - /trunk/netsurf/utils/container.c
by netsurf@semichrome.net
Author: rjek
Date: Fri Oct 27 15:56:32 2006
New Revision: 3019
URL: http://svn.semichrome.net?rev=3019&view=rev
Log:
Add verbose flag to theme creation tool - silent unless used.
Modified:
trunk/netsurf/utils/container.c
Modified: trunk/netsurf/utils/container.c
URL: http://svn.semichrome.net/trunk/netsurf/utils/container.c?rev=3019&r1=301...
==============================================================================
--- trunk/netsurf/utils/container.c (original)
+++ trunk/netsurf/utils/container.c Fri Oct 27 15:56:32 2006
@@ -347,6 +347,8 @@
#include <sys/stat.h>
#include <unistd.h>
+static bool verbose = false;
+
static void show_usage(const char *argv0)
{
fprintf(stderr, "%s [options] <theme file> <directory>\n", argv0);
@@ -355,6 +357,7 @@
fprintf(stderr, " --extract Extract theme file into directory\n");
fprintf(stderr, " --name x Set theme's name when creating\n");
fprintf(stderr, " --author x Set theme's author when creating\n");
+ fprintf(stderr, " --verbose Print progress information\n");
fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n");
}
@@ -384,11 +387,14 @@
exit(1);
}
- printf("theme name: %s\n", container_get_name(cctx));
- printf("theme author: %s\n", container_get_author(cctx));
+ if (verbose == true) {
+ printf("theme name: %s\n", container_get_name(cctx));
+ printf("theme author: %s\n", container_get_author(cctx));
+ }
while ( (e = container_iterate(cctx, &state)) ) {
- printf("extracting %s\n", e);
+ if (verbose == true)
+ printf("extracting %s\n", e);
snprintf(path, PATH_MAX, "%s/%s", dirname, e);
fh = fopen(path, "wb");
if (fh == NULL) {
@@ -431,7 +437,8 @@
if (strcmp(e->d_name, ".") != 0 &&
strcmp(e->d_name, "..") != 0) {
/* not the metadirs, so we want to process this. */
- printf("adding %s\n", e->d_name);
+ if (verbose == true)
+ printf("adding %s\n", e->d_name);
if (strlen(e->d_name) > 15) {
fprintf(stderr,
"warning: name truncated to 15 characters.\n");
@@ -483,11 +490,12 @@
{ "extract", 0, 0, 'x' },
{ "name", 1, 0, 'n' },
{ "author", 1, 0, 'a' },
+ { "verbose", 0, 0, 'v' },
{ NULL, 0, 0, 0 }
};
- static char *s_opts = "hcxn:a:";
+ static char *s_opts = "hcxn:a:v";
int optch, optidx;
bool creating = false, extracting = false;
unsigned char name[32] = { '\0' }, author[64] = { '\0' };
@@ -515,6 +523,9 @@
if (strlen(optarg) > 64)
fprintf(stderr, "warning: theme author truncated to 64 characters.\n");
break;
+ case 'v':
+ verbose = true;
+ break;
default:
show_usage(argv[0]);
exit(1);
@@ -541,12 +552,14 @@
themefile = strdup(argv[optind]);
dirname = strdup(argv[optind + 1]);
- printf("%s '%s' %s directory '%s'\n",
- creating ? "creating" : "extracting", themefile,
- creating ? "from" : "to", dirname);
+ if (verbose == true)
+ printf("%s '%s' %s directory '%s'\n",
+ creating ? "creating" : "extracting", themefile,
+ creating ? "from" : "to", dirname);
if (creating) {
- printf("name = %s, author = %s\n", name, author);
+ if (verbose == true)
+ printf("name = %s, author = %s\n", name, author);
create_theme(themefile, dirname, name, author);
} else {
extract_theme(themefile, dirname);
16 years, 11 months
r3018 rjek - in /trunk/netsurf/utils: config.h container.c
by netsurf@semichrome.net
Author: rjek
Date: Fri Oct 27 00:53:16 2006
New Revision: 3018
URL: http://svn.semichrome.net?rev=3018&view=rev
Log:
Make containers use mmap() where available
Modified:
trunk/netsurf/utils/config.h
trunk/netsurf/utils/container.c
Modified: trunk/netsurf/utils/config.h
URL: http://svn.semichrome.net/trunk/netsurf/utils/config.h?rev=3018&r1=3017&r...
==============================================================================
--- trunk/netsurf/utils/config.h (original)
+++ trunk/netsurf/utils/config.h Fri Oct 27 00:53:16 2006
@@ -54,6 +54,9 @@
#define WITH_PRINT
/* Theme auto-install */
#define WITH_THEME_INSTALL
+#else
+ /* We're likely to have a working mmap() */
+ #define WITH_MMAP
#endif
#ifdef ncos
/* Kiosk style browsing support */
Modified: trunk/netsurf/utils/container.c
URL: http://svn.semichrome.net/trunk/netsurf/utils/container.c?rev=3018&r1=301...
==============================================================================
--- trunk/netsurf/utils/container.c (original)
+++ trunk/netsurf/utils/container.c Fri Oct 27 00:53:16 2006
@@ -21,6 +21,10 @@
#include <stdbool.h>
#include <arpa/inet.h>
#include "netsurf/utils/container.h"
+#include "netsurf/utils/config.h"
+#ifdef WITH_MMAP
+#include <sys/mman.h>
+#endif
struct container_dirent {
unsigned char filename[16];
@@ -119,15 +123,16 @@
{
unsigned char filename[16];
u_int32_t start, len, flags1, flags2;
-
- ctx->data = malloc(ctx->header.diroffset);
-
- /* TODO: Perhaps replace this with mmap() on UNIX? */
-
+
+#ifdef WITH_MMAP
+ ctx->data = mmap(NULL, ctx->header.diroffset, PROT_READ, MAP_PRIVATE,
+ fileno(ctx->fh), 0);
+#else
+ ctx->data = malloc(ctx->header.diroffset);
fseek(ctx->fh, 0, SEEK_SET);
fread(ctx->data, ctx->header.diroffset, 1, ctx->fh);
+#endif
fseek(ctx->fh, ctx->header.diroffset, SEEK_SET);
-
/* now work through the directory structure taking it apart into
* our structure */
#define BEREAD(x) do { fread(&(x), 4, 1, ctx->fh);(x) = ntohl((x)); } while (0)
@@ -291,7 +296,11 @@
container_write_dir(ctx);
} else if (ctx->processed) {
+#ifdef WITH_MMAP
+ munmap(ctx->data, ctx->header.diroffset);
+#else
free(ctx->data);
+#endif
}
fclose(ctx->fh);
16 years, 11 months
r3017 rjek - in /trunk/netsurf/utils: container.c container.h
by netsurf@semichrome.net
Author: rjek
Date: Thu Oct 26 02:10:46 2006
New Revision: 3017
URL: http://svn.semichrome.net?rev=3017&view=rev
Log:
Import initial work on theme container handling code and simple command-line tool to create and dismantal them. Still a little grungy, and doesn't check in enough places for memory exhaustion.
Added:
trunk/netsurf/utils/container.c
trunk/netsurf/utils/container.h
Added: trunk/netsurf/utils/container.c
URL: http://svn.semichrome.net/trunk/netsurf/utils/container.c?rev=3017&view=auto
==============================================================================
--- trunk/netsurf/utils/container.c (added)
+++ trunk/netsurf/utils/container.c Thu Oct 26 02:10:46 2006
@@ -1,0 +1,548 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Rob Kendrick <rjek(a)rjek.com>
+ */
+
+/* To build a stand-alone command-line utility to create and dismantal
+ * these theme files, build this thusly:
+ *
+ * gcc -I../../ -DNSTHEME -o themetool container.c
+ *
+ */
+
+/** \file
+ * Container format handling for themes etc. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <arpa/inet.h>
+#include "netsurf/utils/container.h"
+
+struct container_dirent {
+ unsigned char filename[16];
+ u_int32_t startoffset;
+ u_int32_t len;
+ u_int32_t flags1;
+ u_int32_t flags2;
+};
+
+struct container_header {
+ u_int32_t magic; /* 0x4d54534e little endian */
+ u_int32_t parser;
+ unsigned char name[32];
+ unsigned char author[64];
+ u_int32_t diroffset;
+};
+
+struct container_ctx {
+ FILE *fh;
+ bool creating;
+ bool processed;
+ struct container_header header;
+ unsigned int entries;
+ unsigned char *data;
+ struct container_dirent *directory;
+};
+
+inline static size_t container_filelen(FILE *fd)
+{
+ size_t o = ftell(fd);
+ size_t a;
+
+ fseek(fd, 0, SEEK_END);
+ a = ftell(fd);
+ fseek(fd, o, SEEK_SET);
+
+ return a;
+}
+
+static void container_add_to_dir(struct container_ctx *ctx,
+ const unsigned char *entryname,
+ const u_int32_t offset,
+ const u_int32_t length)
+{
+ ctx->entries += 1;
+ ctx->directory = realloc(ctx->directory, ctx->entries *
+ sizeof(struct container_dirent));
+
+ strncpy((char *)ctx->directory[ctx->entries - 1].filename,
+ (char *)entryname, 16);
+ ctx->directory[ctx->entries - 1].startoffset = offset;
+ ctx->directory[ctx->entries - 1].len = length;
+ ctx->directory[ctx->entries - 1].flags1 = 0;
+ ctx->directory[ctx->entries - 1].flags2 = 0;
+}
+
+struct container_ctx *container_open(const char *filename)
+{
+ struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1);
+
+ ctx->fh = fopen(filename, "rb");
+
+ if (ctx->fh == NULL) {
+ free(ctx);
+ return NULL;
+ }
+
+ /* we don't actually load any of the data (including directory)
+ * until we need to, such that _get_name and _get_author are as quick
+ * as possible. When we have, this gets set to true.
+ */
+ ctx->processed = false;
+
+ fread(&ctx->header.magic, 4, 1, ctx->fh);
+ ctx->header.magic = ntohl(ctx->header.magic);
+
+ fread(&ctx->header.parser, 4, 1, ctx->fh);
+ ctx->header.parser = ntohl(ctx->header.parser);
+
+ fread(ctx->header.name, 32, 1, ctx->fh);
+ fread(ctx->header.author, 64, 1, ctx->fh);
+
+ fread(&ctx->header.diroffset, 4, 1, ctx->fh);
+ ctx->header.diroffset = ntohl(ctx->header.diroffset);
+
+ if (ctx->header.magic != 0x4e53544d || ctx->header.parser != 3) {
+ fclose(ctx->fh);
+ free(ctx);
+ return NULL;
+ }
+
+ return ctx;
+}
+
+static void container_process(struct container_ctx *ctx)
+{
+ unsigned char filename[16];
+ u_int32_t start, len, flags1, flags2;
+
+ ctx->data = malloc(ctx->header.diroffset);
+
+ /* TODO: Perhaps replace this with mmap() on UNIX? */
+
+ fseek(ctx->fh, 0, SEEK_SET);
+ fread(ctx->data, ctx->header.diroffset, 1, ctx->fh);
+ fseek(ctx->fh, ctx->header.diroffset, SEEK_SET);
+
+ /* now work through the directory structure taking it apart into
+ * our structure */
+#define BEREAD(x) do { fread(&(x), 4, 1, ctx->fh);(x) = ntohl((x)); } while (0)
+ do {
+ fread(filename, 16, 1, ctx->fh);
+ BEREAD(start);
+ BEREAD(len);
+ BEREAD(flags1);
+ BEREAD(flags2);
+ if (filename[0] != '\0')
+ container_add_to_dir(ctx, filename, start, len);
+ } while (filename[0] != '\0');
+#undef BEREAD
+ ctx->processed = true;
+}
+
+static const struct container_dirent *container_lookup(
+ struct container_ctx *ctx,
+ const unsigned char *entryname)
+{
+ int i;
+
+ for (i = 1; i <= ctx->entries; i++) {
+ struct container_dirent *e = ctx->directory + i - 1;
+ if (strcmp((char *)e->filename, (char *)entryname) == 0)
+ return e;
+ }
+
+ return NULL;
+}
+
+const unsigned char *container_get(struct container_ctx *ctx,
+ const unsigned char *entryname,
+ u_int32_t *size)
+{
+ const struct container_dirent *e;
+
+ if (ctx->processed == false)
+ container_process(ctx);
+
+ e = container_lookup(ctx, entryname);
+
+ if (e == NULL)
+ return NULL;
+
+ *size = e->len;
+
+ return &ctx->data[e->startoffset];
+}
+
+const unsigned char *container_iterate(struct container_ctx *ctx, int *state)
+{
+ struct container_dirent *e;
+ unsigned char *r;
+
+ if (ctx->processed == false)
+ container_process(ctx);
+
+ e = ctx->directory + *state;
+
+ r = e->filename;
+
+ if (r == NULL || r[0] == '\0')
+ r = NULL;
+
+ *state += 1;
+
+ return r;
+}
+
+const unsigned char *container_get_name(struct container_ctx *ctx)
+{
+ return ctx->header.name;
+}
+
+const unsigned char *container_get_author(struct container_ctx *ctx)
+{
+ return ctx->header.author;
+}
+
+
+static void container_write_dir(struct container_ctx *ctx)
+{
+ int i;
+ u_int32_t tmp;
+#define BEWRITE(x) do {tmp = htonl((x)); fwrite(&tmp, 4, 1, ctx->fh);} while(0)
+ for (i = 1; i <= ctx->entries; i++) {
+ struct container_dirent *e = ctx->directory + i - 1;
+ fwrite(e->filename, 16, 1, ctx->fh);
+ BEWRITE(e->startoffset);
+ BEWRITE(e->len);
+ BEWRITE(e->flags1);
+ BEWRITE(e->flags2);
+ }
+#undef BEWRITE
+ /* empty entry signifies end of directory */
+ tmp = 0;
+ fwrite(&tmp, 4, 8, ctx->fh);
+}
+
+struct container_ctx *container_create(const char *filename,
+ const unsigned char *name,
+ const unsigned char *author)
+{
+ struct container_ctx *ctx = calloc(sizeof(struct container_ctx), 1);
+
+ ctx->fh = fopen(filename, "wb");
+
+ if (ctx->fh == NULL) {
+ free(ctx);
+ return NULL;
+ }
+
+ ctx->creating = true;
+ ctx->entries = 0;
+ ctx->directory = NULL;
+ ctx->header.parser = htonl(3);
+ strncpy((char *)ctx->header.name, (char *)name, 32);
+ strncpy((char *)ctx->header.author, (char *)author, 64);
+
+ fwrite("NSTM", 4, 1, ctx->fh);
+ fwrite(&ctx->header.parser, 4, 1, ctx->fh);
+ fwrite(ctx->header.name, 32, 1, ctx->fh);
+ fwrite(ctx->header.author, 64, 1, ctx->fh);
+
+ ctx->header.diroffset = 108;
+
+ /* skip over the directory offset for now, and fill it in later.
+ * we don't know where it'll be yet!
+ */
+
+ fseek(ctx->fh, 108, SEEK_SET);
+
+ return ctx;
+}
+
+void container_add(struct container_ctx *ctx, const unsigned char *entryname,
+ const unsigned char *data,
+ const u_int32_t datalen)
+{
+ container_add_to_dir(ctx, entryname, ftell(ctx->fh), datalen);
+ fwrite(data, datalen, 1, ctx->fh);
+}
+
+void container_close(struct container_ctx *ctx)
+{
+ if (ctx->creating == true) {
+ size_t flen, nflen;
+
+ /* discover where the directory's going to go. */
+ flen = container_filelen(ctx->fh);
+ flen = (flen + 3) & (~3); /* round up to nearest 4 bytes */
+
+ /* write this location to the header */
+ fseek(ctx->fh, 104, SEEK_SET);
+ nflen = htonl(flen);
+ fwrite(&nflen, 4, 1, ctx->fh);
+
+ /* seek to where the directory will be, and write it */
+ fseek(ctx->fh, flen, SEEK_SET);
+ container_write_dir(ctx);
+
+ } else if (ctx->processed) {
+ free(ctx->data);
+ }
+
+ fclose(ctx->fh);
+ free(ctx);
+}
+
+#ifdef TEST_RIG
+int main(int argc, char *argv[])
+{
+ struct container_ctx *ctx = container_create("test.theme", "Test theme",
+ "Rob Kendrick");
+ u_int32_t size;
+ int state = 0;
+ char *n;
+
+ container_add(ctx, "CHEESE", "This is a test of some cheese.\0", 31);
+ container_add(ctx, "FOO", "This is a test of some cheese.\0", 31);
+
+ container_close(ctx);
+
+ ctx = container_open("test.theme");
+
+ printf("Theme name: %s\n", container_get_name(ctx));
+ printf("Theme author: %s\n", container_get_author(ctx));
+
+ printf("Test string: %s\n", container_get(ctx, "CHEESE", &size));
+ printf("Length of text: %d\n", size);
+
+ while ( (n = container_iterate(ctx, &state)) ) {
+ printf("%s\n", n);
+ }
+
+ container_close(ctx);
+
+ exit(0);
+}
+#endif
+
+#ifdef NSTHEME
+ /* code to implement a simple container creator/extractor */
+#include <getopt.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static void show_usage(const char *argv0)
+{
+ fprintf(stderr, "%s [options] <theme file> <directory>\n", argv0);
+ fprintf(stderr, " --help This text\n");
+ fprintf(stderr, " --create Create theme file from directory\n");
+ fprintf(stderr, " --extract Extract theme file into directory\n");
+ fprintf(stderr, " --name x Set theme's name when creating\n");
+ fprintf(stderr, " --author x Set theme's author when creating\n");
+ fprintf(stderr, "\nOne and only one of --create or --extract must be specified.\n");
+}
+
+static void extract_theme(const char *themefile, const char *dirname)
+{
+ struct stat statbuf;
+ struct container_ctx *cctx;
+ FILE *fh;
+ const unsigned char *e, *d;
+ char path[PATH_MAX];
+ int state = 0;
+ u_int32_t flen;
+
+
+ if (stat(dirname, &statbuf) != -1) {
+ fprintf(stderr, "error: directory '%s' already exists.\n",
+ dirname);
+ exit(1);
+ }
+
+ mkdir(dirname, 00777);
+
+ cctx = container_open(themefile);
+ if (cctx == NULL) {
+ fprintf(stderr, "error: unable to open theme file '%s'\n",
+ themefile);
+ exit(1);
+ }
+
+ printf("theme name: %s\n", container_get_name(cctx));
+ printf("theme author: %s\n", container_get_author(cctx));
+
+ while ( (e = container_iterate(cctx, &state)) ) {
+ printf("extracting %s\n", e);
+ snprintf(path, PATH_MAX, "%s/%s", dirname, e);
+ fh = fopen(path, "wb");
+ if (fh == NULL) {
+ perror("warning: unable to open file for output");
+ } else {
+ d = container_get(cctx, e, &flen);
+ fwrite(d, flen, 1, fh);
+ fclose(fh);
+ }
+ }
+
+ container_close(cctx);
+
+}
+
+static void create_theme(const char *themefile, const char *dirname,
+ const unsigned char *name,
+ const unsigned char *author)
+{
+ DIR *dir = opendir(dirname);
+ FILE *fh;
+ struct dirent *e;
+ struct stat statbuf;
+ struct container_ctx *cctx;
+ unsigned char *data;
+ char path[PATH_MAX];
+ size_t flen;
+ int t;
+
+ if (dir == NULL) {
+ perror("error: unable to open directory");
+ exit(1);
+ }
+
+ cctx = container_create(themefile, name, author);
+
+ errno = 0; /* to distinguish between end of dir and err */
+
+ while ((e = readdir(dir)) != NULL) {
+ if (strcmp(e->d_name, ".") != 0 &&
+ strcmp(e->d_name, "..") != 0) {
+ /* not the metadirs, so we want to process this. */
+ printf("adding %s\n", e->d_name);
+ if (strlen(e->d_name) > 15) {
+ fprintf(stderr,
+ "warning: name truncated to 15 characters.\n");
+ }
+
+ snprintf(path, PATH_MAX, "%s/%s", dirname, e->d_name);
+
+ stat(path, &statbuf);
+ if (S_ISDIR(statbuf.st_mode)) {
+ fprintf(stderr,
+ "warning: skipping directory '%s'\n",
+ e->d_name);
+ continue;
+ }
+
+ fh = fopen(path, "rb");
+ if (fh == NULL) {
+ fprintf(stderr,
+ "warning: unable to open, skipping.");
+ } else {
+ flen = statbuf.st_size;
+ data = malloc(flen);
+ t = fread(data, flen, 1, fh);
+ fclose(fh);
+ container_add(cctx, (unsigned char *)e->d_name,
+ data, flen);
+ free(data);
+ }
+ }
+ errno = 0;
+ }
+
+ if (errno != 0) {
+ perror("error: couldn't enumerate directory");
+ closedir(dir);
+ container_close(cctx);
+ exit(1);
+ }
+
+ closedir(dir);
+ container_close(cctx);
+}
+
+int main(int argc, char *argv[])
+{
+ static struct option l_opts[] = {
+ { "help", 0, 0, 'h' },
+ { "create", 0, 0, 'c' },
+ { "extract", 0, 0, 'x' },
+ { "name", 1, 0, 'n' },
+ { "author", 1, 0, 'a' },
+
+ { NULL, 0, 0, 0 }
+ };
+
+ static char *s_opts = "hcxn:a:";
+ int optch, optidx;
+ bool creating = false, extracting = false;
+ unsigned char name[32] = { '\0' }, author[64] = { '\0' };
+ char *themefile, *dirname;
+
+ while ((optch = getopt_long(argc, argv, s_opts, l_opts, &optidx)) != -1)
+ switch (optch) {
+ case 'h':
+ show_usage(argv[0]);
+ exit(0);
+ break;
+ case 'c':
+ creating = true;
+ break;
+ case 'x':
+ extracting = true;
+ break;
+ case 'n':
+ strncpy((char *)name, optarg, 31);
+ if (strlen(optarg) > 32)
+ fprintf(stderr, "warning: theme name truncated to 32 characters.\n");
+ break;
+ case 'a':
+ strncpy((char *)author, optarg, 63);
+ if (strlen(optarg) > 64)
+ fprintf(stderr, "warning: theme author truncated to 64 characters.\n");
+ break;
+ default:
+ show_usage(argv[0]);
+ exit(1);
+ break;
+ }
+
+ if (creating == extracting) {
+ show_usage(argv[0]);
+ exit(1);
+ }
+
+ if ((argc - optind) < 2) {
+ show_usage(argv[0]);
+ exit(1);
+ }
+
+ if (creating == true &&
+ (strlen((char *)name) == 0 || strlen((char *)author) == 0)) {
+ fprintf(stderr, "No theme name and/or author specified.\n");
+ show_usage(argv[0]);
+ exit(1);
+ }
+
+ themefile = strdup(argv[optind]);
+ dirname = strdup(argv[optind + 1]);
+
+ printf("%s '%s' %s directory '%s'\n",
+ creating ? "creating" : "extracting", themefile,
+ creating ? "from" : "to", dirname);
+
+ if (creating) {
+ printf("name = %s, author = %s\n", name, author);
+ create_theme(themefile, dirname, name, author);
+ } else {
+ extract_theme(themefile, dirname);
+ }
+
+ return 0;
+}
+#endif
Added: trunk/netsurf/utils/container.h
URL: http://svn.semichrome.net/trunk/netsurf/utils/container.h?rev=3017&view=auto
==============================================================================
--- trunk/netsurf/utils/container.h (added)
+++ trunk/netsurf/utils/container.h Thu Oct 26 02:10:46 2006
@@ -1,0 +1,39 @@
+/*
+ * This file is part of NetSurf, http://netsurf.sourceforge.net/
+ * Licensed under the GNU General Public License,
+ * http://www.opensource.org/licenses/gpl-license
+ * Copyright 2006 Rob Kendrick <rjek(a)rjek.com>
+ */
+
+/** \file
+ * Container format handling for themes etc. */
+
+#ifndef __CONTAINER_H__
+#define __CONTAINER_H__
+
+#include <sys/types.h>
+
+struct container_ctx;
+
+/* reading interface */
+struct container_ctx *container_open(const char *filename);
+const unsigned char *container_get(struct container_ctx *ctx,
+ const unsigned char *entryname,
+ u_int32_t *size);
+const unsigned char *container_get_name(struct container_ctx *ctx);
+const unsigned char *container_get_author(struct container_ctx *ctx);
+const unsigned char *container_iterate(struct container_ctx *ctx,
+ int *state);
+
+/* creating interface */
+struct container_ctx *container_create(const char *filename,
+ const unsigned char *name,
+ const unsigned char *author);
+void container_add(struct container_ctx *ctx, const unsigned char *entryname,
+ const unsigned char *data,
+ const u_int32_t datalen);
+
+/* common interface */
+void container_close(struct container_ctx *ctx);
+
+#endif /* __CONTAINER_H__ */
16 years, 11 months
r3016 tlsa - in /trunk/netsurfweb: builds/top.en info.de info.en info.fr info.nl plan.en
by netsurf@semichrome.net
Author: tlsa
Date: Tue Oct 24 12:34:15 2006
New Revision: 3016
URL: http://svn.semichrome.net?rev=3016&view=rev
Log:
Update plan and builds page.
Modified:
trunk/netsurfweb/builds/top.en
trunk/netsurfweb/info.de
trunk/netsurfweb/info.en
trunk/netsurfweb/info.fr
trunk/netsurfweb/info.nl
trunk/netsurfweb/plan.en
Modified: trunk/netsurfweb/builds/top.en
URL: http://svn.semichrome.net/trunk/netsurfweb/builds/top.en?rev=3016&r1=3015...
==============================================================================
--- trunk/netsurfweb/builds/top.en (original)
+++ trunk/netsurfweb/builds/top.en Tue Oct 24 12:34:15 2006
@@ -17,7 +17,8 @@
<p id="newtonetsurf"><strong>New to NetSurf?</strong> Get
<span class="highlight">NetSurf</span> from this section, and the
-<span class="highlight">five required items below</span>.</p>
+<span class="highlight">five required items below</span>. Read the <a
+href="/info#GettingStartedInstallation">installation instructions</a>.</p>
<table class="download">
<tr><th class="highlight"><a href="netsurf.zip"><img src="netsurf.png" alt=""><br>NetSurf</a></th>
Modified: trunk/netsurfweb/info.de
URL: http://svn.semichrome.net/trunk/netsurfweb/info.de?rev=3016&r1=3015&r2=30...
==============================================================================
--- trunk/netsurfweb/info.de (original)
+++ trunk/netsurfweb/info.de Tue Oct 24 12:34:15 2006
@@ -37,10 +37,9 @@
<h3 id="GettingStartedInstallation">Installation</h3>
-<p>Die jeweils aktuellste Version kann von der <a href="http://netsurf.sourceforge.net/">Web-Seite des Projektes</a> geladen werden. Es gibt drei verschiedene Varianten des Programmes. Für die allermeisten Benutzer ist "NetSurf" der empfehlenswerteste Download. Daneben gibt es mit "NetSurf small build" eine für Systeme mit geringem Speicherplatz geeignete Programmversion. Diese bietet jedoch nur einen eingeschränkten Funktionsumfang. Desweiteren existiert mit "NCNetSurf" eine auf NetComputer (NC) abgestimmte Variante des Programmes.</p>
+<p>Die jeweils aktuellste Version kann von der <a href="http://netsurf.sourceforge.net/">Web-Seite des Projektes</a> geladen werden. Es gibt drei verschiedene Varianten des Programmes. Für die allermeisten Benutzer ist "NetSurf" der empfehlenswerteste Download. Daneben gibt es mit "NetSurf small build" eine für Systeme mit geringem Speicherplatz geeignete Programmversion. Diese bietet jedoch nur einen eingeschränkten Funktionsumfang.</p>
-<p>Zur Installation von "NetSurf" oder "NetSurf small build" wird die heruntergeladene Datei mit einem Entpacker geöffnet und die enthaltene Applikation !Netsurf per Drag&Drop in das gewünschte Zielverzeichnis kopiert. Von dort aus kann das Programm dann mit Doppelklick gestartet werden.<br>
-Die Installation von "NCNetSurf" ist noch nicht dokumentiert.</p>
+<p>Zur Installation von "NetSurf" oder "NetSurf small build" wird die heruntergeladene Datei mit einem Entpacker geöffnet und die enthaltene Applikation !Netsurf per Drag&Drop in das gewünschte Zielverzeichnis kopiert. Von dort aus kann das Programm dann mit Doppelklick gestartet werden.</p>
<h3 id="GettingStartedRequirements">Systemvoraussetzungen</h3>
Modified: trunk/netsurfweb/info.en
URL: http://svn.semichrome.net/trunk/netsurfweb/info.en?rev=3016&r1=3015&r2=30...
==============================================================================
--- trunk/netsurfweb/info.en (original)
+++ trunk/netsurfweb/info.en Tue Oct 24 12:34:15 2006
@@ -37,9 +37,9 @@
<h3 id="GettingStartedInstallation">Installation</h3>
-<p>NetSurf requires RISC OS 3 or later and builds are available from the project's <a href="http://netsurf.sourceforge.net/">web site</a>. There are three builds available. For most users, the "NetSurf" build is recommended. The "NetSurf small build" lacks some features of the main build and is intended for systems with little memory. The "NCNetSurf" build is intended only for users of NetComputers (NCs).</p>
+<p>NetSurf requires RISC OS 3 or later and builds are available from the project's <a href="http://netsurf.sourceforge.net/">web site</a>. There are three builds available. For most users, the "NetSurf" build is recommended. The "NetSurf small build" lacks some features of the main build and is intended for systems with little memory.</p>
-<p>To install the "NetSurf" or Small "NetSurf" builds, simply drag the !NetSurf application directory out of the archive, to your desired location and run it from there. "NCNetSurf" installation is not yet documented.</p>
+<p>To install the "NetSurf" or Small "NetSurf" builds, simply drag the !NetSurf application directory out of the archive, to your desired location and run it from there.</p>
<h3 id="GettingStartedRequirements">Requirements</h3>
Modified: trunk/netsurfweb/info.fr
URL: http://svn.semichrome.net/trunk/netsurfweb/info.fr?rev=3016&r1=3015&r2=30...
==============================================================================
--- trunk/netsurfweb/info.fr (original)
+++ trunk/netsurfweb/info.fr Tue Oct 24 12:34:15 2006
@@ -32,9 +32,9 @@
<h3 id="GettingStartedInstallation">Installation</h3>
-<p>NetSurf nécessite RISC OS 3 ou plus et des versions sont disponibles sur le <a href="http://netsurf.sourceforge.net/">site web</a> du projet. Trois versions sont disponibles. Pour la plupart des utilisateurs, la version "NetSurf" est recommandée. La version "NetSurf allégé" n'a pas certaines caractéristiques de la version principale et est destinée aux systèmes ayant peu de mémoire. La version "NCNetSurf" est destinée seulement aux utilisateurs de Netcomputers (NCs).</p>
+<p>NetSurf nécessite RISC OS 3 ou plus et des versions sont disponibles sur le <a href="http://netsurf.sourceforge.net/">site web</a> du projet. Trois versions sont disponibles. Pour la plupart des utilisateurs, la version "NetSurf" est recommandée. La version "NetSurf allégé" n'a pas certaines caractéristiques de la version principale et est destinée aux systèmes ayant peu de mémoire.</p>
-<p>Pour installer les versions "NetSurf" ou "NetSurf allégé", copiez simplement le répertoire d'application !NetSurf de l'archive vers l'endroit où vous souhaitez installer le programme puis démarrez celui-ci de cet endroit. L'installation de "NCNetSurf" n'est pas encore documentée.</p>
+<p>Pour installer les versions "NetSurf" ou "NetSurf allégé", copiez simplement le répertoire d'application !NetSurf de l'archive vers l'endroit où vous souhaitez installer le programme puis démarrez celui-ci de cet endroit.</p>
<h3 id="GettingStartedRequirements">Configuration logicielle nécessaire</h3>
Modified: trunk/netsurfweb/info.nl
URL: http://svn.semichrome.net/trunk/netsurfweb/info.nl?rev=3016&r1=3015&r2=30...
==============================================================================
--- trunk/netsurfweb/info.nl (original)
+++ trunk/netsurfweb/info.nl Tue Oct 24 12:34:15 2006
@@ -37,9 +37,9 @@
<h3 id="GettingStartedInstallation">Installatie</h3>
-<p>NetSurf vereist RISC OS 3 of later. NetSurf is verkrijgbaar bij de <a href="http://netsurf.sourceforge.net"><strong>webstek</strong></a> van het project. Er zijn drie typen beschikbaar. Voor de meeste gebruikers wordt "NetSurf" aanbevolen. "NetSurf small" is bedoeld voor systemen met minder geheugen en daarom ontbreken sommige mogelijkheden. "NCNetSurf" is alleen bedoeld voor gebruik met netwerkcomputers (nc's).</p>
+<p>NetSurf vereist RISC OS 3 of later. NetSurf is verkrijgbaar bij de <a href="http://netsurf.sourceforge.net"><strong>webstek</strong></a> van het project. Er zijn drie typen beschikbaar. Voor de meeste gebruikers wordt "NetSurf" aanbevolen. "NetSurf small" is bedoeld voor systemen met minder geheugen en daarom ontbreken sommige mogelijkheden.</p>
-<p>Voor installatie van "NetSurf" of "NetSurf small" kan de gewenste !NetSurf-map naar de gewenste plaats worden gesleept en van daaruit worden gestart. De installatie van "NCNetSurf" is nog niet gedocumenteerd.</p>
+<p>Voor installatie van "NetSurf" of "NetSurf small" kan de gewenste !NetSurf-map naar de gewenste plaats worden gesleept en van daaruit worden gestart.</p>
<h3 id="GettingStartedRequirements">Verzoeken</h3>
Modified: trunk/netsurfweb/plan.en
URL: http://svn.semichrome.net/trunk/netsurfweb/plan.en?rev=3016&r1=3015&r2=30...
==============================================================================
--- trunk/netsurfweb/plan.en (original)
+++ trunk/netsurfweb/plan.en Tue Oct 24 12:34:15 2006
@@ -81,7 +81,7 @@
<td class="gtk"><abbr title="Not applicable">N/A</abbr></td>
</tr>
<tr>
-<td class="version1"><span>[1]</span>Generated content</td>
+<td class="later"><span>[2]</span>Generated content</td>
<td class="core">-</td>
<td class="ro"><abbr title="Not applicable">N/A</abbr></td>
<td class="gtk"><abbr title="Not applicable">N/A</abbr></td>
@@ -94,7 +94,7 @@
</tr>
<tr>
<td class="version1"><span>[1]</span>Lists</td>
-<td class="core">-</td>
+<td class="core">John-Mark Bell</td>
<td class="ro"><abbr title="Not applicable">N/A</abbr></td>
<td class="gtk"><abbr title="Not applicable">N/A</abbr></td>
</tr>
16 years, 11 months
r3015 bursa - /trunk/netsurf/render/box_construct.c
by netsurf@semichrome.net
Author: bursa
Date: Sun Oct 22 21:20:17 2006
New Revision: 3015
URL: http://svn.semichrome.net?rev=3015&view=rev
Log:
Remove code to determine containing block; no longer used.
Modified:
trunk/netsurf/render/box_construct.c
Modified: trunk/netsurf/render/box_construct.c
URL: http://svn.semichrome.net/trunk/netsurf/render/box_construct.c?rev=3015&r...
==============================================================================
--- trunk/netsurf/render/box_construct.c (original)
+++ trunk/netsurf/render/box_construct.c Sun Oct 22 21:20:17 2006
@@ -79,12 +79,10 @@
static bool convert_xml_to_box(xmlNode *n, struct content *content,
struct css_style *parent_style,
struct box *parent, struct box **inline_container,
- struct box *containing_block,
char *href, const char *target, char *title);
bool box_construct_element(xmlNode *n, struct content *content,
struct css_style *parent_style,
struct box *parent, struct box **inline_container,
- struct box *containing_block,
char *href, const char *target, char *title);
bool box_construct_text(xmlNode *n, struct content *content,
struct css_style *parent_style,
@@ -188,7 +186,7 @@
c->data.html.object = 0;
if (!convert_xml_to_box(n, c, c->data.html.style, &root,
- &inline_container, 0, 0, 0, 0))
+ &inline_container, 0, 0, 0))
return false;
if (!box_normalise_block(&root, c))
@@ -232,8 +230,6 @@
* \param parent parent in box tree
* \param inline_container current inline container box, or 0, updated to
* new current inline container on exit
- * \param containing_block current containing block for absolutes, as defined
- * by CSS 2.1 10.1 4
* \param href current link URL, or 0 if not in a link
* \param target current link target, or 0 if none
* \param title current title, or 0 if none
@@ -243,13 +239,12 @@
bool convert_xml_to_box(xmlNode *n, struct content *content,
struct css_style *parent_style,
struct box *parent, struct box **inline_container,
- struct box *containing_block,
char *href, const char *target, char *title)
{
switch (n->type) {
case XML_ELEMENT_NODE:
return box_construct_element(n, content, parent_style, parent,
- inline_container, containing_block,
+ inline_container,
href, target, title);
case XML_TEXT_NODE:
return box_construct_text(n, content, parent_style, parent,
@@ -270,8 +265,6 @@
* \param parent parent in box tree
* \param inline_container current inline container box, or 0, updated to
* new current inline container on exit
- * \param containing_block current containing block for absolutes, as defined
- * by CSS 2.1 10.1 4
* \param href current link URL, or 0 if not in a link
* \param target current link target, or 0 if none
* \param title current title, or 0 if none
@@ -281,7 +274,6 @@
bool box_construct_element(xmlNode *n, struct content *content,
struct css_style *parent_style,
struct box *parent, struct box **inline_container,
- struct box *containing_block,
char *href, const char *target, char *title)
{
bool convert_children = true;
@@ -289,7 +281,6 @@
char *s;
struct box *box = 0;
struct box *inline_container_c;
- struct box *containing_block_c;
struct box *inline_end;
struct css_style *style = 0;
struct element_entry *element;
@@ -358,15 +349,6 @@
box_free_box(box);
return true;
}
-
- /* determine if this is a new containing block */
- if (style->position == CSS_POSITION_ABSOLUTE ||
- style->position == CSS_POSITION_RELATIVE ||
- style->position == CSS_POSITION_FIXED ||
- !containing_block)
- containing_block_c = box;
- else
- containing_block_c = containing_block;
if (!*inline_container &&
(box->type == BOX_INLINE ||
@@ -389,7 +371,6 @@
for (c = n->children; c; c = c->next)
if (!convert_xml_to_box(c, content, style,
parent, inline_container,
- containing_block_c,
href, target, title))
return false;
inline_end = box_create(style, href, target, title, id,
@@ -411,7 +392,6 @@
for (c = n->children; convert_children && c; c = c->next)
if (!convert_xml_to_box(c, content, style, box,
&inline_container_c,
- containing_block_c,
href, target, title))
return false;
} else {
@@ -435,7 +415,6 @@
for (c = n->children; convert_children && c; c = c->next)
if (!convert_xml_to_box(c, content, style, box,
&inline_container_c,
- containing_block_c,
href, target, title))
return false;
if (style->float_ == CSS_FLOAT_NONE)
@@ -1407,7 +1386,7 @@
/* convert children and place into fallback */
for (c = n->children; c; c = c->next) {
if (!convert_xml_to_box(c, content, box->style, box,
- &inline_container, 0, 0, 0, 0))
+ &inline_container, 0, 0, 0))
return false;
}
box->fallback = box->children;
16 years, 11 months
r3014 rjek - /trunk/netsurf/utils/hashtable.h
by netsurf@semichrome.net
Author: rjek
Date: Fri Oct 20 17:56:40 2006
New Revision: 3014
URL: http://svn.semichrome.net?rev=3014&view=rev
Log:
Make hashtable's fnv hash inline - saves 8 instructions and two pipeline flushes per call
Modified:
trunk/netsurf/utils/hashtable.h
Modified: trunk/netsurf/utils/hashtable.h
URL: http://svn.semichrome.net/trunk/netsurf/utils/hashtable.h?rev=3014&r1=301...
==============================================================================
--- trunk/netsurf/utils/hashtable.h (original)
+++ trunk/netsurf/utils/hashtable.h Fri Oct 20 17:56:40 2006
@@ -19,7 +19,7 @@
void hash_destroy(struct hash_table *ht);
bool hash_add(struct hash_table *ht, const char *key, const char *value);
const char *hash_get(struct hash_table *ht, const char *key);
-unsigned int hash_string_fnv(const char *datum, unsigned int *len);
+inline unsigned int hash_string_fnv(const char *datum, unsigned int *len);
const char *hash_iterate(struct hash_table *ht, unsigned int *c1,
unsigned int **c2);
16 years, 11 months
r3013 rjw - in /trunk/netsurf/utils: hashtable.c hashtable.h
by netsurf@semichrome.net
Author: rjw
Date: Fri Oct 20 13:13:28 2006
New Revision: 3013
URL: http://svn.semichrome.net?rev=3013&view=rev
Log:
Plug possible memory leak. Reduce memory usage. Add facility to iterate through a hashtable.
Modified:
trunk/netsurf/utils/hashtable.c
trunk/netsurf/utils/hashtable.h
Modified: trunk/netsurf/utils/hashtable.c
URL: http://svn.semichrome.net/trunk/netsurf/utils/hashtable.c?rev=3013&r1=301...
==============================================================================
--- trunk/netsurf/utils/hashtable.c (original)
+++ trunk/netsurf/utils/hashtable.c Fri Oct 20 13:13:28 2006
@@ -1,7 +1,7 @@
/*
* This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License,
- * http://www.opensource.org/licenses/gpl-license
+ * http://www.opensource.org/licenses/gpl-license
* Copyright 2006 Rob Kendrick <rjek(a)rjek.com>
* Copyright 2006 Richard Wilson <info(a)tinct.net>
*/
@@ -21,10 +21,9 @@
struct hash_entry {
- char *key;
- char *value;
- unsigned int key_length;
- struct hash_entry *next;
+ char *pairing; /**< block containing '<key>\0<value>\0' */
+ unsigned int key_length; /**< length of key */
+ struct hash_entry *next; /**< next entry */
};
struct hash_table {
@@ -35,13 +34,13 @@
/**
* Create a new hash table, and return a context for it. The memory consumption
- * of a hash table is approximately 8 + (nchains * 16) bytes if it is empty.
+ * of a hash table is approximately 8 + (nchains * 12) bytes if it is empty.
*
* \param chains Number of chains/buckets this hash table will have. This
- * should be a prime number, and ideally a prime number just
- * over a power of two, for best performance and distribution.
+ * should be a prime number, and ideally a prime number just
+ * over a power of two, for best performance and distribution.
* \return struct hash_table containing the context of this hash table or NULL
- * if there is insufficent memory to create it and its chains.
+ * if there is insufficent memory to create it and its chains.
*/
struct hash_table *hash_create(unsigned int chains)
@@ -68,8 +67,8 @@
/**
* Destroys a hash table, freeing all memory associated with it.
*
- * \param ht Hash table to destroy. After the function returns, this
- * will nolonger be valid.
+ * \param ht Hash table to destroy. After the function returns, this
+ * will nolonger be valid.
*/
void hash_destroy(struct hash_table *ht)
@@ -84,8 +83,7 @@
struct hash_entry *e = ht->chain[i];
while (e) {
struct hash_entry *n = e->next;
- free(e->key);
- free(e->value);
+ free(e->pairing);
free(e);
e = n;
}
@@ -102,22 +100,22 @@
* it. The old key/value pair will be inaccessable but still in memory until
* hash_destroy() is called on the hash table.
*
- * \param ht The hash table context to add the key/value pair to.
- * \param key The key to associate the value with. A copy is made.
+ * \param ht The hash table context to add the key/value pair to.
+ * \param key The key to associate the value with. A copy is made.
* \param value The value to associate the key with. A copy is made.
* \return true if the add succeeded, false otherwise. (Failure most likely
- * indicates insufficent memory to make copies of the key and value.
+ * indicates insufficent memory to make copies of the key and value.
*/
bool hash_add(struct hash_table *ht, const char *key, const char *value)
{
- unsigned int h;
- unsigned int c;
- struct hash_entry *e = malloc(sizeof(struct hash_entry));
+ unsigned int h, c, v;
+ struct hash_entry *e;
if (ht == NULL || key == NULL || value == NULL)
return false;
+ e = malloc(sizeof(struct hash_entry));
if (e == NULL) {
LOG(("Not enough memory for hash entry."));
return false;
@@ -125,21 +123,16 @@
h = hash_string_fnv(key, &(e->key_length));
c = h % ht->nchains;
-
- e->key = strdup(key);
- if (e->key == NULL) {
- LOG(("Unable to strdup() key for hash table."));
+
+ v = strlen(value) ;
+ e->pairing = malloc(v + e->key_length + 2);
+ if (e->pairing == NULL) {
+ LOG(("Not enough memory for string duplication."));
free(e);
return false;
}
-
- e->value = strdup(value);
- if (e->value == NULL) {
- LOG(("Unable to strdup() value for hash table."));
- free(e->key);
- free(e);
- return false;
- }
+ memcpy(e->pairing, key, e->key_length + 1);
+ memcpy(e->pairing + e->key_length + 1, value, v + 1);
e->next = ht->chain[c];
ht->chain[c] = e;
@@ -150,16 +143,14 @@
/**
* Looks up a the value associated with with a key from a specific hash table.
*
- * \param ht The hash table context to look up the key in.
- * \param key The key to search for.
+ * \param ht The hash table context to look up the key in.
+ * \param key The key to search for.
* \return The value associated with the key, or NULL if it was not found.
*/
const char *hash_get(struct hash_table *ht, const char *key)
{
- unsigned int h;
- unsigned int c;
- unsigned int key_length;
+ unsigned int h, c, key_length;
struct hash_entry *e;
if (ht == NULL || key == NULL)
@@ -169,12 +160,11 @@
c = h % ht->nchains;
for (e = ht->chain[c]; e; e = e->next)
- if ((key_length == e->key_length) &&
- (memcmp(key, e->key, key_length) == 0))
- return e->value;
+ if ((key_length == e->key_length) &&
+ (memcmp(key, e->pairing, key_length) == 0))
+ return e->pairing + key_length + 1;
return NULL;
-
}
/**
@@ -183,13 +173,14 @@
* See http://en.wikipedia.org/wiki/Fowler_Noll_Vo_hash for more details.
*
* \param datum The string to hash.
- * \param len Pointer to unsigned integer to record datum's length in.
+ * \param len Pointer to unsigned integer to record datum's length in.
* \return The calculated hash value for the datum.
*/
unsigned int hash_string_fnv(const char *datum, unsigned int *len)
{
unsigned int z = 0x01000193;
+ const char *start = datum;
*len = 0;
if (datum == NULL)
@@ -198,10 +189,42 @@
while (*datum) {
z *= 0x01000193;
z ^= *datum++;
- (*len)++;
- }
+ }
+ *len = datum - start;
return z;
+}
+
+/**
+ * Iterate through all available hash keys.
+ *
+ * \param ht The hash table context to iterate.
+ * \param c1 Pointer to first context
+ * \param c2 Pointer to second context (set to 0 on first call)
+ * \return The next hash key, or NULL for no more keys
+ */
+
+const char *hash_iterate(struct hash_table *ht, unsigned int *c1, unsigned int **c2) {
+ struct hash_entry **he = (struct hash_entry **)c2;
+
+ if (ht == NULL)
+ return NULL;
+
+ if (!*he)
+ *c1 = -1;
+ else
+ *he = (*he)->next;
+
+ if (*he)
+ return (*he)->pairing;
+
+ while (!*he) {
+ (*c1)++;
+ if (*c1 >= ht->nchains)
+ return NULL;
+ *he = ht->chain[*c1];
+ }
+ return (*he)->pairing;
}
/* A simple test rig. To compile, use:
Modified: trunk/netsurf/utils/hashtable.h
URL: http://svn.semichrome.net/trunk/netsurf/utils/hashtable.h?rev=3013&r1=301...
==============================================================================
--- trunk/netsurf/utils/hashtable.h (original)
+++ trunk/netsurf/utils/hashtable.h Fri Oct 20 13:13:28 2006
@@ -20,5 +20,7 @@
bool hash_add(struct hash_table *ht, const char *key, const char *value);
const char *hash_get(struct hash_table *ht, const char *key);
unsigned int hash_string_fnv(const char *datum, unsigned int *len);
+const char *hash_iterate(struct hash_table *ht, unsigned int *c1,
+ unsigned int **c2);
#endif
16 years, 11 months