This source file includes following definitions.
- xsltUnicodeSortFunction
#include "config.h"
#include "core/xml/XSLTUnicodeSort.h"
#include "wtf/text/WTFString.h"
#include "wtf/unicode/Collator.h"
#include <libxslt/templates.h>
#include <libxslt/xsltutils.h>
namespace WebCore {
void xsltUnicodeSortFunction(xsltTransformContextPtr ctxt, xmlNodePtr *sorts, int nbsorts)
{
#ifdef XSLT_REFACTORED
xsltStyleItemSortPtr comp;
#else
xsltStylePreCompPtr comp;
#endif
xmlXPathObjectPtr *resultsTab[XSLT_MAX_SORT];
xmlXPathObjectPtr *results = NULL, *res;
xmlNodeSetPtr list = NULL;
int descending, number, desc, numb;
int len = 0;
int i, j, incr;
int tst;
int depth;
xmlNodePtr node;
xmlXPathObjectPtr tmp;
int tempstype[XSLT_MAX_SORT], temporder[XSLT_MAX_SORT];
if ((ctxt == NULL) || (sorts == NULL) || (nbsorts <= 0) ||
(nbsorts >= XSLT_MAX_SORT))
return;
if (sorts[0] == NULL)
return;
comp = static_cast<xsltStylePreComp*>(sorts[0]->psvi);
if (comp == NULL)
return;
list = ctxt->nodeList;
if ((list == NULL) || (list->nodeNr <= 1))
return;
for (j = 0; j < nbsorts; j++) {
comp = static_cast<xsltStylePreComp*>(sorts[j]->psvi);
tempstype[j] = 0;
if ((comp->stype == NULL) && (comp->has_stype != 0)) {
comp->stype =
xsltEvalAttrValueTemplate(ctxt, sorts[j],
(const xmlChar *) "data-type",
XSLT_NAMESPACE);
if (comp->stype != NULL) {
tempstype[j] = 1;
if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
comp->number = 0;
else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
comp->number = 1;
else {
xsltTransformError(ctxt, NULL, sorts[j],
"xsltDoSortFunction: no support for data-type = %s\n",
comp->stype);
comp->number = 0;
}
}
}
temporder[j] = 0;
if ((comp->order == NULL) && (comp->has_order != 0)) {
comp->order = xsltEvalAttrValueTemplate(ctxt, sorts[j],
(const xmlChar *) "order",
XSLT_NAMESPACE);
if (comp->order != NULL) {
temporder[j] = 1;
if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
comp->descending = 0;
else if (xmlStrEqual(comp->order,
(const xmlChar *) "descending"))
comp->descending = 1;
else {
xsltTransformError(ctxt, NULL, sorts[j],
"xsltDoSortFunction: invalid value %s for order\n",
comp->order);
comp->descending = 0;
}
}
}
}
len = list->nodeNr;
resultsTab[0] = xsltComputeSortResult(ctxt, sorts[0]);
for (i = 1;i < XSLT_MAX_SORT;i++)
resultsTab[i] = NULL;
results = resultsTab[0];
comp = static_cast<xsltStylePreComp*>(sorts[0]->psvi);
descending = comp->descending;
number = comp->number;
if (results == NULL)
return;
Collator collator(comp->has_lang ? (const char*)comp->lang : "en");
collator.setOrderLowerFirst(comp->lower_first);
for (incr = len / 2; incr > 0; incr /= 2) {
for (i = incr; i < len; i++) {
j = i - incr;
if (results[i] == NULL)
continue;
while (j >= 0) {
if (results[j] == NULL)
tst = 1;
else {
if (number) {
if (xmlXPathIsNaN(results[j]->floatval)) {
if (xmlXPathIsNaN(results[j + incr]->floatval))
tst = 0;
else
tst = -1;
} else if (xmlXPathIsNaN(results[j + incr]->floatval))
tst = 1;
else if (results[j]->floatval ==
results[j + incr]->floatval)
tst = 0;
else if (results[j]->floatval >
results[j + incr]->floatval)
tst = 1;
else tst = -1;
} else {
Vector<UChar> string1;
Vector<UChar> string2;
String::fromUTF8(reinterpret_cast<const char*>(results[j]->stringval)).appendTo(string1);
String::fromUTF8(reinterpret_cast<const char*>(results[j + incr]->stringval)).appendTo(string2);
tst = collator.collate(string1.data(), string1.size(), string2.data(), string2.size());
}
if (descending)
tst = -tst;
}
if (tst == 0) {
depth = 1;
while (depth < nbsorts) {
if (sorts[depth] == NULL)
break;
comp = static_cast<xsltStylePreComp*>(sorts[depth]->psvi);
if (comp == NULL)
break;
desc = comp->descending;
numb = comp->number;
if (resultsTab[depth] == NULL)
resultsTab[depth] = xsltComputeSortResult(ctxt,
sorts[depth]);
res = resultsTab[depth];
if (res == NULL)
break;
if (res[j] == NULL) {
if (res[j+incr] != NULL)
tst = 1;
} else {
if (numb) {
if (xmlXPathIsNaN(res[j]->floatval)) {
if (xmlXPathIsNaN(res[j +
incr]->floatval))
tst = 0;
else
tst = -1;
} else if (xmlXPathIsNaN(res[j + incr]->
floatval))
tst = 1;
else if (res[j]->floatval == res[j + incr]->
floatval)
tst = 0;
else if (res[j]->floatval >
res[j + incr]->floatval)
tst = 1;
else tst = -1;
} else {
Vector<UChar> string1;
Vector<UChar> string2;
String::fromUTF8(reinterpret_cast<const char*>(res[j]->stringval)).appendTo(string1);
String::fromUTF8(reinterpret_cast<const char*>(res[j + incr]->stringval)).appendTo(string2);
tst = collator.collate(string1.data(), string1.size(), string2.data(), string2.size());
}
if (desc)
tst = -tst;
}
if (tst != 0)
break;
depth++;
}
}
if (tst == 0) {
tst = results[j]->index > results[j + incr]->index;
}
if (tst > 0) {
tmp = results[j];
results[j] = results[j + incr];
results[j + incr] = tmp;
node = list->nodeTab[j];
list->nodeTab[j] = list->nodeTab[j + incr];
list->nodeTab[j + incr] = node;
depth = 1;
while (depth < nbsorts) {
if (sorts[depth] == NULL)
break;
if (resultsTab[depth] == NULL)
break;
res = resultsTab[depth];
tmp = res[j];
res[j] = res[j + incr];
res[j + incr] = tmp;
depth++;
}
j -= incr;
} else
break;
}
}
}
for (j = 0; j < nbsorts; j++) {
comp = static_cast<xsltStylePreComp*>(sorts[j]->psvi);
if (tempstype[j] == 1) {
xmlFree((void *)(comp->stype));
comp->stype = NULL;
}
if (temporder[j] == 1) {
xmlFree((void *)(comp->order));
comp->order = NULL;
}
if (resultsTab[j] != NULL) {
for (i = 0;i < len;i++)
xmlXPathFreeObject(resultsTab[j][i]);
xmlFree(resultsTab[j]);
}
}
}
}