bump product version to 7.2.5.1
[LibreOffice.git] / connectivity / source / drivers / macab / MacabRecord.cxx
blob3072e1eaa2f46ffde982658924d79455eb8816c0
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;
36 MacabRecord::MacabRecord() : size(0)
41 MacabRecord::MacabRecord(const sal_Int32 _size)
42 : size(_size),
43 fields(std::make_unique<macabfield *[]>(size))
45 sal_Int32 i;
46 for(i = 0; i < size; i++)
47 fields[i] = nullptr;
51 MacabRecord::~MacabRecord()
53 if(size > 0)
55 releaseFields();
56 int i;
57 for(i = 0; i < size; i++)
59 delete fields[i];
60 fields[i] = nullptr;
66 void MacabRecord::insertAtColumn (CFTypeRef _value, ABPropertyType _type, const sal_Int32 _column)
68 if(_column < size)
70 if(fields[_column] == nullptr)
71 fields[_column] = new macabfield;
73 fields[_column]->value = _value;
74 if (fields[_column]->value)
75 CFRetain(fields[_column]->value);
76 fields[_column]->type = _type;
81 bool MacabRecord::contains (const macabfield *_field) const
83 if(_field == nullptr)
84 return false;
85 else
86 return contains(_field->value);
90 bool MacabRecord::contains (const CFTypeRef _value) const
92 sal_Int32 i;
93 for(i = 0; i < size; i++)
95 if(fields[i] != nullptr)
97 if(CFEqual(fields[i]->value, _value))
99 return true;
104 return false;
108 sal_Int32 MacabRecord::getSize() const
110 return size;
114 macabfield *MacabRecord::copy(const sal_Int32 i) const
116 /* Note: copy(i) creates a new macabfield identical to that at
117 * location i, whereas get(i) returns a pointer to the macabfield
118 * at location i.
120 if(i < size)
122 macabfield *_copy = new macabfield;
123 _copy->type = fields[i]->type;
124 _copy->value = fields[i]->value;
125 if (_copy->value)
126 CFRetain(_copy->value);
127 return _copy;
130 return nullptr;
134 macabfield *MacabRecord::get(const sal_Int32 i) const
136 /* Note: copy(i) creates a new macabfield identical to that at
137 * location i, whereas get(i) returns a pointer to the macabfield
138 * at location i.
140 if(i < size)
142 return fields[i];
145 return nullptr;
149 void MacabRecord::releaseFields()
151 /* This method is, at the moment, only used in MacabHeader.cxx, but
152 * the idea is simple: if you are not destroying this object but want
153 * to clear it of its macabfields, you should release each field's
154 * value.
156 sal_Int32 i;
157 for(i = 0; i < size; i++)
158 CFRelease(fields[i]->value);
162 sal_Int32 MacabRecord::compareFields(const macabfield *_field1, const macabfield *_field2)
165 /* When comparing records, if either field is NULL (and the other is
166 * not), that field is considered "greater than" the other, so that it
167 * shows up later in the list when fields are ordered.
169 if(_field1 == _field2)
170 return 0;
171 if(_field1 == nullptr)
172 return 1;
173 if(_field2 == nullptr)
174 return -1;
176 /* If they aren't the same type, for now, return the one with
177 * the smaller type ID... I don't know of a better way to compare
178 * two different data types.
180 if(_field1->type != _field2->type)
181 return(_field1->type - _field2->type);
183 CFComparisonResult result;
185 /* Carbon has a unique compare function for each data type: */
186 switch(_field1->type)
188 case kABStringProperty:
189 result = CFStringCompare(
190 static_cast<CFStringRef>(_field1->value),
191 static_cast<CFStringRef>(_field2->value),
192 kCFCompareLocalized); // Specifies that the comparison should take into account differences related to locale, such as the thousands separator character.
193 break;
195 case kABDateProperty:
196 result = CFDateCompare(
197 static_cast<CFDateRef>(_field1->value),
198 static_cast<CFDateRef>(_field2->value),
199 nullptr); // NULL = unused variable
200 break;
202 case kABIntegerProperty:
203 case kABRealProperty:
204 result = CFNumberCompare(
205 static_cast<CFNumberRef>(_field1->value),
206 static_cast<CFNumberRef>(_field2->value),
207 nullptr); // NULL = unused variable
208 break;
210 default:
211 result = kCFCompareEqualTo; // can't compare
214 return static_cast<sal_Int32>(result);
218 /* Create a macabfield out of an OUString and type. Together with the
219 * method fieldToString() (below), it is possible to switch conveniently
220 * between an OUString and a macabfield (for use when creating and handling
221 * SQL statement).
223 macabfield *MacabRecord::createMacabField(const OUString& _newFieldString, const ABPropertyType _abType)
225 macabfield *newField = nullptr;
226 switch(_abType)
228 case kABStringProperty:
229 newField = new macabfield;
230 newField->value = OUStringToCFString(_newFieldString);
231 newField->type = _abType;
232 break;
233 case kABDateProperty:
235 DateTime aDateTime = DBTypeConversion::toDateTime(_newFieldString);
237 // bad format...
238 if(aDateTime.Year == 0 && aDateTime.Month == 0 && aDateTime.Day == 0)
241 else
243 double nTime = DBTypeConversion::toDouble(aDateTime, DBTypeConversion::getStandardDate());
244 nTime -= kCFAbsoluteTimeIntervalSince1970;
245 newField = new macabfield;
246 newField->value = CFDateCreate(nullptr, static_cast<CFAbsoluteTime>(nTime));
247 newField->type = _abType;
250 break;
251 case kABIntegerProperty:
254 sal_Int64 nVal = _newFieldString.toInt64();
256 newField = new macabfield;
257 newField->value = CFNumberCreate(nullptr,kCFNumberLongType, &nVal);
258 newField->type = _abType;
260 // bad format...
261 catch(...)
264 break;
265 case kABRealProperty:
268 double nVal = _newFieldString.toDouble();
270 newField = new macabfield;
271 newField->value = CFNumberCreate(nullptr,kCFNumberDoubleType, &nVal);
272 newField->type = _abType;
274 // bad format...
275 catch(...)
278 break;
279 default:
282 return newField;
286 /* Create an OUString out of a macabfield. Together with the method
287 * createMacabField() (above), it is possible to switch conveniently
288 * between an OUString and a macabfield (for use when creating and handling
289 * SQL statement).
291 OUString MacabRecord::fieldToString(const macabfield *_aField)
293 if(_aField == nullptr)
294 return OUString();
296 OUString fieldString;
298 switch(_aField->type)
300 case kABStringProperty:
301 fieldString = CFStringToOUString(static_cast<CFStringRef>(_aField->value));
302 break;
303 case kABDateProperty:
305 DateTime aTime = CFDateToDateTime(static_cast<CFDateRef>(_aField->value));
306 fieldString = DBTypeConversion::toDateTimeString(aTime);
308 break;
309 case kABIntegerProperty:
311 CFNumberType numberType = CFNumberGetType( static_cast<CFNumberRef>(_aField->value) );
312 sal_Int64 nVal;
313 // Should we check for the wrong type here, e.g., a float?
314 bool m_bSuccess = !CFNumberGetValue(static_cast<CFNumberRef>(_aField->value), numberType, &nVal);
315 if(m_bSuccess)
316 fieldString = OUString::number(nVal);
318 break;
319 case kABRealProperty:
321 CFNumberType numberType = CFNumberGetType( static_cast<CFNumberRef>(_aField->value) );
322 double nVal;
323 // Should we check for the wrong type here, e.g., an int?
324 bool m_bSuccess = !CFNumberGetValue(static_cast<CFNumberRef>(_aField->value), numberType, &nVal);
325 if(m_bSuccess)
326 fieldString = OUString::number(nVal);
328 break;
329 default:
332 return fieldString;
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */