/** callback to initialise the resource fetcher. */ static bool fetch_resource_initialise(lwc_string *scheme) { struct fetch_resource_map_entry *e; uint32_t i; fetch_resource_path_count = 0; for (i = 0; i < NOF_ELEMENTS(fetch_resource_paths); i++) { e = &fetch_resource_map[fetch_resource_path_count]; if (lwc_intern_string(fetch_resource_paths[i], strlen(fetch_resource_paths[i]), &e->path) != lwc_error_ok) { while (i > 0) { i--; lwc_string_unref(fetch_resource_map[i].path); nsurl_unref(fetch_resource_map[i].url); } } e->url = gui_get_resource_url(fetch_resource_paths[i]); LOG(("URL is %s " ,lwc_string_data(e->path))); if (e->url == NULL) { lwc_string_unref(e->path); } else { fetch_resource_path_count++; } } return true; }
/* exported function documented in fbtk.h */ int fbtk_keycode_to_ucs4(int code, fbtk_modifier_type mods) { int ucs4 = -1; if (mods & FBTK_MOD_LSHIFT || mods & FBTK_MOD_RSHIFT) { if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap))) ucs4 = sh_keymap[code]; } else if (mods == FBTK_MOD_CLEAR) { if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap))) ucs4 = keymap[code]; } else if (mods & FBTK_MOD_LCTRL || mods & FBTK_MOD_RCTRL) { switch (code) { case NSFB_KEY_a: ucs4 = NS_KEY_SELECT_ALL; break; case NSFB_KEY_c: ucs4 = NS_KEY_COPY_SELECTION; break; case NSFB_KEY_u: ucs4 = NS_KEY_DELETE_LINE; break; case NSFB_KEY_v: ucs4 = NS_KEY_PASTE; break; case NSFB_KEY_x: ucs4 = NS_KEY_CUT_SELECTION; break; case NSFB_KEY_z: ucs4 = NS_KEY_CLEAR_SELECTION; break; default: break; } } return ucs4; }
/** * Convert a string encoded in the system local encoding to UTF-8 * * \param string The string to convert * \param len The length (in bytes) of the string, or 0 * \param result Pointer to location in which to store result * \return An nserror code */ nserror utf8_from_local_encoding(const char *string, size_t len, char **result) { os_error *error; int alphabet, i, num_specials = 0, result_alloc; #define SPECIAL_CHUNK_SIZE 255 size_t off, prev_off, cur_off; char *temp; const char *enc; nserror err; assert(string && result); /* get length, if necessary */ if (len == 0) len = strlen(string); /* read system alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) alphabet = territory_ALPHABET_LATIN1; /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { temp = strndup(string, len); if (!temp) return NSERROR_NOMEM; *result = temp; return NSERROR_OK; } /* get encoding name */ enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] : (alphabet == 120 ? localencodings[CONT_ENC_END - 100 + 1] : localencodings[0])); /* create output buffer (oversized) */ result_alloc = (len * 4) + (3 * SPECIAL_CHUNK_SIZE) + 1; *(result) = malloc(result_alloc); if (!(*result)) return NSERROR_NOMEM; *(*result) = '\0'; prev_off = 0; cur_off = 0; /* Iterate over string, converting input between unconvertable * characters and inserting appropriate output for characters * that iconv can't handle. */ for (off = 0; off < len; off++) { if (string[off] < 0x80 || string[off] > 0x9f) continue; for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { if (string[off] != special_chars[i].local) continue; /* 0 length has a special meaning to utf8_from_enc */ if (off - prev_off > 0) { err = utf8_from_enc(string + prev_off, enc, off - prev_off, &temp, NULL); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG("utf8_from_enc failed"); free(*result); return NSERROR_NOMEM; } strcat((*result) + cur_off, temp); cur_off += strlen(temp); free(temp); } strcat((*result) + cur_off, special_chars[i].utf); cur_off += special_chars[i].len; prev_off = off + 1; num_specials++; if (num_specials % SPECIAL_CHUNK_SIZE == SPECIAL_CHUNK_SIZE - 1) { char *temp = realloc((*result), result_alloc + (3 * SPECIAL_CHUNK_SIZE)); if (!temp) { free(*result); return NSERROR_NOMEM; } *result = temp; result_alloc += (3 * SPECIAL_CHUNK_SIZE); } } } /* handle last chunk * NB. 0 length has a special meaning to utf8_from_enc */ if (prev_off < len) { err = utf8_from_enc(string + prev_off, enc, len - prev_off, &temp, NULL); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); LOG("utf8_from_enc failed"); free(*result); return NSERROR_NOMEM; } strcat((*result) + cur_off, temp); cur_off += strlen(temp); free(temp); } /* and copy into more reasonably-sized buffer */ temp = realloc((*result), cur_off + 1); if (!temp) { LOG("realloc failed"); free(*result); return NSERROR_NOMEM; } *result = temp; return NSERROR_OK; }
/** * Convert a UTF-8 encoded string into the system local encoding * * \param string The string to convert * \param len The length (in bytes) of the string, or 0 * \param result Pointer to location in which to store result * \return An nserror code */ nserror utf8_to_local_encoding(const char *string, size_t len, char **result) { os_error *error; int alphabet, i; size_t off, prev_off; char *temp, *cur_pos; const char *enc; nserror err; assert(string); assert(result); /* get length, if necessary */ if (len == 0) len = strlen(string); /* read system alphabet */ error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0, &alphabet); if (error) alphabet = territory_ALPHABET_LATIN1; /* UTF-8 -> simply copy string */ if (alphabet == 111 /* UTF-8 */) { *result = strndup(string, len); return NSERROR_OK; } /* get encoding name */ enc = (alphabet <= CONT_ENC_END ? localencodings[alphabet - 100] : (alphabet == 120 ? localencodings[CONT_ENC_END - 100 + 1] : localencodings[0])); /* create output buffer */ *(result) = malloc(len + 1); if (!(*result)) return NSERROR_NOMEM; *(*result) = '\0'; prev_off = 0; cur_pos = (*result); /* Iterate over string, converting input between unconvertable * characters and inserting appropriate output for characters * that iconv can't handle. */ for (off = 0; off < len; off = utf8_next(string, len, off)) { if (string[off] != 0xE2 && string[off] != 0xC5 && string[off] != 0xEF) continue; for (i = 0; i != NOF_ELEMENTS(special_chars); i++) { if (strncmp(string + off, special_chars[i].utf, special_chars[i].len) != 0) continue; /* 0 length has a special meaning to utf8_to_enc */ if (off - prev_off > 0) { err = utf8_to_enc(string + prev_off, enc, off - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); cur_pos += strlen(temp); free(temp); } *cur_pos = special_chars[i].local; *(++cur_pos) = '\0'; prev_off = off + special_chars[i].len; } } /* handle last chunk * NB. 0 length has a special meaning to utf8_to_enc */ if (prev_off < len) { err = utf8_to_enc(string + prev_off, enc, len - prev_off, &temp); if (err != NSERROR_OK) { assert(err != NSERROR_BAD_ENCODING); free(*result); return NSERROR_NOMEM; } strcat(cur_pos, temp); free(temp); } return NSERROR_OK; }
static const char *find_pattern(const char *string, int s_len, const char *pattern, int p_len, bool case_sens, unsigned int *m_len) { struct { const char *ss, *s, *p; bool first; } context[16]; const char *ep = pattern + p_len; const char *es = string + s_len; const char *p = pattern - 1; /* a virtual '*' before the pattern */ const char *ss = string; const char *s = string; bool first = true; int top = 0; while (p < ep) { bool matches; if (p < pattern || *p == '*') { char ch; /* skip any further asterisks; one is the same as many */ do p++; while (p < ep && *p == '*'); /* if we're at the end of the pattern, yes, it matches */ if (p >= ep) break; /* anything matches a # so continue matching from here, and stack a context that will try to match the wildcard against the next character */ ch = *p; if (ch != '#') { /* scan forwards until we find a match for this char */ if (!case_sens) ch = toupper(ch); while (s < es) { if (case_sens) { if (*s == ch) break; } else if (toupper(*s) == ch) break; s++; } } if (s < es) { /* remember where we are in case the match fails; we may then resume */ if (top < (int)NOF_ELEMENTS(context)) { context[top].ss = ss; context[top].s = s + 1; context[top].p = p - 1; /* ptr to last asterisk */ context[top].first = first; top++; } if (first) { ss = s; /* remember first non-'*' char */ first = false; } matches = true; } else { matches = false; } } else if (s < es) { char ch = *p; if (ch == '#') matches = true; else { if (case_sens) matches = (*s == ch); else matches = (toupper(*s) == toupper(ch)); } if (matches && first) { ss = s; /* remember first non-'*' char */ first = false; } } else { matches = false; } if (matches) { p++; s++; } else { /* doesn't match, * resume with stacked context if we have one */ if (--top < 0) return NULL; /* no match, give up */ ss = context[top].ss; s = context[top].s; p = context[top].p; first = context[top].first; } } /* end of pattern reached */ *m_len = max(s - ss, 1); return ss; }
static const char *fetch_resource_paths[] = { "adblock.css", "default.css", "internal.css", "quirks.css", "user.css", "credits.html", "licence.html", "welcome.html", "favicon.ico", "netsurf.png" }; static struct fetch_resource_map_entry { lwc_string *path; nsurl *url; } fetch_resource_map[NOF_ELEMENTS(fetch_resource_paths)]; static uint32_t fetch_resource_path_count; /** issue fetch callbacks with locking */ static inline bool fetch_resource_send_callback(const fetch_msg *msg, struct fetch_resource_context *ctx) { ctx->locked = true; fetch_send_callback(msg, ctx->fetchh); ctx->locked = false; return ctx->aborted; } static bool fetch_resource_send_header(struct fetch_resource_context *ctx,