update dev300-m58
[ooovba.git] / connectivity / source / drivers / macab / MacabRecord.cxx
blob8b019726b6294e453392a3f662563303c7da8b24
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: MacabRecord.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 "MacabRecord.hxx"
35 #include "macabutilities.hxx"
36 #include <com/sun/star/util/DateTime.hpp>
38 #include <premac.h>
39 #include <Carbon/Carbon.h>
40 #include <AddressBook/ABAddressBookC.h>
41 #include <postmac.h>
42 #include <connectivity/dbconversion.hxx>
44 using namespace connectivity::macab;
45 using namespace com::sun::star::util;
46 using namespace ::dbtools;
48 // -------------------------------------------------------------------------
49 MacabRecord::MacabRecord()
51 size = 0;
52 fields = NULL;
55 // -------------------------------------------------------------------------
56 MacabRecord::MacabRecord(const sal_Int32 _size)
58 size = _size;
59 fields = new macabfield *[size];
60 sal_Int32 i;
61 for(i = 0; i < size; i++)
62 fields[i] = NULL;
65 // -------------------------------------------------------------------------
66 MacabRecord::~MacabRecord()
68 if(size > 0)
70 int i;
71 for(i = 0; i < size; i++)
73 delete fields[i];
74 fields[i] = NULL;
77 delete [] fields;
78 fields = NULL;
81 // -------------------------------------------------------------------------
82 void MacabRecord::insertAtColumn (CFTypeRef _value, ABPropertyType _type, const sal_Int32 _column)
84 if(_column < size)
86 if(fields[_column] == NULL)
87 fields[_column] = new macabfield;
89 fields[_column]->value = _value;
90 if (fields[_column]->value)
91 CFRetain(fields[_column]->value);
92 fields[_column]->type = _type;
96 // -------------------------------------------------------------------------
97 sal_Bool MacabRecord::contains (const macabfield *_field) const
99 if(_field == NULL)
100 return sal_False;
101 else
102 return contains(_field->value);
105 // -------------------------------------------------------------------------
106 sal_Bool MacabRecord::contains (const CFTypeRef _value) const
108 sal_Int32 i;
109 for(i = 0; i < size; i++)
111 if(fields[i] != NULL)
113 if(CFEqual(fields[i]->value, _value))
115 return sal_True;
120 return sal_False;
123 // -------------------------------------------------------------------------
124 sal_Int32 MacabRecord::getSize() const
126 return size;
129 // -------------------------------------------------------------------------
130 macabfield *MacabRecord::copy(const sal_Int32 i) const
132 /* Note: copy(i) creates a new macabfield identical to that at
133 * location i, whereas get(i) returns a pointer to the macabfield
134 * at location i.
136 if(i < size)
138 macabfield *_copy = new macabfield;
139 _copy->type = fields[i]->type;
140 _copy->value = fields[i]->value;
141 if (_copy->value)
142 CFRetain(_copy->value);
143 return _copy;
146 return NULL;
149 // -------------------------------------------------------------------------
150 macabfield *MacabRecord::get(const sal_Int32 i) const
152 /* Note: copy(i) creates a new macabfield identical to that at
153 * location i, whereas get(i) returns a pointer to the macabfield
154 * at location i.
156 if(i < size)
158 return fields[i];
161 return NULL;
164 // -------------------------------------------------------------------------
165 void MacabRecord::releaseFields()
167 /* This method is, at the moment, only used in MacabHeader.cxx, but
168 * the idea is simple: if you are not destroying this object but want
169 * to clear it of its macabfields, you should release each field's
170 * value.
172 sal_Int32 i;
173 for(i = 0; i < size; i++)
174 CFRelease(fields[i]->value);
177 // -------------------------------------------------------------------------
178 sal_Int32 MacabRecord::compareFields(const macabfield *_field1, const macabfield *_field2)
181 /* When comparing records, if either field is NULL (and the other is
182 * not), that field is considered "greater than" the other, so that it
183 * shows up later in the list when fields are ordered.
185 if(_field1 == _field2)
186 return 0;
187 if(_field1 == NULL)
188 return 1;
189 if(_field2 == NULL)
190 return -1;
192 /* If they aren't the same type, for now, return the one with
193 * the smaller type ID... I don't know of a better way to compare
194 * two different data types.
196 if(_field1->type != _field2->type)
197 return(_field1->type - _field2->type);
199 CFComparisonResult result;
201 /* Carbon has a unique compare function for each data type: */
202 switch(_field1->type)
204 case kABStringProperty:
205 result = CFStringCompare(
206 (CFStringRef) _field1->value,
207 (CFStringRef) _field2->value,
208 0); // 0 = no options (like ignore case)
209 break;
211 case kABDateProperty:
212 result = CFDateCompare(
213 (CFDateRef) _field1->value,
214 (CFDateRef) _field2->value,
215 NULL); // NULL = unused variable
216 break;
218 case kABIntegerProperty:
219 case kABRealProperty:
220 result = CFNumberCompare(
221 (CFNumberRef) _field1->value,
222 (CFNumberRef) _field2->value,
223 NULL); // NULL = unused variable
224 break;
226 default:
227 result = kCFCompareEqualTo; // can't compare
230 return (sal_Int32) result;
233 // -------------------------------------------------------------------------
234 /* Create a macabfield out of an OUString and type. Together with the
235 * method fieldToString() (below), it is possible to switch conveniently
236 * between an OUString and a macabfield (for use when creating and handling
237 * SQL statement).
239 macabfield *MacabRecord::createMacabField(const ::rtl::OUString _newFieldString, const ABPropertyType _abType)
241 macabfield *newField = NULL;
242 switch(_abType)
244 case kABStringProperty:
245 newField = new macabfield;
246 newField->value = OUStringToCFString(_newFieldString);
247 newField->type = _abType;
248 break;
249 case kABDateProperty:
251 DateTime aDateTime = DBTypeConversion::toDateTime(_newFieldString);
253 // bad format...
254 if(aDateTime.Year == 0 && aDateTime.Month == 0 && aDateTime.Day == 0)
257 else
259 double nTime = DBTypeConversion::toDouble(aDateTime, DBTypeConversion::getStandardDate());
260 nTime -= kCFAbsoluteTimeIntervalSince1970;
261 newField = new macabfield;
262 newField->value = CFDateCreate(NULL, (CFAbsoluteTime) nTime);
263 newField->type = _abType;
266 break;
267 case kABIntegerProperty:
270 sal_Int64 nVal = _newFieldString.toInt64();
272 newField = new macabfield;
273 newField->value = CFNumberCreate(NULL,kCFNumberLongType, &nVal);
274 newField->type = _abType;
276 // bad format...
277 catch(...)
280 break;
281 case kABRealProperty:
284 double nVal = _newFieldString.toDouble();
286 newField = new macabfield;
287 newField->value = CFNumberCreate(NULL,kCFNumberDoubleType, &nVal);
288 newField->type = _abType;
290 // bad format...
291 catch(...)
294 break;
295 default:
298 return newField;
301 // -------------------------------------------------------------------------
302 /* Create an OUString out of a macabfield. Together with the method
303 * createMacabField() (above), it is possible to switch conveniently
304 * between an OUString and a macabfield (for use when creating and handling
305 * SQL statement).
307 ::rtl::OUString MacabRecord::fieldToString(const macabfield *_aField)
309 if(_aField == NULL)
310 return ::rtl::OUString();
312 ::rtl::OUString fieldString;
314 switch(_aField->type)
316 case kABStringProperty:
317 fieldString = CFStringToOUString((CFStringRef) _aField->value);
318 break;
319 case kABDateProperty:
321 DateTime aTime = CFDateToDateTime((CFDateRef) _aField->value);
322 fieldString = DBTypeConversion::toDateTimeString(aTime);
324 break;
325 case kABIntegerProperty:
327 CFNumberType numberType = CFNumberGetType( (CFNumberRef) _aField->value );
328 sal_Int64 nVal;
329 // Should we check for the wrong type here, e.g., a float?
330 sal_Bool m_bSuccess = !CFNumberGetValue((CFNumberRef) _aField->value, numberType, &nVal);
331 if(m_bSuccess != sal_False)
332 fieldString = ::rtl::OUString::valueOf(nVal);
334 break;
335 case kABRealProperty:
337 CFNumberType numberType = CFNumberGetType( (CFNumberRef) _aField->value );
338 double nVal;
339 // Should we check for the wrong type here, e.g., an int?
340 sal_Bool m_bSuccess = !CFNumberGetValue((CFNumberRef) _aField->value, numberType, &nVal);
341 if(m_bSuccess != sal_False)
342 fieldString = ::rtl::OUString::valueOf(nVal);
344 break;
345 default:
348 return fieldString;