📄 misc.c
字号:
/* * File: misc.c * * Copyright (C) 2000 Jorge Arellano Cid <jcid@dillo.org>, * J鰎gen Viksell <vsksga@hotmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */#include <gtk/gtk.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <ctype.h>#include "msg.h"#include "misc.h"/* * Prepend the users home-dir to 'file' string i.e, * pass in .dillo/bookmarks.html and it will return * /home/imain/.dillo/bookmarks.html * * Remember to g_free() returned value! */gchar *a_Misc_prepend_user_home(const char *file){ return ( g_strconcat(g_get_home_dir(), "/", file, NULL) );}/* * Escape characters as %XX sequences. * Return value: New string, or NULL if there's no need to escape. */gchar *a_Misc_escape_chars(const gchar *str, gchar *esc_set){ static const char *hex = "0123456789ABCDEF"; gchar *p = NULL; GString *gstr; gint i; for (i = 0; str[i]; ++i) if (str[i] <= 0x1F || str[i] == 0x7F || strchr(esc_set, str[i])) break; if (str[i]) { /* needs escaping */ gstr = g_string_sized_new(64); for (i = 0; str[i]; ++i) { if (str[i] <= 0x1F || str[i] == 0x7F || strchr(esc_set, str[i])) { g_string_append_c(gstr, '%'); g_string_append_c(gstr, hex[(str[i] >> 4) & 15]); g_string_append_c(gstr, hex[str[i] & 15]); } else { g_string_append_c(gstr, str[i]); } } p = gstr->str; g_string_free(gstr, FALSE); } return p;}/* * Use character stuffing for characters given in 'esc_set'. * Return value: a stuffed new string. * Note: formerly it returned NULL when there was no need to stuff, * now it always returns a new string. Simplicity. */gchar *a_Misc_stuff_chars(const gchar *str, const gchar *esc_set){ gint i; gchar *p, *sstr = NULL; if ((p = strpbrk(str, esc_set))) { /* start stuffing */ GString *gstr = g_string_new(str); for (i = p - str; gstr->str[i]; ++i) if (strchr(esc_set, gstr->str[i])) { g_string_insert_c(gstr, i, gstr->str[i]); ++i; } sstr = gstr->str; g_string_free(gstr, FALSE); } return (sstr ? sstr : g_strdup(str));}/* * Case insensitive strstr */gchar *a_Misc_stristr(char *src, char *str){ int i, j; for (i = 0, j = 0; src[i] && str[j]; ++i) if (tolower(src[i]) == tolower(str[j])) { ++j; } else if (j) { i -= j; j = 0; } if (!str[j]) /* Got all */ return (src + i - j); return NULL;}/* * strsep implementation */gchar *a_Misc_strsep(char **orig, const char *delim){ gchar *str, *p; if (!(str = *orig)) return NULL; p = strpbrk(str, delim); if (p) { *p++ = 0; *orig = p; } else { *orig = NULL; } return str;}#define TAB_SIZE 8/* * Takes a string and converts any tabs to spaces. */gchar *a_Misc_expand_tabs(const char *str){ GString *New = g_string_new(""); int len, i, j, pos, old_pos; char *val; if ( (len = strlen(str)) ) { for (pos = 0, i = 0; i < len; i++) { if (str[i] == '\t') { /* Fill with whitespaces until the next tab. */ old_pos = pos; pos += TAB_SIZE - (pos % TAB_SIZE); for (j = old_pos; j < pos; j++) g_string_append_c(New, ' '); } else { g_string_append_c(New, str[i]); pos++; } } } val = New->str; g_string_free(New, FALSE); return val;}/* * Split a string into tokens, at any character contained by delim, * and return the starting and ending positions within the string. For * n tokens, the returned array has at least 2 * n + 1 elements, and * contains the start of token i at 2 * i, the end at 2 * i + 1. The * array is terminated by -1. */gint *a_Misc_strsplitpos(const gchar *str, const gchar *delim){ gint array_max = 4; gint *array = g_new(gint, array_max); gint n = 0; gint p1 = 0, p2; while (TRUE) { while (str[p1] != 0 && strchr(delim, str[p1]) != NULL) p1++; if (str[p1] == 0) break; p2 = p1; while (str[p2] != 0 && strchr(delim, str[p2]) == NULL) p2++; if (array_max < 2 * n + 3) { array_max <<= 2; array = g_realloc(array, array_max * sizeof(gint)); } array[2 * n] = p1; array[2 * n + 1] = p2; n++; if (str[p2] == 0) break; else { p1 = p2; } } array[2 * n] = -1; return array;}/* * Return a copy of an array which was created by a_Misc_strsplitpos. */gint *a_Misc_strsplitposdup(gint *pos){ gint n = 0; gint *pos2; while (pos[2 * n] != -1) n++; pos2 = g_new(gint, 2 * n + 1); memcpy(pos2, pos, (2 * n + 1) * sizeof(gint)); return pos2;}/* * Detects 'Content-Type' when the server does not supply one. * It uses the magic(5) logic from file(1). Currently, it * only checks the few mime types that Dillo supports. * * 'Data' is a pointer to the first bytes of the raw data. */const gchar *a_Misc_get_content_type_from_data(void *Data, size_t Size){ static const gchar *Types[] = { "application/octet-stream", "text/html", "text/plain", "image/gif", "image/png", "image/jpeg", }; gint Type = 0; gchar *p = Data; size_t i; /* HTML try */ for (i = 0; i < Size && isspace(p[i]); ++i); if ((Size - i >= 5 && !g_strncasecmp(p+i, "<html", 5)) || (Size - i >= 5 && !g_strncasecmp(p+i, "<head", 5)) || (Size - i >= 6 && !g_strncasecmp(p+i, "<title", 6)) || (Size - i >= 14 && !g_strncasecmp(p+i, "<!doctype html", 14)) || /* this line is workaround for FTP through the Squid proxy */ (Size - i >= 17 && !g_strncasecmp(p+i, "<!-- HTML listing", 17))) { Type = 1; /* Images */ } else if (Size >= 4 && !g_strncasecmp(p, "GIF8", 4)) { Type = 3; } else if (Size >= 4 && !g_strncasecmp(p, "\x89PNG", 4)) { Type = 4; } else if (Size >= 2 && !g_strncasecmp(p, "\xff\xd8", 2)) { /* JPEG has the first 2 bytes set to 0xffd8 in BigEndian - looking * at the character representation should be machine independent. */ Type = 5; /* Text */ } else { /* We'll assume ASCII if chars are below 128 (after all, this * is a last resort when the server doesn't send Content-Type) */ Size = MIN (Size, 256); for (i = 0; i < Size; i++) if ((guchar) p[i] > 127) break; Type = (i < 12 || i < Size) ? 0 : 2; } return (Types[Type]);}/* * Parse a geometry string. */gint a_Misc_parse_geometry(gchar *str, gint *x, gint *y, gint *w, gint *h){ gchar *p, *t1, *t2; gint n1, n2; gint ret = 0; if ((p = strchr(str, 'x')) || (p = strchr(str, 'X'))) { n1 = strtol(str, &t1, 10); n2 = strtol(++p, &t2, 10); if (t1 != str && t2 != p) { *w = n1; *h = n2; ret = 1; /* parse x,y now */ p = t2; n1 = strtol(p, &t1, 10); n2 = strtol(t1, &t2, 10); if (t1 != p && t2 != t1) { *x = n1; *y = n2; } } } _MSG("geom: w,h,x,y = (%d,%d,%d,%d)\n", *w, *h, *x, *y); return ret;}/* * Encodes string using base64 encoding. * Return value: new string or NULL if input string is empty. */gchar *a_Misc_encode_base64(const gchar *in){ static const char *base64_hex = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; gchar *out = NULL; int len, i = 0; if (in == NULL) return NULL; len = strlen(in); out = (gchar *)g_malloc((len + 2) / 3 * 4 + 1); for (; len >= 3; len -= 3) { out[i++] = base64_hex[in[0] >> 2]; out[i++] = base64_hex[((in[0]<<4) & 0x30) | (in[1]>>4)]; out[i++] = base64_hex[((in[1]<<2) & 0x3c) | (in[2]>>6)]; out[i++] = base64_hex[in[2] & 0x3f]; in += 3; } if (len > 0) { unsigned char fragment; out[i++] = base64_hex[in[0] >> 2]; fragment = (in[0] << 4) & 0x30; if (len > 1) fragment |= in[1] >> 4; out[i++] = base64_hex[fragment]; out[i++] = (len < 2) ? '=' : base64_hex[(in[1] << 2) & 0x3c]; out[i++] = '='; } out[i] = '\0'; return out;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -