css_error node_has_attribute_prefix(void *pw, void *n, const css_qname *qname, lwc_string *value, bool *match) { node *node = n; uint32_t i; UNUSED(pw); *match = false; for (i = 0; i < node->n_attrs; i++) { assert(lwc_string_caseless_isequal( node->attrs[i].name, qname->name, match) == lwc_error_ok); if (*match == true) break; } if (*match == true) { size_t len = lwc_string_length(node->attrs[i].value); const char *data = lwc_string_data(node->attrs[i].value); size_t vlen = lwc_string_length(value); const char *vdata = lwc_string_data(value); if (len < vlen) *match = false; else *match = (strncasecmp(data, vdata, vlen) == 0); } return CSS_OK; }
/** * Callback to determine if a node has an attribute with the given name whose * value contains the substring given. * * \param pw HTML document * \param node DOM node * \param qname Name to match * \param value Value to match * \param match Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_has_attribute_substring(void *pw, void *node, const css_qname *qname, lwc_string *value, bool *match) { dom_node *n = node; dom_string *name; dom_string *atr_val; dom_exception err; size_t vlen = lwc_string_length(value); if (vlen == 0) { *match = false; return CSS_OK; } err = dom_string_create_interned( (const uint8_t *) lwc_string_data(qname->name), lwc_string_length(qname->name), &name); if (err != DOM_NO_ERR) return CSS_NOMEM; err = dom_element_get_attribute(n, name, &atr_val); if ((err != DOM_NO_ERR) || (atr_val == NULL)) { dom_string_unref(name); *match = false; return CSS_OK; } dom_string_unref(name); /* check for exact match */ *match = dom_string_caseless_lwc_isequal(atr_val, value); /* check for prefix match */ if (*match == false) { const char *vdata = lwc_string_data(value); const char *start = (const char *) dom_string_data(atr_val); size_t len = dom_string_byte_length(atr_val); const char *last_start = start + len - vlen; if (len >= vlen) { while (start <= last_start) { if (strncasecmp(start, vdata, vlen) == 0) { *match = true; break; } start++; } } } dom_string_unref(atr_val); return CSS_OK; }
/** * Callback to determine if a node has an attribute with the given name whose * value includes that given. * * \param pw HTML document * \param node DOM node * \param qname Name to match * \param value Value to match * \param match Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_has_attribute_includes(void *pw, void *node, const css_qname *qname, lwc_string *value, bool *match) { dom_node *n = node; dom_string *name; dom_string *atr_val; dom_exception err; size_t vlen = lwc_string_length(value); const char *p; const char *start; const char *end; *match = false; if (vlen == 0) { return CSS_OK; } err = dom_string_create_interned( (const uint8_t *) lwc_string_data(qname->name), lwc_string_length(qname->name), &name); if (err != DOM_NO_ERR) return CSS_NOMEM; err = dom_element_get_attribute(n, name, &atr_val); if ((err != DOM_NO_ERR) || (atr_val == NULL)) { dom_string_unref(name); *match = false; return CSS_OK; } dom_string_unref(name); /* check for match */ start = (const char *) dom_string_data(atr_val); end = start + dom_string_byte_length(atr_val); for (p = start; p <= end; p++) { if (*p == ' ' || *p == '\0') { if ((size_t) (p - start) == vlen && strncasecmp(start, lwc_string_data(value), vlen) == 0) { *match = true; break; } start = p + 1; } } dom_string_unref(atr_val); return CSS_OK; }
/** * Callback to determine if a node has an attribute with the given name whose * value dashmatches that given. * * \param pw HTML document * \param node DOM node * \param qname Name to match * \param value Value to match * \param match Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_has_attribute_dashmatch(void *pw, void *node, const css_qname *qname, lwc_string *value, bool *match) { dom_node *n = node; dom_string *name; dom_string *atr_val; dom_exception err; size_t vlen = lwc_string_length(value); if (vlen == 0) { *match = false; return CSS_OK; } err = dom_string_create_interned( (const uint8_t *) lwc_string_data(qname->name), lwc_string_length(qname->name), &name); if (err != DOM_NO_ERR) return CSS_NOMEM; err = dom_element_get_attribute(n, name, &atr_val); if ((err != DOM_NO_ERR) || (atr_val == NULL)) { dom_string_unref(name); *match = false; return CSS_OK; } dom_string_unref(name); /* check for exact match */ *match = dom_string_caseless_lwc_isequal(atr_val, value); /* check for dashmatch */ if (*match == false) { const char *vdata = lwc_string_data(value); const char *data = (const char *) dom_string_data(atr_val); size_t len = dom_string_byte_length(atr_val); if (len > vlen && data[vlen] == '-' && strncasecmp(data, vdata, vlen) == 0) { *match = true; } } dom_string_unref(atr_val); return CSS_OK; }
/** * Finalise a cURL fetcher. * * \param scheme The scheme to finalise. */ static void fetch_curl_finalise(lwc_string *scheme) { struct cache_handle *h; curl_fetchers_registered--; LOG("Finalise cURL fetcher %s", lwc_string_data(scheme)); if (curl_fetchers_registered == 0) { CURLMcode codem; /* All the fetchers have been finalised. */ LOG("All cURL fetchers finalised, closing down cURL"); curl_easy_cleanup(fetch_blank_curl); codem = curl_multi_cleanup(fetch_curl_multi); if (codem != CURLM_OK) LOG("curl_multi_cleanup failed: ignoring"); curl_global_cleanup(); } /* Free anything remaining in the cached curl handle ring */ while (curl_handle_ring != NULL) { h = curl_handle_ring; RING_REMOVE(curl_handle_ring, h); lwc_string_unref(h->host); curl_easy_cleanup(h->handle); free(h); } }
/** * Parse a hash colour (#rgb or #rrggbb) * * \param data Pointer to colour string * \param result Pointer to location to receive result (AARRGGBB) * \return CSS_OK on success, * CSS_INVALID if the input is invalid */ css_error css__parse_hash_colour(lwc_string *data, uint32_t *result) { uint8_t r = 0, g = 0, b = 0, a = 0xff; size_t len = lwc_string_length(data); const char *input = lwc_string_data(data); if (len == 3 && isHex(input[0]) && isHex(input[1]) && isHex(input[2])) { r = charToHex(input[0]); g = charToHex(input[1]); b = charToHex(input[2]); r |= (r << 4); g |= (g << 4); b |= (b << 4); } else if (len == 6 && isHex(input[0]) && isHex(input[1]) && isHex(input[2]) && isHex(input[3]) && isHex(input[4]) && isHex(input[5])) { r = (charToHex(input[0]) << 4); r |= charToHex(input[1]); g = (charToHex(input[2]) << 4); g |= charToHex(input[3]); b = (charToHex(input[4]) << 4); b |= charToHex(input[5]); } else return CSS_INVALID; *result = (a << 24) | (r << 16) | (g << 8) | b; return CSS_OK; }
/** 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; }
static bool fetch_data_initialise(lwc_string *scheme) { NSLOG(netsurf, INFO, "fetch_data_initialise called for %s", lwc_string_data(scheme)); return true; }
css_error node_has_attribute_substring(void *pw, void *n, const css_qname *qname, lwc_string *value, bool *match) { node *node = n; uint32_t i; UNUSED(pw); *match = false; for (i = 0; i < node->n_attrs; i++) { assert(lwc_string_caseless_isequal( node->attrs[i].name, qname->name, match) == lwc_error_ok); if (*match == true) break; } if (*match == true) { size_t len = lwc_string_length(node->attrs[i].value); const char *data = lwc_string_data(node->attrs[i].value); size_t vlen = lwc_string_length(value); const char *vdata = lwc_string_data(value); const char *last_start = data + len - vlen; if (len < vlen) *match = false; else { while (data <= last_start) { if (strncasecmp(data, vdata, vlen) == 0) { *match = true; break; } data++; } if (data > last_start) *match = false; } } return CSS_OK; }
/** * Initialise a CSS content * * \param c Content to initialise * \param params Content-Type parameters * \return true on success, false on failure */ nserror nscss_create(const content_handler *handler, lwc_string *imime_type, const http_parameter *params, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) { nscss_content *result; const char *charset = NULL; const char *xnsbase = NULL; lwc_string *charset_value = NULL; union content_msg_data msg_data; nserror error; result = calloc(1, sizeof(nscss_content)); if (result == NULL) return NSERROR_NOMEM; error = content__init(&result->base, handler, imime_type, params, llcache, fallback_charset, quirks); if (error != NSERROR_OK) { free(result); return error; } /* Find charset specified on HTTP layer, if any */ error = http_parameter_list_find_item(params, css_charset, &charset_value); if (error != NSERROR_OK || lwc_string_length(charset_value) == 0) { /* No charset specified, use fallback, if any */ /** \todo libcss will take this as gospel, which is wrong */ charset = fallback_charset; } else { charset = lwc_string_data(charset_value); } /* Compute base URL for stylesheet */ xnsbase = llcache_handle_get_header(llcache, "X-NS-Base"); if (xnsbase == NULL) { xnsbase = nsurl_access(content_get_url(&result->base)); } error = nscss_create_css_data(&result->data, xnsbase, charset, result->base.quirks, nscss_content_done, result); if (error != NSERROR_OK) { msg_data.error = messages_get("NoMemory"); content_broadcast(&result->base, CONTENT_MSG_ERROR, msg_data); if (charset_value != NULL) lwc_string_unref(charset_value); free(result); return error; } if (charset_value != NULL) lwc_string_unref(charset_value); *c = (struct content *) result; return NSERROR_OK; }
static void netsurf_lwc_iterator(lwc_string *str, void *pw) { fprintf(stderr, "[%3u] %.*s", str->refcnt, (int)lwc_string_length(str), lwc_string_data(str)); }
static bool fetch_data_initialise(lwc_string *scheme) { LOG("fetch_data_initialise called for %s", lwc_string_data(scheme)); if ( (curl = curl_easy_init()) == NULL) return false; else return true; }
static void printing_lwc_iterator(lwc_string *str, void *pw) { UNUSED(pw); printf(" DICT: %*s\n", (int)(lwc_string_length(str)), lwc_string_data(str)); fail_because_lwc_leaked = true; }
css_error node_has_attribute_dashmatch(void *pw, void *n, const css_qname *qname, lwc_string *value, bool *match) { node *node = n; uint32_t i; size_t vlen = lwc_string_length(value); UNUSED(pw); *match = false; for (i = 0; i < node->n_attrs; i++) { assert(lwc_string_caseless_isequal( node->attrs[i].name, qname->name, match) == lwc_error_ok); if (*match == true) break; } if (*match == true) { const char *p; const char *start = lwc_string_data(node->attrs[i].value); const char *end = start + lwc_string_length(node->attrs[i].value); *match = false; for (p = start; p < end; p++) { if (*p == '-') { if ((size_t) (p - start) == vlen && strncasecmp(start, lwc_string_data(value), vlen) == 0) { *match = true; break; } start = p + 1; } } } return CSS_OK; }
/** * Get the raw character data of the dom_string. * * \param str The dom_string object * \return The C string pointer * * @note: This function is just provided for the convenience of accessing the * raw C string character, no change on the result string is allowed. */ const char *dom_string_data(const dom_string *str) { dom_string_internal *istr = (dom_string_internal *) str; if (istr->type == DOM_STRING_CDATA) { return (const char *) istr->data.cdata.ptr; } else { return lwc_string_data(istr->data.intern); } }
/** * Create a path from a nsurl using amiga file handling. * * @param[in] url The url to encode. * @param[out] path_out A string containing the result path which should * be freed by the caller. * @return NSERROR_OK and the path is written to \a path or error code * on faliure. */ static nserror amiga_nsurl_to_path(struct nsurl *url, char **path_out) { lwc_string *urlpath; char *path; bool match; lwc_string *scheme; nserror res; char *colon; char *slash; if ((url == NULL) || (path_out == NULL)) { return NSERROR_BAD_PARAMETER; } scheme = nsurl_get_component(url, NSURL_SCHEME); if (lwc_string_caseless_isequal(scheme, corestring_lwc_file, &match) != lwc_error_ok) { return NSERROR_BAD_PARAMETER; } lwc_string_unref(scheme); if (match == false) { return NSERROR_BAD_PARAMETER; } urlpath = nsurl_get_component(url, NSURL_PATH); if (urlpath == NULL) { return NSERROR_BAD_PARAMETER; } res = url_unescape(lwc_string_data(urlpath) + 1, &path); lwc_string_unref(urlpath); if (res != NSERROR_OK) { return res; } colon = strchr(path, ':'); if(colon == NULL) { slash = strchr(path, '/'); if(slash) { *slash = ':'; } else { int len = strlen(path); path[len] = ':'; path[len + 1] = '\0'; } } *path_out = path; return NSERROR_OK; }
END_TEST START_TEST (test_lwc_extract_data_ok) { fail_unless(memcmp("one", lwc_string_data(intern_one), lwc_string_length(intern_one)) == 0, "Extracting data ptr etc failed"); }
END_TEST START_TEST (test_lwc_string_is_nul_terminated) { lwc_string *new_ONE; fail_unless(lwc_intern_string("ONE", 3, &new_ONE) == lwc_error_ok, "Failure interning 'ONE'"); fail_unless(lwc_string_data(new_ONE)[lwc_string_length(new_ONE)] == '\0', "Interned string isn't NUL terminated"); }
/* exported interface documented in content/fetch.h */ void fetch_quit(void) { while (fetchers != NULL) { if (fetchers->refcount != 1) { LOG(("Fetcher for scheme %s still active?!", lwc_string_data(fetchers->scheme_name))); /* We shouldn't do this, but... */ fetchers->refcount = 1; } fetch_unref_fetcher(fetchers); } }
css_fixed css__number_from_lwc_string(lwc_string *string, bool int_only, size_t *consumed) { if (string == NULL || lwc_string_length(string) == 0 || consumed == NULL) return 0; return css__number_from_string( (uint8_t *)lwc_string_data(string), lwc_string_length(string), int_only, consumed); }
/** * Try and find the correct RISC OS filetype from a download context. */ static nserror download_ro_filetype(download_context *ctx, bits *ftype_out) { nsurl *url = download_context_get_url(ctx); bits ftype = 0; lwc_string *scheme; /* If the file is local try and read its filetype */ scheme = nsurl_get_component(url, NSURL_SCHEME); if (scheme != NULL) { bool filescheme; if (lwc_string_isequal(scheme, corestring_lwc_file, &filescheme) != lwc_error_ok) { filescheme = false; } if (filescheme) { lwc_string *path = nsurl_get_component(url, NSURL_PATH); if (path != NULL && lwc_string_length(path) != 0) { char *raw_path; if (url_unescape(lwc_string_data(path), lwc_string_length(path), &raw_path) == NSERROR_OK) { ftype = ro_filetype_from_unix_path(raw_path); free(raw_path); } } } } /* If we still don't have a filetype (i.e. failed reading local * one or fetching a remote object), then use the MIME type. */ if (ftype == 0) { /* convert MIME type to RISC OS file type */ os_error *error; const char *mime_type; mime_type = download_context_get_mime_type(ctx); error = xmimemaptranslate_mime_type_to_filetype(mime_type, &ftype); if (error) { LOG("xmimemaptranslate_mime_type_to_filetype: 0x%x: %s", error->errnum, error->errmess); ro_warn_user("MiscError", error->errmess); ftype = 0xffd; } } *ftype_out = ftype; return NSERROR_OK; }
css_error node_has_name(void *pw, void *n, const css_qname *qname, bool *match) { node *node = n; UNUSED(pw); if (lwc_string_length(qname->name) == 1 && lwc_string_data(qname->name)[0] == '*') *match = true; else assert(lwc_string_caseless_isequal(node->name, qname->name, match) == lwc_error_ok); return CSS_OK; }
//void create_login_window(struct browser_window *bw, const char *host, // const char *realm, const char *fetchurl) static void create_login_window(nsurl *url, lwc_string *host, const char *realm, nserror (*cb)(bool proceed, void *pw), void *cbpw) { BString r("Secure Area"); if (realm) r = realm; BString text(/*messages_get(*/"Please login\n"); text << "Realm: " << r << "\n"; text << "Host: " << host << "\n"; //text << "\n"; LoginAlert *a = new LoginAlert(cb, cbpw, url, lwc_string_data(host), r.String(), text.String()); // asynchronously a->Go(NULL); }
nserror amiga_dt_picture_init(void) { char dt_mime[50]; struct DataType *dt, *prevdt = NULL; lwc_string *type; lwc_error lerror; nserror error; BPTR fh = 0; struct Node *node = NULL; while((dt = ObtainDataType(DTST_RAM, NULL, DTA_DataType, prevdt, DTA_GroupID, GID_PICTURE, // we only support images for now TAG_DONE)) != NULL) { ReleaseDataType(prevdt); prevdt = dt; do { node = ami_mime_from_datatype(dt, &type, node); if(node) { error = content_factory_register_handler( lwc_string_data(type), &amiga_dt_picture_content_handler); if (error != NSERROR_OK) return error; } }while (node != NULL); } ReleaseDataType(prevdt); return NSERROR_OK; }
/** * Case insensitively compare DOM string with lwc_string * * \param s1 The first string to compare * \param s2 The second string to compare * \return true if strings match, false otherwise * * Returns false if either are NULL. */ bool dom_string_caseless_lwc_isequal(const dom_string *s1, lwc_string *s2) { size_t len; const uint8_t *d1 = NULL; const uint8_t *d2 = NULL; dom_string_internal *is1 = (dom_string_internal *) s1; if (s1 == NULL || s2 == NULL) return false; if (is1->type == DOM_STRING_INTERNED) { bool match; if (lwc_string_caseless_isequal(is1->data.intern, s2, &match) != lwc_error_ok) return false; return match; } len = dom_string_byte_length(s1); if (len != lwc_string_length(s2)) return false; d1 = (const uint8_t *) dom_string_data(s1); d2 = (const uint8_t *) lwc_string_data(s2); while (len > 0) { if (dolower(*d1) != dolower(*d2)) return false; d1++; d2++; len--; } return true; }
/** * Callback to determine if a node has an attribute with the given name. * * \param pw HTML document * \param node DOM node * \param qname Name to match * \param match Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_has_attribute(void *pw, void *node, const css_qname *qname, bool *match) { dom_node *n = node; dom_string *name; dom_exception err; err = dom_string_create_interned( (const uint8_t *) lwc_string_data(qname->name), lwc_string_length(qname->name), &name); if (err != DOM_NO_ERR) return CSS_NOMEM; err = dom_element_has_attribute(n, name, match); if (err != DOM_NO_ERR) { dom_string_unref(name); return CSS_OK; } dom_string_unref(name); return CSS_OK; }
/** * Callback to determine if a node has an attribute with given name and value. * * \param pw HTML document * \param node DOM node * \param qname Name to match * \param value Value to match * \param match Pointer to location to receive result * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion. * * \post \a match will contain true if the node matches and false otherwise. */ css_error node_has_attribute_equal(void *pw, void *node, const css_qname *qname, lwc_string *value, bool *match) { dom_node *n = node; dom_string *name; dom_string *atr_val; dom_exception err; size_t vlen = lwc_string_length(value); if (vlen == 0) { *match = false; return CSS_OK; } err = dom_string_create_interned( (const uint8_t *) lwc_string_data(qname->name), lwc_string_length(qname->name), &name); if (err != DOM_NO_ERR) return CSS_NOMEM; err = dom_element_get_attribute(n, name, &atr_val); if ((err != DOM_NO_ERR) || (atr_val == NULL)) { dom_string_unref(name); *match = false; return CSS_OK; } dom_string_unref(name); *match = dom_string_caseless_lwc_isequal(atr_val, value); dom_string_unref(atr_val); return CSS_OK; }
/** * URL resolution callback for libcss * * \param pw Resolution context * \param base Base URI * \param rel Relative URL * \param abs Pointer to location to receive resolved URL * \return CSS_OK on success, * CSS_NOMEM on memory exhaustion, * CSS_INVALID if resolution failed. */ css_error nscss_resolve_url(void *pw, const char *base, lwc_string *rel, lwc_string **abs) { lwc_error lerror; nserror error; nsurl *nsbase; nsurl *nsabs; /* Create nsurl from base */ /* TODO: avoid this */ error = nsurl_create(base, &nsbase); if (error != NSERROR_OK) { return error == NSERROR_NOMEM ? CSS_NOMEM : CSS_INVALID; } /* Resolve URI */ error = nsurl_join(nsbase, lwc_string_data(rel), &nsabs); if (error != NSERROR_OK) { nsurl_unref(nsbase); return error == NSERROR_NOMEM ? CSS_NOMEM : CSS_INVALID; } nsurl_unref(nsbase); /* Intern it */ lerror = lwc_intern_string(nsurl_access(nsabs), nsurl_length(nsabs), abs); if (lerror != lwc_error_ok) { *abs = NULL; nsurl_unref(nsabs); return lerror == lwc_error_oom ? CSS_NOMEM : CSS_INVALID; } nsurl_unref(nsabs); return CSS_OK; }
/** * Case sensitively compare DOM string with lwc_string * * \param s1 The first string to compare * \param s2 The second string to compare * \return true if strings match, false otherwise * * Returns false if either are NULL. */ bool dom_string_lwc_isequal(const dom_string *s1, lwc_string *s2) { size_t len; dom_string_internal *is1 = (dom_string_internal *) s1; if (s1 == NULL || s2 == NULL) return false; if (is1->type == DOM_STRING_INTERNED) { bool match; (void) lwc_string_isequal(is1->data.intern, s2, &match); return match; } /* Handle non-interned case */ len = dom_string_byte_length(s1); if (len != lwc_string_length(s2)) return false; return 0 == memcmp(dom_string_data(s1), lwc_string_data(s2), len); }
static void fetch_rsrc_finalise(lwc_string *scheme) { LOG(("fetch_rsrc_finalise called for %s", lwc_string_data(scheme))); }