1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "stdafx.h"
17 
18 #include "runtime/core/gflwor/comp_function.h"
19 
20 #include <iostream>
21 
22 namespace zorba {
23 namespace flwor {
24 
25 
operator ()(const SortTuple & t1,const SortTuple & t2) const26 bool SortTupleCmp::operator()(const SortTuple& t1, const SortTuple& t2) const
27 {
28   ZORBA_ASSERT(t1.theKeyValues.size() == t2.theKeyValues.size());
29   ZORBA_ASSERT(t1.theKeyValues.size() == theOrderSpecs->size());
30 
31   std::vector<store::Item*>::const_iterator t1iter = t1.theKeyValues.begin();
32   std::vector<store::Item*>::const_iterator t1end = t1.theKeyValues.end();
33   std::vector<store::Item*>::const_iterator t2iter = t2.theKeyValues.begin();
34 
35   std::vector<OrderSpec>::const_iterator orderSpecIter = theOrderSpecs->begin();
36 
37   while (t1iter != t1end)
38   {
39     long cmp = compare(*t1iter,
40                         *t2iter,
41                         orderSpecIter->theDescending,
42                         orderSpecIter->theEmptyLeast,
43                         orderSpecIter->theNativeCompare,
44                         orderSpecIter->theCollator);
45     if (cmp > 0)
46     {
47       return false;
48     }
49     else if (cmp < 0)
50     {
51       return true;
52     }
53 
54     ++t1iter;
55     ++t2iter;
56     ++orderSpecIter;
57   }
58   return false;
59 }
60 
61 
compare(store::Item * item1,store::Item * item2,bool desc,bool emptyLeast,bool nativeCompare,XQPCollator * collator) const62 long SortTupleCmp::compare(
63       store::Item* item1,
64       store::Item* item2,
65       bool desc,
66       bool emptyLeast,
67       bool nativeCompare,
68       XQPCollator* collator) const
69 {
70   if (item1 == NULL)
71   {
72     if (item2 == NULL)
73       return 0;
74     else
75       return descAsc(emptyLeast ? -1 : 1, desc);
76   }
77   else if (item1->isNaN())
78   {
79     if (item2 == NULL)
80       return descAsc(emptyLeast ? 1 : -1, desc);
81     else if (item2->isNaN())
82       return 0;
83     else
84       return descAsc(emptyLeast ? -1 : 1, desc);
85   }
86   else if (item2 == NULL || item2->isNaN())
87   {
88     return descAsc(emptyLeast ? 1 : -1, desc);
89   }
90   else
91   {
92     long result;
93 
94     // danm: both valueCompare (x, NaN) and valueCompare (NaN, x) return 2.
95     // That's why empty_item is needed.
96     if (nativeCompare)
97     {
98       result = item1->compare(item2, theTimezone, collator);
99     }
100     else
101     {
102       store::Item_t ls1(item1);
103       store::Item_t ls2(item2);
104       result = CompareIterator::valueCompare(theLocation,
105                                              ls1,
106                                              ls2,
107                                              theTypeManager,
108                                              theTimezone,
109                                              collator);
110     }
111 
112     return descAsc(result , desc);
113   }
114 }
115 
116 } // namespace flwor
117 } // namespace zorba
118 
119 /*
120 * Local variables:
121 * mode: c++
122 * End:
123 */
124 /* vim:set et sw=2 ts=2: */
125