merge the formfield patch from ooo-build
[ooovba.git] / connectivity / source / drivers / macab / MacabHeader.cxx
blob2efd06665d0d7cf0c5eb0823d802df36f99e58b1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: MacabHeader.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
34 #include "MacabHeader.hxx"
35 #include "MacabRecord.hxx"
36 #include "macabutilities.hxx"
38 #include <math.h>
39 #include <com/sun/star/sdbc/DataType.hpp>
40 #include <connectivity/dbconversion.hxx>
42 using namespace connectivity::macab;
43 using namespace com::sun::star::sdbc;
44 using namespace com::sun::star::util;
45 using namespace ::dbtools;
47 // -------------------------------------------------------------------------
48 MacabHeader::MacabHeader(const sal_Int32 _size, macabfield **_fields)
50 sal_Int32 i;
51 size = _size;
52 fields = new macabfield *[size];
53 for(i = 0; i < size; i++)
55 if(_fields[i] == NULL)
57 fields[i] = NULL;
59 else
61 /* The constructor duplicates the macabfields it gets because they
62 * are either deleted later or used for other purposes.
64 fields[i] = new macabfield;
65 fields[i]->type = _fields[i]->type;
66 fields[i]->value = _fields[i]->value;
67 if (fields[i]->value)
68 CFRetain(fields[i]->value);
74 // -------------------------------------------------------------------------
75 MacabHeader::MacabHeader()
77 size = 0;
78 fields = NULL;
81 // -------------------------------------------------------------------------
82 MacabHeader::~MacabHeader()
86 // -------------------------------------------------------------------------
87 void MacabHeader::operator+= (const MacabHeader *r)
89 /* Add one MacabHeader to another. Anything not already in the header is
90 * added to the end of it.
92 sal_Int32 rSize = r->getSize();
93 if(rSize != 0) // If the new header does actually have fields
95 /* If our header is currently empty, just copy all of the fields from
96 * the new header to this one.
98 if(size == 0)
100 sal_Int32 i;
101 size = rSize;
102 fields = new macabfield *[size];
103 for(i = 0; i < size; i++)
105 fields[i] = r->copy(i);
109 /* Otherwise, only add the duplicates. We do this with a two-pass
110 * approach. First, find out how many fields to add, then reallocate
111 * the size of the fields array and add the old ones at the end.
112 * (More precisely, we create a _new_ fields array with the new length
113 * allocated to it, then get all of the fields from the current
114 * fields array to it, then copy the non-duplicates from the new
115 * header to the end.)
117 else
119 sal_Int32 i;
120 sal_Int32 numToAdd = 0, numAdded = 0;
121 macabfield **newFields;
122 for( i = 0; i < rSize; i++)
124 if(!contains(r->get(i)))
126 numToAdd++;
130 newFields = new macabfield *[size+numToAdd];
131 for(i = 0; i < size; i++)
133 newFields[i] = copy(i);
136 for( i = 0; i < rSize; i++)
138 if(!contains(r->get(i)))
140 newFields[size+numAdded] = r->copy(i);
141 numAdded++;
142 if(numAdded == numToAdd)
143 break;
147 releaseFields();
148 delete [] fields;
149 size += numAdded;
150 fields = newFields;
155 // -------------------------------------------------------------------------
156 ::rtl::OUString MacabHeader::getString(const sal_Int32 i) const
158 ::rtl::OUString nRet;
160 if(i < size)
162 if(fields[i] == NULL || fields[i]->value == NULL || CFGetTypeID(fields[i]->value) != CFStringGetTypeID())
163 return ::rtl::OUString();
166 nRet = CFStringToOUString( (CFStringRef) fields[i]->value);
168 catch(...){ }
171 return nRet;
174 // -------------------------------------------------------------------------
175 void MacabHeader::sortRecord()
177 sortRecord(0,size);
180 // -------------------------------------------------------------------------
181 macabfield **MacabHeader::sortRecord(const sal_Int32 _start, const sal_Int32 _length)
183 /* Sort using mergesort. Because it uses mergesort, it is recursive and
184 * not in place (so it creates a new array at every step of the
185 * recursion), so if you prefer to use a different sort, please feel
186 * free to implement it.
188 macabfield** sorted = new macabfield *[_length];
189 if(_length <= 2)
191 if(_length == 2)
193 if(compareFields(fields[_start], fields[_start+1]) > 0)
195 sorted[0] = get(_start+1);
196 sorted[1] = get(_start);
198 else
200 sorted[0] = get(_start);
201 sorted[1] = get(_start+1);
204 else if(_length == 1)
206 sorted[0] = get(_start);
209 else
211 sal_Int32 halfLength = floor(_length/2);
212 sal_Int32 fp = 0, lp = 0;
213 sal_Int32 i;
214 macabfield **firstHalf = new macabfield *[halfLength];
215 macabfield **lastHalf = new macabfield *[_length - halfLength];
217 firstHalf = sortRecord(_start, halfLength);
218 lastHalf = sortRecord(_start+halfLength, _length-halfLength);
219 for(i = 0; i < _length; i++)
221 if(compareFields(firstHalf[fp],lastHalf[lp]) < 0)
223 sorted[i] = firstHalf[fp++];
224 if(fp == halfLength)
226 for( i++; i < _length; i++)
228 sorted[i] = lastHalf[lp++];
230 break;
233 else
235 sorted[i] = lastHalf[lp++];
236 if(lp == _length - halfLength)
238 for( i++; i < _length; i++)
240 sorted[i] = firstHalf[fp++];
242 break;
246 if(_length == size)
248 fields = sorted;
251 return sorted;
254 sal_Int32 MacabHeader::compareFields(const macabfield *_field1, const macabfield *_field2)
256 /* Comparing two fields in a MacabHeader is different than comparing two
257 * fields in a MacabRecord. It starts in the same way (if one of the two
258 * fields is NULL, it belongs after the other, so it is considered
259 * "greater"). But, then, all headers are CFStrings, no matter what
260 * type they claim to be (since they actually hold the expected type for
261 * the records with that header). That being said, all we have to do is
262 * the built-in CFStringCompare.
264 if(_field1 == _field2)
265 return 0;
266 if(_field1 == NULL)
267 return 1;
268 if(_field2 == NULL)
269 return -1;
271 CFComparisonResult result = CFStringCompare(
272 (CFStringRef) _field1->value,
273 (CFStringRef) _field2->value,
274 0); // 0 = no options (like ignore case)
276 return (sal_Int32) result;
279 // -------------------------------------------------------------------------
280 sal_Int32 MacabHeader::getColumnNumber(const ::rtl::OUString s) const
282 sal_Int32 i;
283 for(i = 0; i < size; i++)
285 if(getString(i) == s)
286 break;
289 if(i == size)
290 i = -1;
292 return i;
295 // -------------------------------------------------------------------------
296 MacabHeader *MacabHeader::begin()
298 return this;
301 // -------------------------------------------------------------------------
302 MacabHeader::iterator::iterator ()
306 // -------------------------------------------------------------------------
307 MacabHeader::iterator::~iterator ()
311 void MacabHeader::iterator::operator= (MacabHeader *_record)
313 id = 0;
314 record = _record;
317 // -------------------------------------------------------------------------
318 void MacabHeader::iterator::operator++ ()
320 id++;
323 // -------------------------------------------------------------------------
324 sal_Bool MacabHeader::iterator::operator!= (const sal_Int32 i) const
326 return(id != i);
329 // -------------------------------------------------------------------------
330 sal_Bool MacabHeader::iterator::operator== (const sal_Int32 i) const
332 return(id == i);
335 // -------------------------------------------------------------------------
336 macabfield *MacabHeader::iterator::operator* () const
338 return record->get(id);
341 // -------------------------------------------------------------------------
342 sal_Int32 MacabHeader::end() const
344 return size;