bump product version to 4.1.6.2
[LibreOffice.git] / connectivity / source / drivers / macab / MacabRecord.cxx
blobb814b4415242a81c4aead0109d089c339f7831b1
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "MacabRecord.hxx"
22 #include "macabutilities.hxx"
23 #include <com/sun/star/util/DateTime.hpp>
25 #include <premac.h>
26 #include <Carbon/Carbon.h>
27 #include <AddressBook/ABAddressBookC.h>
28 #include <postmac.h>
29 #include <connectivity/dbconversion.hxx>
31 using namespace connectivity::macab;
32 using namespace com::sun::star::util;
33 using namespace ::dbtools;
35 // -------------------------------------------------------------------------
36 MacabRecord::MacabRecord()
38 size = 0;
39 fields = NULL;
42 // -------------------------------------------------------------------------
43 MacabRecord::MacabRecord(const sal_Int32 _size)
45 size = _size;
46 fields = new macabfield *[size];
47 sal_Int32 i;
48 for(i = 0; i < size; i++)
49 fields[i] = NULL;
52 // -------------------------------------------------------------------------
53 MacabRecord::~MacabRecord()
55 if(size > 0)
57 int i;
58 for(i = 0; i < size; i++)
60 delete fields[i];
61 fields[i] = NULL;
64 delete [] fields;
65 fields = NULL;
68 // -------------------------------------------------------------------------
69 void MacabRecord::insertAtColumn (CFTypeRef _value, ABPropertyType _type, const sal_Int32 _column)
71 if(_column < size)
73 if(fields[_column] == NULL)
74 fields[_column] = new macabfield;
76 fields[_column]->value = _value;
77 if (fields[_column]->value)
78 CFRetain(fields[_column]->value);
79 fields[_column]->type = _type;
83 // -------------------------------------------------------------------------
84 sal_Bool MacabRecord::contains (const macabfield *_field) const
86 if(_field == NULL)
87 return sal_False;
88 else
89 return contains(_field->value);
92 // -------------------------------------------------------------------------
93 sal_Bool MacabRecord::contains (const CFTypeRef _value) const
95 sal_Int32 i;
96 for(i = 0; i < size; i++)
98 if(fields[i] != NULL)
100 if(CFEqual(fields[i]->value, _value))
102 return sal_True;
107 return sal_False;
110 // -------------------------------------------------------------------------
111 sal_Int32 MacabRecord::getSize() const
113 return size;
116 // -------------------------------------------------------------------------
117 macabfield *MacabRecord::copy(const sal_Int32 i) const
119 /* Note: copy(i) creates a new macabfield identical to that at
120 * location i, whereas get(i) returns a pointer to the macabfield
121 * at location i.
123 if(i < size)
125 macabfield *_copy = new macabfield;
126 _copy->type = fields[i]->type;
127 _copy->value = fields[i]->value;
128 if (_copy->value)
129 CFRetain(_copy->value);
130 return _copy;
133 return NULL;
136 // -------------------------------------------------------------------------
137 macabfield *MacabRecord::get(const sal_Int32 i) const
139 /* Note: copy(i) creates a new macabfield identical to that at
140 * location i, whereas get(i) returns a pointer to the macabfield
141 * at location i.
143 if(i < size)
145 return fields[i];
148 return NULL;
151 // -------------------------------------------------------------------------
152 void MacabRecord::releaseFields()
154 /* This method is, at the moment, only used in MacabHeader.cxx, but
155 * the idea is simple: if you are not destroying this object but want
156 * to clear it of its macabfields, you should release each field's
157 * value.
159 sal_Int32 i;
160 for(i = 0; i < size; i++)
161 CFRelease(fields[i]->value);
164 // -------------------------------------------------------------------------
165 sal_Int32 MacabRecord::compareFields(const macabfield *_field1, const macabfield *_field2)
168 /* When comparing records, if either field is NULL (and the other is
169 * not), that field is considered "greater than" the other, so that it
170 * shows up later in the list when fields are ordered.
172 if(_field1 == _field2)
173 return 0;
174 if(_field1 == NULL)
175 return 1;
176 if(_field2 == NULL)
177 return -1;
179 /* If they aren't the same type, for now, return the one with
180 * the smaller type ID... I don't know of a better way to compare
181 * two different data types.
183 if(_field1->type != _field2->type)
184 return(_field1->type - _field2->type);
186 CFComparisonResult result;
188 /* Carbon has a unique compare function for each data type: */
189 switch(_field1->type)
191 case kABStringProperty:
192 result = CFStringCompare(
193 (CFStringRef) _field1->value,
194 (CFStringRef) _field2->value,
195 kCFCompareLocalized); // Specifies that the comparison should take into account differences related to locale, such as the thousands separator character.
196 break;
198 case kABDateProperty:
199 result = CFDateCompare(
200 (CFDateRef) _field1->value,
201 (CFDateRef) _field2->value,
202 NULL); // NULL = unused variable
203 break;
205 case kABIntegerProperty:
206 case kABRealProperty:
207 result = CFNumberCompare(
208 (CFNumberRef) _field1->value,
209 (CFNumberRef) _field2->value,
210 NULL); // NULL = unused variable
211 break;
213 default:
214 result = kCFCompareEqualTo; // can't compare
217 return (sal_Int32) result;
220 // -------------------------------------------------------------------------
221 /* Create a macabfield out of an OUString and type. Together with the
222 * method fieldToString() (below), it is possible to switch conveniently
223 * between an OUString and a macabfield (for use when creating and handling
224 * SQL statement).
226 macabfield *MacabRecord::createMacabField(const OUString _newFieldString, const ABPropertyType _abType)
228 macabfield *newField = NULL;
229 switch(_abType)
231 case kABStringProperty:
232 newField = new macabfield;
233 newField->value = OUStringToCFString(_newFieldString);
234 newField->type = _abType;
235 break;
236 case kABDateProperty:
238 DateTime aDateTime = DBTypeConversion::toDateTime(_newFieldString);
240 // bad format...
241 if(aDateTime.Year == 0 && aDateTime.Month == 0 && aDateTime.Day == 0)
244 else
246 double nTime = DBTypeConversion::toDouble(aDateTime, DBTypeConversion::getStandardDate());
247 nTime -= kCFAbsoluteTimeIntervalSince1970;
248 newField = new macabfield;
249 newField->value = CFDateCreate(NULL, (CFAbsoluteTime) nTime);
250 newField->type = _abType;
253 break;
254 case kABIntegerProperty:
257 sal_Int64 nVal = _newFieldString.toInt64();
259 newField = new macabfield;
260 newField->value = CFNumberCreate(NULL,kCFNumberLongType, &nVal);
261 newField->type = _abType;
263 // bad format...
264 catch(...)
267 break;
268 case kABRealProperty:
271 double nVal = _newFieldString.toDouble();
273 newField = new macabfield;
274 newField->value = CFNumberCreate(NULL,kCFNumberDoubleType, &nVal);
275 newField->type = _abType;
277 // bad format...
278 catch(...)
281 break;
282 default:
285 return newField;
288 // -------------------------------------------------------------------------
289 /* Create an OUString out of a macabfield. Together with the method
290 * createMacabField() (above), it is possible to switch conveniently
291 * between an OUString and a macabfield (for use when creating and handling
292 * SQL statement).
294 OUString MacabRecord::fieldToString(const macabfield *_aField)
296 if(_aField == NULL)
297 return OUString();
299 OUString fieldString;
301 switch(_aField->type)
303 case kABStringProperty:
304 fieldString = CFStringToOUString((CFStringRef) _aField->value);
305 break;
306 case kABDateProperty:
308 DateTime aTime = CFDateToDateTime((CFDateRef) _aField->value);
309 fieldString = DBTypeConversion::toDateTimeString(aTime);
311 break;
312 case kABIntegerProperty:
314 CFNumberType numberType = CFNumberGetType( (CFNumberRef) _aField->value );
315 sal_Int64 nVal;
316 // Should we check for the wrong type here, e.g., a float?
317 sal_Bool m_bSuccess = !CFNumberGetValue((CFNumberRef) _aField->value, numberType, &nVal);
318 if(m_bSuccess != sal_False)
319 fieldString = OUString::valueOf(nVal);
321 break;
322 case kABRealProperty:
324 CFNumberType numberType = CFNumberGetType( (CFNumberRef) _aField->value );
325 double nVal;
326 // Should we check for the wrong type here, e.g., an int?
327 sal_Bool m_bSuccess = !CFNumberGetValue((CFNumberRef) _aField->value, numberType, &nVal);
328 if(m_bSuccess != sal_False)
329 fieldString = OUString::valueOf(nVal);
331 break;
332 default:
335 return fieldString;
339 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */