diff options
author | Matthias Clasen <mclasen@redhat.com> | 2019-10-15 11:56:16 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-10-15 11:56:16 -0400 |
commit | 0917506dcf843333301d130a264f5b95052b2171 (patch) | |
tree | 52dd6549ef06b2657f5b696c7d7e0abc25483fb8 | |
parent | c7dd1ae04055001ad48cb9da371fa8131118f3b3 (diff) | |
download | glib-faster-contenttype-guess.tar.gz |
xdgmime: Use memmem when we canfaster-contenttype-guess
When comparing magic without a mask, we can use
the optimized function that glibc has for this
purpose.
This makes g_content_type_guess drop from 10%
to 3% in some of my GTK profiles. Still not
ideal. It would be much better if we could
ask 'Which of these 3 types is it?' style
questions.
-rw-r--r-- | gio/xdgmime/xdgmimecache.c | 55 |
1 files changed, 23 insertions, 32 deletions
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c index 769b57836..3150c1cb3 100644 --- a/gio/xdgmime/xdgmimecache.c +++ b/gio/xdgmime/xdgmimecache.c @@ -48,6 +48,10 @@ #include "xdgmimecache.h" #include "xdgmimeint.h" +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif @@ -175,42 +179,29 @@ cache_magic_matchlet_compare_to_data (XdgMimeCache *cache, xdg_uint32_t data_length = GET_UINT32 (cache->buffer, offset + 12); xdg_uint32_t data_offset = GET_UINT32 (cache->buffer, offset + 16); xdg_uint32_t mask_offset = GET_UINT32 (cache->buffer, offset + 20); - + int end; int i, j; + const unsigned char *_buffer = cache->buffer; + const unsigned char *_data = data; + + if (len < data_length) + return FALSE; - for (i = range_start; i < range_start + range_length; i++) - { - int valid_matchlet = TRUE; - - if (i + data_length > len) - return FALSE; + if (mask_offset == 0) + return memmem (_data + range_start, MIN (range_length + data_length, len), _buffer + data_offset, data_length) != NULL; - if (mask_offset) - { - for (j = 0; j < data_length; j++) - { - if ((((unsigned char *)cache->buffer)[data_offset + j] & ((unsigned char *)cache->buffer)[mask_offset + j]) != - ((((unsigned char *) data)[j + i]) & ((unsigned char *)cache->buffer)[mask_offset + j])) - { - valid_matchlet = FALSE; - break; - } - } - } - else - { - for (j = 0; j < data_length; j++) - { - if (((unsigned char *)cache->buffer)[data_offset + j] != ((unsigned char *) data)[j + i]) - { - valid_matchlet = FALSE; - break; - } - } + end = MIN (range_start + range_length, len - data_length); + + for (i = range_start; i < end; i++) + { + for (j = 0; j < data_length; j++) + { + if ((_buffer[data_offset + j] & _buffer[mask_offset + j]) != + (_data[i + j] & _buffer[mask_offset + j])) + break; } - - if (valid_matchlet) - return TRUE; + if (j == data_length) + return TRUE; } return FALSE; |