2 * The contents of this file are subject to the Mozilla Public
3 * License Version 1.1 (the "License"); you may not use this file
4 * except in compliance with the License. You may obtain a copy of
5 * the License at http://www.mozilla.org/MPL/
7 * Software distributed under the License is distributed on an "AS
8 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9 * implied. See the License for the specific language governing
10 * rights and limitations under the License.
12 * The Original Code is the Sablotron XSLT Processor.
14 * The Initial Developer of the Original Code is Ginger Alliance Ltd.
15 * Portions created by Ginger Alliance are Copyright (C) 2000-2002
16 * Ginger Alliance Ltd. All Rights Reserved.
20 * Alternatively, the contents of this file may be used under the
21 * terms of the GNU General Public License Version 2 or later (the
22 * "GPL"), in which case the provisions of the GPL are applicable
23 * instead of those above. If you wish to allow use of your
24 * version of this file only under the terms of the GPL and not to
25 * allow others to use your version of this file under the MPL,
26 * indicate your decision by deleting the provisions above and
27 * replace them with the notice and other provisions required by
28 * the GPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under either the MPL or the
36 #include "domprovider.h"
51 int KList::findNdx(const Str& keyValue) const
57 while (top >= bottom && !found)
59 middle = (top + bottom)/2;
60 //switch(values[middle] -> compare(keyValue))
61 switch(keyValue.compare(values[middle]))
64 bottom = middle + 1; break;
66 top = middle - 1; break;
71 if (!found) return -1;
73 while (middle > 0 && keyValue == values[middle-1])
78 eFlag KList::getNodes(Sit S, const Str& keyValue, Context& result) const
80 int ndx = findNdx(keyValue);
85 result.append((*this)[ndx]);
87 while (++ndx < number() && keyValue == values[ndx]);
92 eFlag KList::makeValues(Sit S, Expression& use)
94 Context c(NULL); //_cn_ no current in top level keys
95 Expression result(use.getOwnerElement());
96 NodeHandle thisVertex;
98 for (int i = 0; i < number(); i++)
100 thisVertex = (*this)[i];
102 E( use.eval(S, result, &c) );
104 //values.append(new Str);
109 const Context& set = result.tonodesetRef();
112 char *foo = new char[1]; *foo = '\0';
116 S.dom().constructStringValue(set[0], strg);
117 //*(values.last()) = strg;
118 values.append(strg.cloneData());
120 for (int j = 1; j < set.getSize(); j++)
122 insertBefore(thisVertex, ++i);
123 //values.append(new Str);
124 S.dom().constructStringValue(set[j], strg);
125 //*(values.last()) = strg;
126 values.append(strg.cloneData());
132 //E( result.tostring(S, *(values.last())) );
134 E( result.tostring(S, strg) );
135 values.append(strg.cloneData());
142 int KList::compare(int i, int j, void *data)
144 //int cmp = strcmp((char*)*(values[i]), (char*)*(values[j]));
145 //always non wcsxfrm'ed ????
146 int cmp = strcmp(values[i], values[j]);
148 return (cmp > 0) ? 1 : -1;
151 void KList::swap(int i, int j)
153 SList<NodeHandle>::swap(i, j);
157 void KList::sort(Sit S)
159 SList<NodeHandle>::sort(0, number() - 1, &(S.dom()));
167 Key::Key(const EQName& ename_, Expression& match_, Expression& use_)
168 : ename(ename_), match(match_), use(use_)
172 eFlag Key::create(Sit S, SXP_Document doc)
174 GP( Context ) c = new Context(NULL, /* isForKey = */ TRUE);
176 // subkey exists, return
178 // create a context for 'match'
179 //E( toTree(doc) -> getMatchingList(S, match, *c) );
180 S.dom().getMatchingList(S, doc, match, *c);
181 // only keep the array of nodes
182 KList *array = (*c).getKeyArray();
183 array -> incRefCount();
184 array -> setSourceDoc(doc);
185 subkeys.append(array);
187 E( array -> makeValues(S, use) );
190 ename.getname(fullname);
191 Log2(S, L2_KEY_ADDED, Str(array -> number()), fullname);
199 const EQName& Key::getName()
204 eFlag Key::getNodes(Sit S, const Str& keyValue, Context& result, SXP_Document doc) const
206 KList *array = find(doc);
207 E( NZ(array) -> getNodes(S, keyValue, result) );
213 subkeys.freeall(FALSE);
216 void Key::report(Sit S, MsgType type, MsgCode code,
217 const Str &arg1, const Str &arg2) const
219 S.message(type, code, arg1, arg2);
226 printf("// KEY %s\n", (char*)full);
227 for (int i = 0; i < subkeys.number(); i++)
229 printf("// \"doc %p\"\n",subkeys[i] -> getSourceDoc());
230 for (int j = 0; j < subkeys[i] -> number(); j++)
231 printf("// (%p) '%s'\n", subkeys[i] -> operator[](j),
232 //(char*)*(subkeys[i] -> values[j]));
233 subkeys[i] -> values[j]);
238 KList* Key::find(SXP_Document doc) const
241 for (i = 0; i < subkeys.number(); i++)
242 if (subkeys[i] -> getSourceDoc() == doc)
251 #define KeyErr1(situa, code, ename) {\
252 Str fullname; ename.getname(fullname); Err1(S, code, fullname); }
255 : PList<Key*>(LIST_SIZE_SMALL)
259 eFlag KeySet::addKey(Sit S, const EQName& ename, SXP_Document doc,
260 Expression& match, Expression& use)
263 KeyErr1(S, E1_DUPLICIT_KEY, ename);
265 append(newKey = new Key(ename, match, use));
266 E( newKey -> create(S, doc) );
270 eFlag KeySet::makeKeysForDoc(Sit S, SXP_Document doc)
272 for (int i = 0; i < number(); i++)
275 if (k -> find(doc)) break;
276 E( k -> create(S, doc) );
281 eFlag KeySet::getNodes(Sit S, const EQName& ename, SXP_Document doc,
282 const Str& value, Context& result)
284 Key* theKey = findKey(ename);
286 KeyErr1(S, E1_KEY_NOT_FOUND, ename);
287 E( theKey -> getNodes(S, value, result, doc) );
296 Key* KeySet::findKey(const EQName& ename)
298 for (int i = 0; i < number(); i++)
300 if (ename == (*this)[i] -> getName())
306 void KeySet::report(Sit S, MsgType type, MsgCode code,
307 const Str &arg1, const Str &arg2) const
309 S.message(type, code, arg1, arg2);