static void testOrderedInserts(MprTestGroup *gp) { MprList *lp; int i, item, next; lp = mprCreateList(0, 0); tassert(lp != 0); /* Add items such that the final list is ordered */ mprAddItem(lp, (void*) (long) 4); mprAddItem(lp, (void*) (long) 5); mprInsertItemAtPos(lp, 0, (void*) 2); mprInsertItemAtPos(lp, 0, (void*) 1); mprInsertItemAtPos(lp, 2, (void*) 3); mprAddItem(lp, (void*) (long) 6); i = 1; next = 0; item = (int) (long) mprGetNextItem(lp, &next); while (item > 0) { tassert(item == i); i++; item = (int) (long) mprGetNextItem(lp, &next); } }
int maAddLocation(MaHost *host, MaLocation *newLocation) { MaLocation *location; int next, rc; mprAssert(newLocation); mprAssert(newLocation->prefix); if (mprGetParent(host->locations) == host->parent) { host->locations = mprDupList(host, host->parent->locations); } /* * Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc */ for (next = 0; (location = mprGetNextItem(host->locations, &next)) != 0; ) { rc = strcmp(newLocation->prefix, location->prefix); if (rc == 0) { mprRemoveItem(host->locations, location); mprInsertItemAtPos(host->locations, next - 1, newLocation); return 0; } if (strcmp(newLocation->prefix, location->prefix) > 0) { mprInsertItemAtPos(host->locations, next - 1, newLocation); return 0; } } mprAddItem(host->locations, newLocation); return 0; }
int maInsertDir(MaHost *host, MaDir *newDir) { MaDir *dir; int rc, next; mprAssert(newDir); mprAssert(newDir->path); if (mprGetParent(host->dirs) == host->parent) { host->dirs = mprDupList(host, host->parent->dirs); } /* * Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc */ for (next = 0; (dir = mprGetNextItem(host->dirs, &next)) != 0; ) { mprAssert(dir->path); rc = strcmp(newDir->path, dir->path); if (rc == 0) { mprRemoveItem(host->dirs, dir); mprInsertItemAtPos(host->dirs, next, newDir); return 0; } else if (rc > 0) { mprInsertItemAtPos(host->dirs, next - 1, newDir); return 0; } } mprAddItem(host->dirs, newDir); return 0; }
int maInsertAlias(MaHost *host, MaAlias *newAlias) { MaAlias *alias, *old; int rc, next, index; if (mprGetParent(host->aliases) == host->parent) { host->aliases = mprDupList(host, host->parent->aliases); } /* * Sort in reverse collating sequence. Must make sure that /abc/def sorts before /abc. But we sort redirects with * status codes first. */ for (next = 0; (alias = mprGetNextItem(host->aliases, &next)) != 0; ) { rc = strcmp(newAlias->prefix, alias->prefix); if (rc == 0) { index = mprLookupItem(host->aliases, alias); old = (MaAlias*) mprGetItem(host->aliases, index); mprRemoveItem(host->aliases, alias); mprInsertItemAtPos(host->aliases, next - 1, newAlias); return 0; } else if (rc > 0) { if (newAlias->redirectCode >= alias->redirectCode) { mprInsertItemAtPos(host->aliases, next - 1, newAlias); return 0; } } } mprAddItem(host->aliases, newAlias); return 0; }
/* Update an existing element */ static int updateElement(Ejs *ejs, EjsXML *list, EjsXML *elt, int index, EjsObj *value) { EjsXML *node; int i, j; if (!ejsIsXML(ejs, value)) { /* Not XML or XMLList -- convert to string */ value = ejsCast(ejs, value, String); // TODO - seem to be doing this in too many places } mprSetItem(list->elements, index, value); if (elt->kind == EJS_XML_ATTRIBUTE) { assure(ejsIs(ejs, value, String)); i = mprLookupItem(elt->parent->elements, elt); assure(i >= 0); ejsSetXMLElement(ejs, elt->parent, i, elt); // TODO - why do this. Doesn't above do this? ejsSetPropertyByName(ejs, elt->parent, elt->qname, value); elt->value = (EjsString*) value; } if (ejsIsXML(ejs, value) && ((EjsXML*) value)->kind == EJS_XML_LIST) { value = (EjsObj*) shallowCopy(ejs, (EjsXML*) value); if (elt->parent) { index = mprLookupItem(elt->parent->elements, elt); assure(index >= 0); for (j = 0; j < mprGetListLength(((EjsXML*) value)->elements); j++) { mprInsertItemAtPos(elt->parent->elements, index, value); } } } else if (ejsIsXML(ejs, value) || elt->kind != EJS_XML_ELEMENT) { if (elt->parent) { index = mprLookupItem(elt->parent->elements, elt); assure(index >= 0); mprSetItem(elt->parent->elements, index, value); ((EjsXML*) value)->parent = elt->parent; if (ejsIs(ejs, value, String)) { node = ejsCreateXML(ejs, EJS_XML_TEXT, N(NULL, NULL), list, (EjsString*) value); mprSetItem(list->elements, index, node); } else { mprSetItem(list->elements, index, value); } } } else { ejsSetPropertyByName(ejs, elt, N(NULL, "*"), value); } return index; }
static EjsXML *createElement(Ejs *ejs, EjsXML *list, EjsXML *targetObject, EjsName qname, EjsObj *value) { EjsXML *elt, *last, *attList; int index; int j; if (targetObject && ejsIsXML(ejs, targetObject) && targetObject->kind == EJS_XML_LIST) { /* If the target is a list it must have 1 element. So switch to it. TODO - could we get resolve to do this? */ if (mprGetListLength(targetObject->elements) != 1) { /* Spec says so - TODO why no error? */ return 0; } targetObject = mprGetFirstItem(targetObject->elements); } /* Return if the target object is not an XML element */ if (!ejsIsXML(ejs, targetObject) || targetObject->kind != EJS_XML_ELEMENT) { /* Spec says so - TODO why no error? */ return 0; } elt = ejsCreateXML(ejs, EJS_XML_ELEMENT, list->targetProperty, targetObject, NULL); if (list->targetProperty.name && list->targetProperty.name->value[0] == '@') { elt->kind = EJS_XML_ATTRIBUTE; attList = ejsGetPropertyByName(ejs, (EjsObj*) targetObject, list->targetProperty); if (attList && mprGetListLength(attList->elements) > 0) { /* Spec says so. But this surely means you can't update an attribute? */ return 0; } } else if (list->targetProperty.name == NULL || qname.name->value[0] == '*') { elt->kind = EJS_XML_TEXT; elt->qname.name = 0; } index = mprGetListLength(list->elements); if (elt->kind != EJS_XML_ATTRIBUTE) { if (targetObject) { if (index > 0) { /* Find the place of the last list item in the resolved target object. */ last = mprGetItem(list->elements, index - 1); j = mprLookupItem(targetObject->elements, last); } else { j = -1; } if (j < 0) { j = mprGetListLength(targetObject->elements) - 1; } // TODO - really need to wrap this ejsInsertXML(EjsXML *xml, int index, EjsXML *node) if (targetObject->elements == 0) { targetObject->elements = mprCreateList(-1, 0); } /* Insert into the target object */ mprInsertItemAtPos(targetObject->elements, j + 1, elt); } if (ejsIsXML(ejs, value)) { if (((EjsXML*) value)->kind == EJS_XML_LIST) { elt->qname = ((EjsXML*) value)->targetProperty; } else { elt->qname = ((EjsXML*) value)->qname; } } /* Insert into the XML list */ mprSetItem(list->elements, index, elt); } return (EjsXML*) mprGetItem(list->elements, index); }