source: branches/work_320/lists/ARFieldList.cpp @ 675

Revision 675, 11.9 KB checked in by jls17, 5 years ago (diff)
  • moved the new classes from lists/ARListHelpers.cpp into it's own files in the support directory
  • removed some of the code duplication in UTF8StringList
Line 
1//Copyright (C) 2010 John Luthgers | jls17
2//
3//This file is part of ARInside.
4//
5//    ARInside is free software: you can redistribute it and/or modify
6//    it under the terms of the GNU General Public License as published by
7//    the Free Software Foundation, version 2 of the License.
8//
9//    ARInside is distributed in the hope that it will be useful,
10//    but WITHOUT ANY WARRANTY; without even the implied warranty of
11//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12//    GNU General Public License for more details.
13//
14//    You should have received a copy of the GNU General Public License
15//    along with ARInside.  If not, see <http://www.gnu.org/licenses/>.
16
17#include "stdafx.h"
18#include "ARFieldList.h"
19#include "ARListHelpers.h"
20#include "../ARInside.h"
21#include "../core/ARStatusList.h"
22#include "../util/RefItem.h"
23#include "support/IndexSorter.h"
24
25///////////////////////////////////////////////////////////////////////////////
26// CARFieldList implementation
27bool CARFieldList::FieldReferenceExists(unsigned int index, const CRefItem& refItem)
28{
29        ReferenceList::iterator curIt = workflowReferences[index].begin();
30        ReferenceList::iterator endIt = workflowReferences[index].end();
31
32        for (; curIt != endIt; ++curIt)
33        {
34                if (*curIt == refItem)
35                {
36                        return true;
37                }
38        }       
39        return false;
40}
41
42bool CARFieldList::FieldReferenceAdd(unsigned int index, const CRefItem &refItem)
43{
44        if (refItem.GetObjectType() != AR_STRUCT_ITEM_XML_NONE)
45        {
46                workflowReferences[index].push_back(refItem);
47                return true;
48        }
49        return false;
50}
51
52size_t CARFieldList::FieldReferenceCount(unsigned int index)
53{
54        return workflowReferences[index].size();
55}
56
57const CARFieldList::ReferenceList& CARFieldList::FieldReferenceList(unsigned int index)
58{
59        return workflowReferences[index];
60}
61
62///////////////////////////////////////////////////////////////////////////////
63// CARFieldListXML implementation
64void CARFieldListXML::FinishLoading()
65{
66        if (sortedList.empty() && fieldInfo.numItems > 0)
67        {
68                for (unsigned int i = 0; i < fieldInfo.numItems; ++i)
69                        sortedList.push_back(i);
70        }
71
72        workflowReferences.resize(fieldInfo.numItems);
73
74        Sort();
75}
76
77void CARFieldListXML::Sort()
78{
79        if (GetCount() > 0)
80        {
81                IndexSorter indexSorter(CARInside::GetInstance()->appConfig.bUseUtf8);
82                indexSorter.SortBy(this->fieldInfo).Sort(sortedList);
83        }
84}
85
86
87int CARFieldListXML::Find(const char *name)
88{
89        unsigned int count = GetCount();
90        for (unsigned int i = 0; i < count; ++i)
91        {
92                int result = strcoll(fieldInfo.fieldList[sortedList[i]].fieldName, name);
93                if (result == 0)
94                {
95                        return i;
96                }
97                else if (result > 0)
98                        // the current string in the sorted list is greater as the string we are looking for.
99                        // stop searching here.
100                        break;
101        }
102        return -1;
103}
104
105int CARFieldListXML::Find(unsigned int fieldId)
106{
107        unsigned int count = GetCount();
108        for (unsigned int i = 0; i < count; ++i)
109        {
110                if (fieldInfo.fieldList[sortedList[i]].fieldId == fieldId)
111                        return i;
112        }
113        return -1;
114}
115
116const ARPropList& CARFieldListXML::FieldGetPropList(unsigned int index) const
117{
118#if AR_CURRENT_API_VERSION < AR_API_VERSION_763
119        return emptyPropList;
120#else
121        return fieldInfo.fieldList[sortedList[index]].objPropList; 
122#endif
123}
124
125///////////////////////////////////////////////////////////////////////////////
126// CARFieldListServer implementation
127CARFieldListServer::CARFieldListServer(unsigned int schemaInsideId)
128{
129        schemaId = schemaInsideId;
130        ARZeroMemory(&names);
131        ARZeroMemory(&fieldIds);
132        ARZeroMemory(&fieldMaps);
133        ARZeroMemory(&dataTypes);
134        ARZeroMemory(&options);
135        ARZeroMemory(&createModes);
136        ARZeroMemory(&fieldOptions);
137        ARZeroMemory(&defaultValues);
138        ARZeroMemory(&permLists);
139        ARZeroMemory(&limits);
140        ARZeroMemory(&dInstanceLists);
141        ARZeroMemory(&helpTexts);
142        ARZeroMemory(&changedTimes);
143        ARZeroMemory(&owners);
144        ARZeroMemory(&changedUsers);
145        ARZeroMemory(&changeDiary);
146}
147
148CARFieldListServer::~CARFieldListServer()
149{
150        FreeARNameList(&names, false);
151        FreeARInternalIdList(&fieldIds, false);
152        FreeARFieldMappingList(&fieldMaps, false);
153        FreeARUnsignedIntList(&dataTypes, false);
154        FreeARUnsignedIntList(&options, false);
155        FreeARUnsignedIntList(&createModes, false);
156        FreeARUnsignedIntList(&fieldOptions, false);
157        FreeARValueList(&defaultValues, false);
158        FreeARPermissionListList(&permLists, false);
159        FreeARFieldLimitList(&limits, false);
160        FreeARDisplayInstanceListList(&dInstanceLists, false);
161        FreeARTextStringList(&helpTexts, false);
162        FreeARTimestampList(&changedTimes, false);
163        FreeARAccessNameList(&owners, false);
164        FreeARAccessNameList(&changedUsers, false);
165        FreeARTextStringList(&changeDiary, false);
166}
167
168bool CARFieldListServer::LoadFromServer()
169{
170        ARBooleanList   fldExists;
171        ARStatusList    status;
172        CARInside*      arIn = CARInside::GetInstance();
173        ARNameType                      schemaName; memcpy(schemaName, arIn->schemaList.SchemaGetName(schemaId), sizeof(ARNameType));
174
175        memset(&fldExists, 0, sizeof(ARBooleanList));
176        memset(&status, 0, sizeof(status));
177
178        if (!arIn->appConfig.slowObjectLoading && ARGetMultipleFields(&arIn->arControl,
179                schemaName, 
180                NULL, // all field ids
181                &fldExists,
182                &fieldIds,
183                &names,
184                &fieldMaps,
185                &dataTypes,
186                &options,
187                &createModes,
188                &fieldOptions,
189                &defaultValues,
190#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
191                NULL, // groupListList // TODO: support static inherited permissions
192#endif
193                &permLists,
194                &limits,
195                &dInstanceLists,
196                &helpTexts,
197                &changedTimes,
198                &owners,
199                &changedUsers,
200                &changeDiary,
201#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
202                &objProps,
203#endif
204                &status) == AR_RETURN_OK)
205        {
206                FreeARBooleanList(&fldExists, false);
207                BuildIndex();
208                return true;
209        }
210        else
211        {
212                cerr << BuildMessageAndFreeStatus(status);
213
214                // ok, fallback to slow data retrieval
215                // this could be necessaray if there is a corrupt field that keeps us from getting all fields at once
216                if (!arIn->appConfig.slowObjectLoading)
217                        cout << "WARN: switching to slow field loading for: " << schemaName << endl;
218
219                ARInternalIdList fieldIdList;
220                ARZeroMemory(&fieldIdList);
221
222                if (ARGetListField(&arIn->arControl, schemaName, AR_FIELD_TYPE_ALL, 0, 
223#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
224                        NULL, 
225#endif
226                        &fieldIdList, &status) == AR_RETURN_OK)
227                {
228                        Reserve(fieldIdList.numItems);
229
230                        unsigned int currentWriteIndex = 0;
231                        for (unsigned int idx = 0; idx < fieldIdList.numItems; ++idx)
232                        {
233                                if (ARGetField(&arIn->arControl, schemaName, fieldIdList.internalIdList[idx],
234                                        names.nameList[currentWriteIndex],
235                                        &fieldMaps.mappingList[currentWriteIndex],
236                                        &dataTypes.intList[currentWriteIndex],
237                                        &options.intList[currentWriteIndex],
238                                        &createModes.intList[currentWriteIndex],
239                                        &fieldOptions.intList[currentWriteIndex],
240                                        &defaultValues.valueList[currentWriteIndex],
241#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
242                                        NULL,
243#endif
244                                        &permLists.permissionList[currentWriteIndex],
245                                        &limits.fieldLimitList[currentWriteIndex],
246                                        &dInstanceLists.dInstanceList[currentWriteIndex],
247                                        &helpTexts.stringList[currentWriteIndex],
248                                        &changedTimes.timestampList[currentWriteIndex],
249                                        owners.nameList[currentWriteIndex],
250                                        changedUsers.nameList[currentWriteIndex],
251                                        &changeDiary.stringList[currentWriteIndex],
252#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
253                                        &objProps.propsList[currentWriteIndex],
254#endif
255                                        &status) == AR_RETURN_OK)
256                                {
257                                        fieldIds.internalIdList[currentWriteIndex++] = fieldIdList.internalIdList[idx];
258                                }
259                                else
260                                        cerr << "Schema: " << schemaName << " -- Failed to load field " << fieldIdList.internalIdList[idx] << ": " << BuildMessageAndFreeStatus(status);
261                        }
262                        SetNumItems(currentWriteIndex);
263                        BuildIndex();
264                        return true;
265                }
266                else
267                {
268                        cerr << BuildMessageAndFreeStatus(status);
269                        return false;
270                }
271        }
272}
273
274int CARFieldListServer::Find(const char *name)
275{
276        unsigned int count = GetCount();
277        for (unsigned int i = 0; i < count; ++i)
278        {
279                int result = strcoll(names.nameList[sortedList[i]], name);
280                if (result == 0)
281                {
282                        return i;
283                }
284                else if (result > 0)
285                        // the current string in the sorted list is greater as the string we are looking for.
286                        // stop searching here.
287                        break;
288        }
289        return -1;
290}
291
292int CARFieldListServer::Find(unsigned int fieldId)
293{
294        unsigned int count = GetCount();
295        for (unsigned int i = 0; i < count; ++i)
296        {
297                if (fieldIds.internalIdList[sortedList[i]] == fieldId)
298                        return i;
299        }
300        return -1;
301}
302
303void CARFieldListServer::Sort()
304{
305        if (GetCount() > 0)
306        {
307                IndexSorter indexSorter(CARInside::GetInstance()->appConfig.bUseUtf8);
308                indexSorter.SortBy(names).Sort(sortedList);
309        }
310}
311
312const ARPropList& CARFieldListServer::FieldGetPropList(unsigned int index) const
313{
314#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
315        if (objProps.numItems == 0)
316                return emptyPropList;
317        return objProps.propsList[sortedList[index]];
318#else
319        return emptyPropList;
320#endif
321}
322
323void CARFieldListServer::Reserve(unsigned int amount)
324{
325        names.nameList = new ARNameType[amount];
326        ARZeroMemory(names.nameList, sizeof(ARNameType) * amount);
327
328        fieldIds.internalIdList = new ARInternalId[amount];
329        ARZeroMemory(fieldIds.internalIdList, sizeof(ARInternalId) * amount);
330
331        fieldMaps.mappingList = new ARFieldMappingStruct[amount];
332        ARZeroMemory(fieldMaps.mappingList, sizeof(ARFieldMappingStruct) * amount);
333
334        dataTypes.intList = new unsigned int[amount];
335        ARZeroMemory(dataTypes.intList, sizeof(unsigned int) * amount);
336
337        options.intList = new unsigned int[amount];
338        ARZeroMemory(options.intList, sizeof(unsigned int) * amount);
339
340        createModes.intList = new unsigned int[amount];
341        ARZeroMemory(createModes.intList, sizeof(unsigned int) * amount);
342       
343        fieldOptions.intList = new unsigned int[amount];
344        ARZeroMemory(fieldOptions.intList, sizeof(unsigned int) * amount);
345
346        defaultValues.valueList = new ARValueStruct[amount];
347        ARZeroMemory(defaultValues.valueList, sizeof(ARValueStruct) * amount);
348
349        permLists.permissionList = new ARPermissionList[amount];
350        ARZeroMemory(permLists.permissionList, sizeof(ARPermissionList) * amount);
351
352        limits.fieldLimitList = new ARFieldLimitStruct[amount];
353        ARZeroMemory(limits.fieldLimitList, sizeof(ARFieldLimitStruct) * amount);
354
355        dInstanceLists.dInstanceList = new ARDisplayInstanceList[amount];
356        ARZeroMemory(dInstanceLists.dInstanceList, sizeof(ARDisplayInstanceList) * amount);
357
358        helpTexts.stringList = new char*[amount];
359        ARZeroMemory(helpTexts.stringList, sizeof(char*) * amount);
360
361        changedTimes.timestampList = new ARTimestamp[amount];
362        ARZeroMemory(changedTimes.timestampList, sizeof(ARTimestamp) * amount);
363
364        owners.nameList = new ARAccessNameType[amount];
365        ARZeroMemory(owners.nameList, sizeof(ARAccessNameType) * amount);
366
367        changedUsers.nameList = new ARAccessNameType[amount];
368        ARZeroMemory(changedUsers.nameList, sizeof(ARAccessNameType) * amount);
369
370        changeDiary.stringList = new char*[amount];
371        ARZeroMemory(changeDiary.stringList, sizeof(char*) * amount);
372
373#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
374        objProps.propsList = new ARPropList[amount];
375        ARZeroMemory(objProps.propsList, sizeof(ARPropList) * amount);
376#endif
377}
378
379void CARFieldListServer::SetNumItems(unsigned int amount)
380{
381        names.numItems = amount;
382        fieldIds.numItems = amount;
383        fieldMaps.numItems = amount;
384        dataTypes.numItems = amount;
385        options.numItems = amount;
386        createModes.numItems = amount;
387        fieldOptions.numItems = amount;
388        defaultValues.numItems = amount;
389        permLists.numItems = amount;
390        limits.numItems = amount;
391        dInstanceLists.numItems = amount;
392        helpTexts.numItems = amount;
393        changedTimes.numItems = amount;
394        owners.numItems = amount;
395        changedUsers.numItems = amount;
396        changeDiary.numItems = amount;
397#if AR_CURRENT_API_VERSION >= AR_API_VERSION_763
398        objProps.numItems = amount;
399#endif
400}
401
402void CARFieldListServer::BuildIndex()
403{
404        sortedList.reserve(names.numItems);
405        for (unsigned int i=0; i<names.numItems; ++i)
406        {
407                sortedList.push_back(i);
408        }
409        workflowReferences.resize(names.numItems);
410}
Note: See TracBrowser for help on using the repository browser.