summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@netsurf-browser.org>2012-03-29 12:27:43 (GMT)
committer Daniel Silverstone <dsilvers@netsurf-browser.org>2012-03-29 12:27:43 (GMT)
commit1e2476627da6e343f9c646fc5e1a6bf179a991c0 (patch)
treef4c4efd6718b07e41bf6ca27c6a608ce89015088
parent76c0dfc52a443b19be0f808e23632d52f721f11a (diff)
downloadlibwapcaplet-1e2476627da6e343f9c646fc5e1a6bf179a991c0.tar.gz
libwapcaplet-1e2476627da6e343f9c646fc5e1a6bf179a991c0.tar.bz2
Rework the majority of wapcaplet's interface to be macros. This removes *many* function call overheads but does require GNUish braced-group expressions.
svn path=/trunk/libwapcaplet/; revision=13777
-rw-r--r--include/libwapcaplet/libwapcaplet.h95
-rw-r--r--src/libwapcaplet.c81
2 files changed, 79 insertions, 97 deletions
diff --git a/include/libwapcaplet/libwapcaplet.h b/include/libwapcaplet/libwapcaplet.h
index 212b928..47d93a6 100644
--- a/include/libwapcaplet/libwapcaplet.h
+++ b/include/libwapcaplet/libwapcaplet.h
@@ -19,11 +19,33 @@ extern "C"
#include <stdint.h>
/**
- * An interned string.
+ * The type of a reference counter used in libwapcaplet.
+ */
+typedef uint32_t lwc_refcounter;
+
+/**
+ * The type of a hash value used in libwapcaplet.
*/
-typedef struct lwc_string_s lwc_string;
+typedef uint32_t lwc_hash;
/**
+ * An interned string.
+ *
+ * NOTE: The contents of this struct are considered *PRIVATE* and may
+ * change in future revisions. Do not rely on them whatsoever.
+ * They're only here at all so that the ref, unref and matches etc can
+ * use them.
+ */
+typedef struct lwc_string_s {
+ struct lwc_string_s ** prevptr;
+ struct lwc_string_s * next;
+ size_t len;
+ lwc_hash hash;
+ lwc_refcounter refcnt;
+ struct lwc_string_s * insensitive;
+} lwc_string;
+
+/**
* String iteration function
*
* @param str A string which has been interned.
@@ -41,11 +63,6 @@ typedef enum lwc_error_e {
} lwc_error;
/**
- * The type of a hash value used in libwapcaplet.
- */
-typedef uint32_t lwc_hash;
-
-/**
* Intern a string.
*
* Take a copy of the string data referred to by \a s and \a slen and
@@ -104,7 +121,7 @@ extern lwc_error lwc_intern_substring(lwc_string *str,
* @note Use this if copying the string and intending both sides to retain
* ownership.
*/
-extern lwc_string *lwc_string_ref(lwc_string *str);
+#define lwc_string_ref(str) ({lwc_string *__lwc_s = (str); __lwc_s->refcnt++; __lwc_s;})
/**
* Release a reference on an lwc_string.
@@ -112,13 +129,27 @@ extern lwc_string *lwc_string_ref(lwc_string *str);
* This decreases the reference count on the given ::lwc_string.
*
* @param str The string to unref.
- * @return The result of the operation, if not OK then the string
- * was not unreffed.
*
* @note If the reference count reaches zero then the string will be
- * freed.
+ * freed. (Ref count of 1 where string is its own insensitve match
+ * will also result in the string being freed.)
*/
-extern void lwc_string_unref(lwc_string *str);
+#define lwc_string_unref(str) { \
+ lwc_string *__lwc_s = (str); \
+ __lwc_s->refcnt--; \
+ if ((__lwc_s->refcnt == 0) || \
+ ((__lwc_s->refcnt == 1) && (__lwc_s->insensitive == __lwc_s))) \
+ lwc_string_destroy(__lwc_s); \
+ }
+
+/**
+ * Destroy an unreffed lwc_string.
+ *
+ * This destroys an lwc_string whose reference count indicates that it should be.
+ *
+ * @param str The string to unref.
+ */
+extern void lwc_string_destroy(lwc_string *str);
/**
* Check if two interned strings are equal.
@@ -141,9 +172,37 @@ extern void lwc_string_unref(lwc_string *str);
* @return Result of operation, if not ok then value pointed to
* by \a ret will not be valid.
*/
-extern lwc_error lwc_string_caseless_isequal(lwc_string *str1,
- lwc_string *str2,
- bool *ret);
+#define lwc_string_caseless_isequal(_str1,_str2,_ret) ({ \
+ lwc_error __lwc_err = lwc_error_ok; \
+ lwc_string *__lwc_str1 = (_str1); \
+ lwc_string *__lwc_str2 = (_str2); \
+ bool *__lwc_ret = (_ret); \
+ \
+ if (__lwc_str1->insensitive == NULL) { \
+ __lwc_err = lwc__intern_caseless_string(__lwc_str1); \
+ } \
+ if (__lwc_err == lwc_error_ok && __lwc_str2->insensitive == NULL) { \
+ __lwc_err = lwc__intern_caseless_string(__lwc_str2); \
+ } \
+ if (__lwc_err == lwc_error_ok) \
+ *__lwc_ret = (__lwc_str1->insensitive == __lwc_str2->insensitive); \
+ __lwc_err; \
+ })
+
+/**
+ * Intern a caseless copy of the passed string.
+ *
+ * @param str The string to intern the caseless copy of.
+ *
+ * @return lwc_error_ok if successful, otherwise the
+ * error code describing the issue.,
+ *
+ * @note This is for "internal" use by the caseless comparison
+ * macro and not for users.
+ */
+extern lwc_error
+lwc__intern_caseless_string(lwc_string *str);
+
/**
* Retrieve the data pointer for an interned string.
*
@@ -156,7 +215,7 @@ extern lwc_error lwc_string_caseless_isequal(lwc_string *str1,
* in future. Any code relying on it currently should be
* modified to use ::lwc_string_length if possible.
*/
-extern const char *lwc_string_data(const lwc_string *str);
+#define lwc_string_data(str) ((const char *)((str)+1))
/**
* Retrieve the data length for an interned string.
@@ -164,7 +223,7 @@ extern const char *lwc_string_data(const lwc_string *str);
* @param str The string to retrieve the length of.
* @return The length of \a str.
*/
-extern size_t lwc_string_length(const lwc_string *str);
+#define lwc_string_length(str) ((str)->len)
/**
* Retrieve (or compute if unavailable) a hash value for the content of the string.
@@ -178,7 +237,7 @@ extern size_t lwc_string_length(const lwc_string *str);
* to be stable between invocations of the program. Never use the hash
* value as a way to directly identify the value of the string.
*/
-extern uint32_t lwc_string_hash_value(lwc_string *str);
+#define lwc_string_hash_value(str) ((str)->hash)
/**
* Iterate the context and return every string in it.
diff --git a/src/libwapcaplet.c b/src/libwapcaplet.c
index 5ae655a..bd20abc 100644
--- a/src/libwapcaplet.c
+++ b/src/libwapcaplet.c
@@ -16,8 +16,6 @@
#define UNUSED(x) ((x) = (x))
#endif
-typedef uint32_t lwc_refcounter;
-
static inline lwc_hash
lwc__calculate_hash(const char *str, size_t len)
{
@@ -33,15 +31,6 @@ lwc__calculate_hash(const char *str, size_t len)
return z;
}
-struct lwc_string_s {
- lwc_string ** prevptr;
- lwc_string * next;
- size_t len;
- lwc_hash hash;
- lwc_refcounter refcnt;
- lwc_string * insensitive;
-};
-
#define STR_OF(str) ((char *)(str + 1))
#define CSTR_OF(str) ((const char *)(str + 1))
@@ -174,27 +163,11 @@ lwc_intern_substring(lwc_string *str,
return lwc_intern_string(CSTR_OF(str) + ssoffset, sslen, ret);
}
-lwc_string *
-lwc_string_ref(lwc_string *str)
-{
- assert(str);
-
- str->refcnt++;
-
- return str;
-}
-
void
-lwc_string_unref(lwc_string *str)
+lwc_string_destroy(lwc_string *str)
{
assert(str);
- if (--(str->refcnt) > 1)
- return;
-
- if ((str->refcnt == 1) && (str->insensitive != str))
- return;
-
*(str->prevptr) = str->next;
if (str->next != NULL)
@@ -254,7 +227,7 @@ lwc__lcase_memcpy(char *target, const char *source, size_t n)
}
}
-static lwc_error
+lwc_error
lwc__intern_caseless_string(lwc_string *str)
{
assert(str);
@@ -267,56 +240,6 @@ lwc__intern_caseless_string(lwc_string *str)
lwc__lcase_memcpy);
}
-lwc_error
-lwc_string_caseless_isequal(lwc_string *str1,
- lwc_string *str2,
- bool *ret)
-{
- lwc_error err;
- assert(str1);
- assert(str2);
-
- if (str1->insensitive == NULL) {
- err = lwc__intern_caseless_string(str1);
- if (err != lwc_error_ok)
- return err;
- }
- if (str2->insensitive == NULL) {
- err = lwc__intern_caseless_string(str2);
- if (err != lwc_error_ok)
- return err;
- }
-
- *ret = (str1->insensitive == str2->insensitive);
- return lwc_error_ok;
-}
-
-/**** Simple accessors ****/
-
-const char *
-lwc_string_data(const lwc_string *str)
-{
- assert(str);
-
- return CSTR_OF(str);
-}
-
-size_t
-lwc_string_length(const lwc_string *str)
-{
- assert(str);
-
- return str->len;
-}
-
-uint32_t
-lwc_string_hash_value(lwc_string *str)
-{
- assert(str);
-
- return str->hash;
-}
-
/**** Iteration ****/
void