810 lines
25 KiB
C++
810 lines
25 KiB
C++
|
/*
|
||
|
* NOTICE and LICENSE for Tecplot Input/Output Library (TecIO) - OpenFOAM
|
||
|
*
|
||
|
* Copyright (C) 1988-2009 Tecplot, Inc. All rights reserved worldwide.
|
||
|
*
|
||
|
* Tecplot hereby grants OpenCFD limited authority to distribute without
|
||
|
* alteration the source code to the Tecplot Input/Output library, known
|
||
|
* as TecIO, as part of its distribution of OpenFOAM and the
|
||
|
* OpenFOAM_to_Tecplot converter. Users of this converter are also hereby
|
||
|
* granted access to the TecIO source code, and may redistribute it for the
|
||
|
* purpose of maintaining the converter. However, no authority is granted
|
||
|
* to alter the TecIO source code in any form or manner.
|
||
|
*
|
||
|
* This limited grant of distribution does not supersede Tecplot, Inc.'s
|
||
|
* copyright in TecIO. Contact Tecplot, Inc. for further information.
|
||
|
*
|
||
|
* Tecplot, Inc.
|
||
|
* 3535 Factoria Blvd, Ste. 550
|
||
|
* Bellevue, WA 98006, USA
|
||
|
* Phone: +1 425 653 1200
|
||
|
* http://www.tecplot.com/
|
||
|
*
|
||
|
*/
|
||
|
#include "stdafx.h"
|
||
|
#include "MASTER.h"
|
||
|
#define TECPLOTENGINEMODULE
|
||
|
|
||
|
/*
|
||
|
*****************************************************************
|
||
|
*****************************************************************
|
||
|
******* ********
|
||
|
****** Copyright (C) 1988-2008 Tecplot, Inc. ********
|
||
|
******* All Rights Reserved. ********
|
||
|
******* ********
|
||
|
*****************************************************************
|
||
|
*****************************************************************
|
||
|
*/
|
||
|
|
||
|
#define AUXDATAMODULE
|
||
|
#include "GLOBAL.h"
|
||
|
#include "TASSERT.h"
|
||
|
#include "Q_UNICODE.h"
|
||
|
#include "ALLOC.h"
|
||
|
#include "STRUTIL.h"
|
||
|
#include "ARRLIST.h"
|
||
|
#include "DATASET.h"
|
||
|
#include "STRLIST.h"
|
||
|
#if defined TECPLOTKERNEL
|
||
|
/* CORE SOURCE CODE REMOVED */
|
||
|
#endif
|
||
|
#include "SET.h"
|
||
|
#include "AUXDATA.h"
|
||
|
|
||
|
using namespace tecplot::strutil;
|
||
|
|
||
|
/**
|
||
|
* Private auxiliary data item structure.
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
const char *Name;
|
||
|
ArbParam_t Value;
|
||
|
AuxDataType_e Type;
|
||
|
Boolean_t Retain;
|
||
|
} AuxDataItem_s;
|
||
|
|
||
|
/**
|
||
|
* Private auxiliary data item container structure.
|
||
|
*/
|
||
|
typedef struct _AuxData_s
|
||
|
{
|
||
|
/* invariant: ItemList is case-insensitive sorted by AuxDataItem->Name */
|
||
|
ArrayList_pa ItemList; /* <AuxDataItem_s *>[dynamic] */
|
||
|
} AuxData_s;
|
||
|
|
||
|
static Mutex_pa AuxDataMutex = NULL;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* A valid auxiliary data name character must begin with a '_' or alpha
|
||
|
* character and may be followed by one or more '_', '.', alpha or digit
|
||
|
* characters.
|
||
|
*/
|
||
|
Boolean_t AuxDataIsValidNameChar(char Char,
|
||
|
Boolean_t IsLeadChar)
|
||
|
{
|
||
|
Boolean_t IsValidNameChar;
|
||
|
|
||
|
REQUIRE("Char can be any value");
|
||
|
REQUIRE(VALID_BOOLEAN(IsLeadChar));
|
||
|
|
||
|
IsValidNameChar = (Char == '_' ||
|
||
|
isalpha(Char));
|
||
|
if (!IsLeadChar)
|
||
|
IsValidNameChar = (IsValidNameChar ||
|
||
|
Char == '.' ||
|
||
|
isdigit(Char));
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(IsValidNameChar));
|
||
|
return IsValidNameChar;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Indicates if the auxiliary data name is valid. A valid auxiliary data name
|
||
|
* must begin with a '_' or alpha character and may be followed by one or
|
||
|
* more '_', '.', alpha or digit characters.
|
||
|
*/
|
||
|
Boolean_t AuxDataIsValidName(const char *Name)
|
||
|
{
|
||
|
Boolean_t IsValidName;
|
||
|
const char *NPtr;
|
||
|
REQUIRE(VALID_REF(Name));
|
||
|
|
||
|
for (NPtr = Name, IsValidName = AuxDataIsValidNameChar(*NPtr, TRUE);
|
||
|
IsValidName && *NPtr != '\0';
|
||
|
NPtr++)
|
||
|
{
|
||
|
IsValidName = AuxDataIsValidNameChar(*NPtr, FALSE);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(IsValidName));
|
||
|
return IsValidName;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deallocates an auxiliary data item and its contents and sets the target to
|
||
|
* NULL.
|
||
|
*
|
||
|
* param AuxDataItem
|
||
|
* Reference to an auxiliary data item.
|
||
|
*/
|
||
|
static void AuxDataItemDealloc(AuxDataItem_s **AuxDataItem)
|
||
|
{
|
||
|
REQUIRE(VALID_REF(AuxDataItem));
|
||
|
REQUIRE(VALID_REF(*AuxDataItem) || *AuxDataItem == NULL);
|
||
|
|
||
|
if (*AuxDataItem != NULL)
|
||
|
{
|
||
|
char *Name = (char *)(*AuxDataItem)->Name;
|
||
|
if (Name != NULL)
|
||
|
FREE_ARRAY(Name, "auxiliary name");
|
||
|
|
||
|
if ((*AuxDataItem)->Type == AuxDataType_String)
|
||
|
{
|
||
|
char *Value = (char *)(*AuxDataItem)->Value;
|
||
|
if (Value != NULL)
|
||
|
FREE_ARRAY(Value, "auxiliary value");
|
||
|
}
|
||
|
else
|
||
|
CHECK(FALSE);
|
||
|
|
||
|
FREE_ITEM(*AuxDataItem, "auxiliary data item");
|
||
|
*AuxDataItem = NULL;
|
||
|
}
|
||
|
|
||
|
ENSURE(*AuxDataItem == NULL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Allocates an auxiliary data item.
|
||
|
*
|
||
|
* NOTE: Copies are made of the name and value.
|
||
|
*
|
||
|
* param Name
|
||
|
* Auxiliary data item's name (case insenstive).
|
||
|
* param Value
|
||
|
* Auxiliary data item's value.
|
||
|
* param Type
|
||
|
* Auxiliary data item's value type.
|
||
|
* param Retain
|
||
|
* Indicates if the auxiliary data item should persist. In other words
|
||
|
* copied, saved, etc.
|
||
|
*
|
||
|
* return
|
||
|
* A new auxiliary data item or NULL if sufficient memory was not
|
||
|
* available.
|
||
|
*/
|
||
|
static AuxDataItem_s *AuxDataItemAlloc(const char *Name,
|
||
|
ArbParam_t Value,
|
||
|
AuxDataType_e Type,
|
||
|
Boolean_t Retain)
|
||
|
{
|
||
|
AuxDataItem_s *Result;
|
||
|
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
REQUIRE(IMPLICATION(Type == AuxDataType_String,
|
||
|
(VALID_REF((char *)Value) ||
|
||
|
(char *)Value == NULL)));
|
||
|
REQUIRE(VALID_ENUM(Type, AuxDataType_e));
|
||
|
REQUIRE(VALID_BOOLEAN(Retain));
|
||
|
|
||
|
Result = ALLOC_ITEM(AuxDataItem_s, "auxiliary data item");
|
||
|
if (Result != NULL)
|
||
|
{
|
||
|
Boolean_t IsOk;
|
||
|
Result->Type = Type;
|
||
|
Result->Retain = Retain;
|
||
|
Result->Name = DupString(dontTranslate(Name));
|
||
|
IsOk = (Result->Name != NULL);
|
||
|
Result->Value = 0; /* to satisfy some compilers' uninitialized warnings */
|
||
|
if (IsOk && Type == AuxDataType_String)
|
||
|
{
|
||
|
char *strValue = (char *)Value;
|
||
|
if (strValue != NULL)
|
||
|
{
|
||
|
char *strCopy = DupString(dontTranslate(strValue));
|
||
|
Result->Value = (ArbParam_t)strCopy;
|
||
|
IsOk = (strCopy != NULL);
|
||
|
}
|
||
|
else
|
||
|
Result->Value = (ArbParam_t)NULL;
|
||
|
}
|
||
|
else
|
||
|
CHECK(FALSE);
|
||
|
|
||
|
if (!IsOk)
|
||
|
AuxDataItemDealloc(&Result);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_REF(Result) || Result == NULL);
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Destroys an auxiliary data item list item. This is an item destructor
|
||
|
* callback for ArrayList's private data.
|
||
|
*
|
||
|
* param ItemRef
|
||
|
* Reference to the auxiliary data item to cleanup.
|
||
|
* param ClientData
|
||
|
* Not used.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE is a requirement
|
||
|
*/
|
||
|
static Boolean_t AuxDataItemListItemDestructor(void *ItemRef,
|
||
|
ArbParam_t ClientData)
|
||
|
{
|
||
|
AuxDataItem_s **AuxDataItemRef = (AuxDataItem_s **)ItemRef;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxDataItemRef));
|
||
|
REQUIRE(VALID_REF(*AuxDataItemRef) || *AuxDataItemRef == NULL);
|
||
|
|
||
|
if (*AuxDataItemRef != NULL)
|
||
|
AuxDataItemDealloc(AuxDataItemRef);
|
||
|
|
||
|
ENSURE(*AuxDataItemRef == NULL);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Destroys an auxiliary data item. This is an item destructor
|
||
|
* callback for ArrayList's private data.
|
||
|
*
|
||
|
* param ItemRef
|
||
|
* Reference to the auxiliary data to cleanup.
|
||
|
* param ClientData
|
||
|
* Not used.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE is a requirement
|
||
|
*/
|
||
|
Boolean_t AuxDataItemDestructor(void *ItemRef,
|
||
|
ArbParam_t ClientData)
|
||
|
{
|
||
|
AuxData_pa *AuxDataRef = (AuxData_pa *)ItemRef;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxDataRef));
|
||
|
REQUIRE(VALID_REF(*AuxDataRef) || *AuxDataRef == NULL);
|
||
|
|
||
|
if (*AuxDataRef != NULL)
|
||
|
AuxDataDealloc(AuxDataRef);
|
||
|
|
||
|
ENSURE(*AuxDataRef == NULL);
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Duplicates an auxiliary data item if its Retain flag is TRUE or if directed
|
||
|
* by the callback data. This is an item duplicator callback for ArrayList.
|
||
|
*
|
||
|
* param TargetItemRef
|
||
|
* Reference to the auxiliary data item to receive duplicate.
|
||
|
* param SourceItemRef
|
||
|
* Reference to the auxiliary data item to duplicate.
|
||
|
* param ClientData
|
||
|
* Boolean indicating if the Retain flag should be considered.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE if the duplication was a success
|
||
|
* FALSE otherwise.
|
||
|
*/
|
||
|
static Boolean_t AuxDataItemDuplicator(void *TargetItemRef,
|
||
|
void *SourceItemRef,
|
||
|
ArbParam_t ClientData)
|
||
|
{
|
||
|
Boolean_t IsOk = TRUE;
|
||
|
AuxDataItem_s **TargetAuxDataItemRef = (AuxDataItem_s **)TargetItemRef;
|
||
|
AuxDataItem_s **SourceAuxDataItemRef = (AuxDataItem_s **)SourceItemRef;
|
||
|
Boolean_t ConsiderRetain;
|
||
|
|
||
|
REQUIRE(VALID_REF(TargetAuxDataItemRef));
|
||
|
REQUIRE(VALID_REF(SourceAuxDataItemRef));
|
||
|
REQUIRE(VALID_REF(*SourceAuxDataItemRef) || *SourceAuxDataItemRef == NULL);
|
||
|
REQUIRE(VALID_BOOLEAN((Boolean_t)ClientData));
|
||
|
|
||
|
ConsiderRetain = (Boolean_t)ClientData;
|
||
|
|
||
|
/* duplicate the item */
|
||
|
if (*SourceAuxDataItemRef != NULL &&
|
||
|
(!ConsiderRetain || (*SourceAuxDataItemRef)->Retain))
|
||
|
{
|
||
|
*TargetAuxDataItemRef = AuxDataItemAlloc((*SourceAuxDataItemRef)->Name,
|
||
|
(*SourceAuxDataItemRef)->Value,
|
||
|
(*SourceAuxDataItemRef)->Type,
|
||
|
(*SourceAuxDataItemRef)->Retain);
|
||
|
IsOk = (*TargetAuxDataItemRef != NULL);
|
||
|
}
|
||
|
else
|
||
|
*TargetAuxDataItemRef = NULL;
|
||
|
|
||
|
ENSURE(VALID_REF(*TargetAuxDataItemRef) || *TargetAuxDataItemRef == NULL);
|
||
|
ENSURE(VALID_BOOLEAN(IsOk));
|
||
|
return IsOk;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deallocates an auxiliary data handle and sets the handle to NULL.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Reference to an auxiliary data handle or reference to NULL.
|
||
|
*/
|
||
|
void AuxDataDealloc(AuxData_pa *AuxData)
|
||
|
{
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
REQUIRE(VALID_REF(*AuxData) || *AuxData == NULL);
|
||
|
|
||
|
if (*AuxData != NULL)
|
||
|
{
|
||
|
ArrayListDealloc(&(*AuxData)->ItemList, AuxDataItemListItemDestructor, 0);
|
||
|
FREE_ITEM(*AuxData, "auxiliary data container");
|
||
|
*AuxData = NULL;
|
||
|
}
|
||
|
|
||
|
ENSURE(*AuxData == NULL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Allocates an auxiliary data handle.
|
||
|
*
|
||
|
* return
|
||
|
* Auxiliary data handle or NULL if sufficient memory was not available.
|
||
|
*/
|
||
|
AuxData_pa AuxDataAlloc(void)
|
||
|
{
|
||
|
AuxData_pa Result = ALLOC_ITEM(AuxData_s, "auxiliary data container");
|
||
|
if (Result != NULL)
|
||
|
{
|
||
|
Result->ItemList = ArrayListAlloc(0, ArrayListType_VoidPtr, NULL, 0);
|
||
|
if (Result->ItemList == NULL)
|
||
|
AuxDataDealloc(&Result);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_REF(Result) || Result == NULL);
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Copies the auxiliary data and all its members who's Retain flag is TRUE
|
||
|
* if the ConsiderRetain flag is TRUE otherwise it copies everything.
|
||
|
*/
|
||
|
AuxData_pa AuxDataCopy(AuxData_pa AuxData,
|
||
|
Boolean_t ConsiderRetain)
|
||
|
{
|
||
|
AuxData_pa Result;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
REQUIRE(VALID_BOOLEAN(ConsiderRetain));
|
||
|
|
||
|
Result = ALLOC_ITEM(AuxData_s, "auxiliary data container");
|
||
|
if (Result != NULL)
|
||
|
{
|
||
|
Result->ItemList = ArrayListCopy(AuxData->ItemList,
|
||
|
AuxDataItemDuplicator,
|
||
|
ConsiderRetain);
|
||
|
if (Result->ItemList != NULL)
|
||
|
{
|
||
|
if (ConsiderRetain)
|
||
|
{
|
||
|
/*
|
||
|
* Now pass through the array cleaning up the holes left by those
|
||
|
* auxiliary data item member who's Retain flag was FALSE and
|
||
|
* therefore left a VOID pointer because it was not copied.
|
||
|
*/
|
||
|
LgIndex_t ItemOffset = 0;
|
||
|
LgIndex_t ItemCount = ArrayListGetCount(Result->ItemList);
|
||
|
while (ItemOffset < ItemCount)
|
||
|
{
|
||
|
/* if there is more than one in a row remove them all at once */
|
||
|
if (ArrayListGetVoidPtr(Result->ItemList, ItemOffset) == NULL)
|
||
|
{
|
||
|
LgIndex_t BaseOffsetToRemove = ItemOffset;
|
||
|
LgIndex_t NumItemsToRemove = 1;
|
||
|
while (BaseOffsetToRemove + NumItemsToRemove < ItemCount &&
|
||
|
ArrayListGetVoidPtr(Result->ItemList,
|
||
|
BaseOffsetToRemove + NumItemsToRemove) == NULL)
|
||
|
NumItemsToRemove++;
|
||
|
|
||
|
/* delete the NULL items */
|
||
|
ArrayListDeleteItems(Result->ItemList,
|
||
|
BaseOffsetToRemove,
|
||
|
NumItemsToRemove,
|
||
|
NULL, 0);
|
||
|
|
||
|
/*
|
||
|
* Update ItemCount but leave ItemOffset alone as it is now
|
||
|
* indexing the next item to examine.
|
||
|
*/
|
||
|
ItemCount = ArrayListGetCount(Result->ItemList);
|
||
|
}
|
||
|
else
|
||
|
ItemOffset++;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
AuxDataDealloc(&Result);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_REF(Result) || Result == NULL);
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the current number of auxiliary data items maintained by the auxiliary.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Handle to auxiliary data.
|
||
|
*
|
||
|
* return
|
||
|
* Number of items maintained by the auxiliary data.
|
||
|
*/
|
||
|
LgIndex_t AuxDataGetNumItems(AuxData_pa AuxData)
|
||
|
{
|
||
|
LgIndex_t NumItems;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
|
||
|
NumItems = ArrayListGetCount(AuxData->ItemList);
|
||
|
|
||
|
ENSURE(NumItems >= 0);
|
||
|
return NumItems;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the item index of the name if found or if not found the index where an
|
||
|
* auxiliary data item could be inserted.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Handle to auxiliary data.
|
||
|
* param Name
|
||
|
* Name used for the search (case insensitive).
|
||
|
* param ItemIndex
|
||
|
* Address to hold the index of the found item or the index where an
|
||
|
* auxiliary data item could be inserted.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE if the named item was found,
|
||
|
* FALSE otherwise.
|
||
|
*/
|
||
|
Boolean_t AuxDataGetItemIndex(AuxData_pa AuxData,
|
||
|
const char *Name,
|
||
|
LgIndex_t *ItemIndex)
|
||
|
{
|
||
|
Boolean_t FoundItem = FALSE;
|
||
|
LgIndex_t Index;
|
||
|
LgIndex_t NumItems;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
REQUIRE(VALID_REF(ItemIndex));
|
||
|
|
||
|
/*
|
||
|
* Note that the current implementation just does a linear search
|
||
|
* though the array looking for the index of the item or if not
|
||
|
* found the index of the insertion point. This should be replaced
|
||
|
* with a binary search.
|
||
|
*/
|
||
|
NumItems = AuxDataGetNumItems(AuxData);
|
||
|
|
||
|
# if defined DO_LINEAR_SEARCH
|
||
|
{
|
||
|
for (Index = 0; Index < NumItems; Index++)
|
||
|
{
|
||
|
AuxDataItem_s *AuxDataItem =
|
||
|
(AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index);
|
||
|
int CompareResult = ustrcmp(AuxDataItem->Name, Name);
|
||
|
if (CompareResult >= 0)
|
||
|
{
|
||
|
FoundItem = (CompareResult == 0);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
# else
|
||
|
{
|
||
|
int low, high;
|
||
|
low = 0;
|
||
|
high = NumItems - 1;
|
||
|
Index = 0;
|
||
|
while (low <= high)
|
||
|
{
|
||
|
AuxDataItem_s *AuxDataItem;
|
||
|
int CompareResult;
|
||
|
Index = (low + high) / 2;
|
||
|
AuxDataItem = (AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index);
|
||
|
CompareResult = ustrcmp(Name, AuxDataItem->Name);
|
||
|
if (CompareResult < 0)
|
||
|
high = Index - 1; /* If the new name is "less" than the one we're comparing to,
|
||
|
don't change Index since Index is already in the right spot */
|
||
|
else if (CompareResult > 0)
|
||
|
low = ++Index; /* If the new name it "greater" than the one we're comparing
|
||
|
against, we want to make sure its Index is greater than
|
||
|
the current name's index as well, that's why we increment Index here. */
|
||
|
else
|
||
|
{
|
||
|
FoundItem = TRUE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
# endif
|
||
|
|
||
|
*ItemIndex = Index;
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(FoundItem));
|
||
|
ENSURE(0 <= *ItemIndex &&
|
||
|
((FoundItem && *ItemIndex < NumItems) ||
|
||
|
(!FoundItem && *ItemIndex <= NumItems)));
|
||
|
return FoundItem;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the auxiliary data item at the specified index.
|
||
|
*
|
||
|
* NOTE: The name and value are a references, NOT copies.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Handle to auxiliary data.
|
||
|
* param Index
|
||
|
* Index of the auxiliary data item of interest.
|
||
|
* param Name
|
||
|
* Address to hold the auxiliary data item name.
|
||
|
* param Value
|
||
|
* Address to hold the auxiliary data item value.
|
||
|
* param Type
|
||
|
* Address to hold the auxiliary data item type.
|
||
|
* param Retain
|
||
|
* Address to hold the auxiliary data item retain flag.
|
||
|
*/
|
||
|
void AuxDataGetItemByIndex(AuxData_pa AuxData,
|
||
|
LgIndex_t Index,
|
||
|
const char **Name,
|
||
|
ArbParam_t *Value,
|
||
|
AuxDataType_e *Type,
|
||
|
Boolean_t *Retain)
|
||
|
{
|
||
|
AuxDataItem_s *AuxDataItem;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
REQUIRE(0 <= Index && Index < ArrayListGetCount(AuxData->ItemList));
|
||
|
REQUIRE(VALID_REF(Name));
|
||
|
REQUIRE(VALID_REF(Value));
|
||
|
REQUIRE(VALID_REF(Type));
|
||
|
REQUIRE(VALID_REF(Retain));
|
||
|
|
||
|
AuxDataItem = (AuxDataItem_s *)ArrayListGetVoidPtr(AuxData->ItemList, Index);
|
||
|
*Name = AuxDataItem->Name;
|
||
|
*Value = AuxDataItem->Value;
|
||
|
*Type = AuxDataItem->Type;
|
||
|
*Retain = AuxDataItem->Retain;
|
||
|
|
||
|
ENSURE(VALID_REF(*Name) && AuxDataIsValidName(*Name));
|
||
|
ENSURE(IMPLICATION(*Type == AuxDataType_String,
|
||
|
(VALID_REF((char *)(*Value)) ||
|
||
|
(char *)(*Value) == NULL)));
|
||
|
ENSURE(VALID_ENUM(*Type, AuxDataType_e));
|
||
|
ENSURE(VALID_BOOLEAN(*Retain));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Gets the auxiliary data item by the specified name if it exists.
|
||
|
*
|
||
|
* NOTE: The name and value are a references, NOT copies.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Handle to auxiliary data.
|
||
|
* param Name
|
||
|
* Name used for the search (case insensitive).
|
||
|
* param Value
|
||
|
* Address to hold the auxiliary data item value.
|
||
|
* param Type
|
||
|
* Address to hold the auxiliary data item type.
|
||
|
* param Retain
|
||
|
* Address to hold the auxiliary data item retain flag.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE if the an auxilary data item by the specified name was found,
|
||
|
* FALSE otherwise.
|
||
|
*/
|
||
|
Boolean_t AuxDataGetItemByName(AuxData_pa AuxData,
|
||
|
const char *Name,
|
||
|
ArbParam_t *Value,
|
||
|
AuxDataType_e *Type,
|
||
|
Boolean_t *Retain)
|
||
|
{
|
||
|
Boolean_t FoundItem;
|
||
|
LgIndex_t ItemIndex;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
REQUIRE(VALID_REF(Value));
|
||
|
REQUIRE(VALID_REF(Type));
|
||
|
REQUIRE(VALID_REF(Retain));
|
||
|
|
||
|
FoundItem = AuxDataGetItemIndex(AuxData, Name, &ItemIndex);
|
||
|
if (FoundItem)
|
||
|
{
|
||
|
const char *SameName;
|
||
|
AuxDataGetItemByIndex(AuxData, ItemIndex, &SameName,
|
||
|
Value, Type, Retain);
|
||
|
CHECK(ustrcmp(Name, SameName) == 0);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(FoundItem));
|
||
|
ENSURE(IMPLICATION(FoundItem,
|
||
|
IMPLICATION(*Type == AuxDataType_String,
|
||
|
(VALID_REF((char *)(*Value)) ||
|
||
|
(char *)(*Value) == NULL))));
|
||
|
ENSURE(IMPLICATION(FoundItem,
|
||
|
VALID_ENUM(*Type, AuxDataType_e)));
|
||
|
ENSURE(IMPLICATION(FoundItem,
|
||
|
VALID_BOOLEAN(*Retain)));
|
||
|
return FoundItem;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Get a string value from AuxData and convert it to a boolean.
|
||
|
*/
|
||
|
Boolean_t AuxDataGetBooleanItemByName(AuxData_pa AuxData, /* IN */
|
||
|
const char *Name, /* IN */
|
||
|
Boolean_t *Value, /* OUT */
|
||
|
AuxDataType_e *Type, /* OUT */
|
||
|
Boolean_t *Retain) /* OUT */
|
||
|
{
|
||
|
Boolean_t FoundItem;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
REQUIRE(VALID_REF(Value));
|
||
|
REQUIRE(VALID_REF(Type));
|
||
|
REQUIRE(VALID_REF(Retain));
|
||
|
|
||
|
ArbParam_t strValue;
|
||
|
FoundItem = AuxDataGetItemByName(AuxData,
|
||
|
Name,
|
||
|
&strValue,
|
||
|
Type,
|
||
|
Retain);
|
||
|
|
||
|
if (FoundItem &&
|
||
|
(ustrcmp((char *)strValue, "YES") == 0 ||
|
||
|
ustrcmp((char *)strValue, "YEP") == 0 ||
|
||
|
ustrcmp((char *)strValue, "Y") == 0 ||
|
||
|
ustrcmp((char *)strValue, "TRUE") == 0 ||
|
||
|
ustrcmp((char *)strValue, "T") == 0 ||
|
||
|
ustrcmp((char *)strValue, "ON") == 0 ||
|
||
|
ustrcmp((char *)strValue, "1") == 0))
|
||
|
{
|
||
|
*Value = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*Value = FALSE;
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(FoundItem));
|
||
|
ENSURE(VALID_BOOLEAN(*Value));
|
||
|
return FoundItem;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Adds the auxiliary data item to the auxiliary data or replaces it if one
|
||
|
* already exists by the same name.
|
||
|
*
|
||
|
* NOTE: The auxiliary data makes copies of the name and value.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Auxiliary data handle.
|
||
|
* param Name
|
||
|
* Auxiliary data item's name (case insenstive).
|
||
|
* param Value
|
||
|
* Auxiliary data item's value.
|
||
|
* param Type
|
||
|
* Auxiliary data item's value type.
|
||
|
* param Retain
|
||
|
* Indicates if the auxiliary data item should persist.
|
||
|
*
|
||
|
* return
|
||
|
* TRUE if the item was added to the auxiliary data.
|
||
|
*/
|
||
|
Boolean_t AuxDataSetItem(AuxData_pa AuxData,
|
||
|
const char *Name,
|
||
|
ArbParam_t Value,
|
||
|
AuxDataType_e Type,
|
||
|
Boolean_t Retain)
|
||
|
{
|
||
|
Boolean_t IsOk;
|
||
|
AuxDataItem_s *AuxDataItem;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
REQUIRE(IMPLICATION(Type == AuxDataType_String,
|
||
|
(VALID_REF((char *)Value) ||
|
||
|
(char *)Value == NULL)));
|
||
|
REQUIRE(VALID_ENUM(Type, AuxDataType_e));
|
||
|
REQUIRE(VALID_BOOLEAN(Retain));
|
||
|
|
||
|
AuxDataItem = AuxDataItemAlloc(Name, Value, Type, Retain);
|
||
|
IsOk = (AuxDataItem != NULL);
|
||
|
if (IsOk)
|
||
|
{
|
||
|
LgIndex_t ItemIndex;
|
||
|
ArrayListItem_u ListItem;
|
||
|
|
||
|
/* add or replace the item to the list */
|
||
|
ListItem.VoidPtr = (void *)AuxDataItem;
|
||
|
if (!AuxDataGetItemIndex(AuxData, Name, &ItemIndex))
|
||
|
IsOk = ArrayListInsertItem(AuxData->ItemList, ItemIndex, ListItem);
|
||
|
else
|
||
|
IsOk = ArrayListSetItem(AuxData->ItemList, ItemIndex, ListItem,
|
||
|
AuxDataItemListItemDestructor, 0);
|
||
|
|
||
|
if (!IsOk)
|
||
|
AuxDataItemDealloc(&AuxDataItem);
|
||
|
}
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(IsOk));
|
||
|
INVARIANT("AuxData->ItemList is case-insensitive sorted by AuxDataItem->Name");
|
||
|
return IsOk;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deletes the auxiliary data item at the specified index.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Auxiliary data handle.
|
||
|
* param Index
|
||
|
* Index of the auxiliary data item of interest.
|
||
|
*/
|
||
|
void AuxDataDeleteItemByIndex(AuxData_pa AuxData,
|
||
|
LgIndex_t Index)
|
||
|
{
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
REQUIRE(0 <= Index && Index < ArrayListGetCount(AuxData->ItemList));
|
||
|
|
||
|
ArrayListDeleteItem(AuxData->ItemList, Index, AuxDataItemListItemDestructor, 0);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Deletes the auxiliary data item by the specified name if it exists.
|
||
|
*
|
||
|
* param AuxData
|
||
|
* Auxiliary data handle.
|
||
|
* param Name
|
||
|
* Name used for the search (case insensitive).
|
||
|
*
|
||
|
* return
|
||
|
* TRUE if the an auxilary data item by the specified name was found,
|
||
|
* FALSE otherwise.
|
||
|
*/
|
||
|
Boolean_t AuxDataDeleteItemByName(AuxData_pa AuxData,
|
||
|
const char *Name)
|
||
|
{
|
||
|
Boolean_t FoundItem;
|
||
|
LgIndex_t ItemIndex;
|
||
|
|
||
|
REQUIRE(VALID_REF(AuxData));
|
||
|
REQUIRE(VALID_REF(Name) && AuxDataIsValidName(Name));
|
||
|
|
||
|
FoundItem = AuxDataGetItemIndex(AuxData, Name, &ItemIndex);
|
||
|
if (FoundItem)
|
||
|
AuxDataDeleteItemByIndex(AuxData, ItemIndex);
|
||
|
|
||
|
ENSURE(VALID_BOOLEAN(FoundItem));
|
||
|
return FoundItem;
|
||
|
}
|
||
|
|
||
|
#if defined TECPLOTKERNEL
|
||
|
/* CORE SOURCE CODE REMOVED */
|
||
|
#endif /* TECPLOTKERNEL */
|