DocumentImpl* XSLTProcessorImpl::transformDocument(DocumentImpl* doc) { // FIXME: Right now we assume |doc| is unparsed, but if it has been parsed we will need to serialize it // and then feed that resulting source to libxslt. m_resultOutput = ""; if (!m_stylesheet || !m_stylesheet->document()) return 0; globalSheet = m_stylesheet; xsltSetLoaderFunc(stylesheetLoadFunc); xsltStylesheetPtr sheet = m_stylesheet->compileStyleSheet(); globalSheet = 0; xsltSetLoaderFunc(0); if (!sheet) return 0; m_stylesheet->clearDocuments(); // Get the parsed source document. xmlDocPtr sourceDoc = (xmlDocPtr)doc->transformSource(); xmlDocPtr resultDoc = xsltApplyStylesheet(sheet, sourceDoc, NULL); DocumentImpl* result = documentFromXMLDocPtr(resultDoc, sheet); xsltFreeStylesheet(sheet); return result; }
extern "C" xsltStylesheetPtr get_stylesheet(const char *name) { // this needs to be done only once, but doesn't hurt to run every time xsltSetLoaderFunc(get_stylesheet_doc); // get main document: xmlDocPtr doc = get_stylesheet_doc((const xmlChar *)name, NULL, 0, NULL, XSLT_LOAD_START); if (!doc) return NULL; // xsltSetGenericErrorFunc(stderr, NULL); xsltStylesheetPtr xslt = xsltParseStylesheetDoc(doc); if (!xslt) { xmlFreeDoc(doc); return NULL; } return xslt; }
static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, DocLoader* loader) { xsltSetLoaderFunc(func); globalProcessor = processor; globalDocLoader = loader; }
static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, CachedResourceLoader* cachedResourceLoader) { xsltSetLoaderFunc(func); globalProcessor = processor; globalCachedResourceLoader = cachedResourceLoader; }
static inline void setXSLTLoadCallBack(xsltDocLoaderFunc func, XSLTProcessor* processor, ResourceFetcher* fetcher) { xsltSetLoaderFunc(func); globalProcessor = processor; globalResourceFetcher = fetcher; }
void xslt_transform(xmlDocPtr doc, const char *xslfilename, client_t *client) { xmlDocPtr res; xsltStylesheetPtr cur; xmlChar *string; int len, problem = 0; const char *mediatype = NULL; const char *charset = NULL; xmlSetGenericErrorFunc("", log_parse_failure); xsltSetGenericErrorFunc("", log_parse_failure); xsltSetLoaderFunc(custom_loader); thread_mutex_lock(&xsltlock); cur = xslt_get_stylesheet(xslfilename); if (cur == NULL) { thread_mutex_unlock(&xsltlock); ICECAST_LOG_ERROR("problem reading stylesheet \"%s\"", xslfilename); client_send_error(client, 404, 0, "Could not parse XSLT file"); return; } res = xsltApplyStylesheet(cur, doc, NULL); if (xsltSaveResultToString (&string, &len, res, cur) < 0) problem = 1; /* lets find out the content type and character encoding to use */ if (cur->encoding) charset = (char *)cur->encoding; if (cur->mediaType) mediatype = (char *)cur->mediaType; else { /* check method for the default, a missing method assumes xml */ if (cur->method && xmlStrcmp (cur->method, XMLSTR("html")) == 0) mediatype = "text/html"; else if (cur->method && xmlStrcmp (cur->method, XMLSTR("text")) == 0) mediatype = "text/plain"; else mediatype = "text/xml"; } if (problem == 0) { ssize_t ret; int failed = 0; refbuf_t *refbuf; ssize_t full_len = strlen(mediatype) + (ssize_t)len + (ssize_t)1024; if (full_len < 4096) full_len = 4096; refbuf = refbuf_new (full_len); if (string == NULL) string = xmlCharStrdup (""); ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL, client); if (ret == -1) { ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); client_send_error(client, 500, 0, "Header generation failed."); } else { if ( full_len < (ret + (ssize_t)len + (ssize_t)64) ) { void *new_data; full_len = ret + (ssize_t)len + (ssize_t)64; new_data = realloc(refbuf->data, full_len); if (new_data) { ICECAST_LOG_DEBUG("Client buffer reallocation succeeded."); refbuf->data = new_data; refbuf->len = full_len; ret = util_http_build_header(refbuf->data, full_len, 0, 0, 200, NULL, mediatype, charset, NULL, NULL, client); if (ret == -1) { ICECAST_LOG_ERROR("Dropping client as we can not build response headers."); client_send_error(client, 500, 0, "Header generation failed."); failed = 1; } } else { ICECAST_LOG_ERROR("Client buffer reallocation failed. Dropping client."); client_send_error(client, 500, 0, "Buffer reallocation failed."); failed = 1; } } if (!failed) { snprintf(refbuf->data + ret, full_len - ret, "Content-Length: %d\r\n\r\n%s", len, string); client->respcode = 200; client_set_queue (client, NULL); client->refbuf = refbuf; refbuf->len = strlen (refbuf->data); fserve_add_client (client, NULL); } } xmlFree (string); } else { ICECAST_LOG_WARN("problem applying stylesheet \"%s\"", xslfilename); client_send_error(client, 404, 0, "XSLT problem"); } thread_mutex_unlock (&xsltlock); xmlFreeDoc(res); }