Dryad/DryadVertex/VertexHost/system/common/include/dryadmetadata.h

289 lines
13 KiB
C++

/*
Copyright (c) Microsoft Corporation
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License
at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
*/
#pragma once
#pragma warning(disable:4512)
#pragma warning(disable:4511)
#pragma warning(disable:4995)
#include <DrCommon.h>
#include "dryadmetadatatag.h"
#include "dryadmetadatatagtypes.h"
#include <map>
#include <list>
class DryadMetaDataConst;
class DryadMetaData;
typedef DrRef<DryadMetaData> DryadMetaDataRef;
class DryadMetaData : public DrRefCounter
{
public:
typedef std::list<DryadMTag *> TagList;
typedef TagList::iterator TagListIter;
typedef std::multimap< UInt16,DryadMTag * > TagMap;
typedef TagMap::iterator TagMapIter;
/* the following method places a reference to a new, empty,
DryadMetaData object in the caller's dstMetaData object. */
static void Create(DryadMetaDataRef* dstMetaData);
/* this appends tag to the end of self's tag list and transfers
the caller's reference to tag. If allowDuplicateTags is false
and there is a tag of the same name in self, tag is not
appended to self and its reference count is
decremented. Returns true if and only if tag was appended to
self. */
bool Append(DryadMTag* tag, bool allowDuplicateTags);
/* this appends all the tags in metaData to the end of self's tag
list without modifying metaData (incrementing each tag's
refcount). If allowDuplicateTags is false then any tags in
metaData which already exist in self are not appended. */
void AppendMetaDataTags(DryadMetaData* metaData, bool allowDuplicateTags);
/* this replaces oldTag with newTag in self's tag list. It is an
error to call Replace with oldTag and newTag which do not have
the same tag value. If oldTag is not in self's tag list this
returns false and does not alter any reference counts,
otherwise it returns true, transfers the caller's reference to
newTag into self and discards self's reference to oldTag.
*/
bool Replace(DryadMTag* newTag, DryadMTag* oldTag);
/* this removes tag from self's tag list. If tag is not in self's
tag list this returns false and does not alter any reference
counts, otherwise it returns true and discards self's reference
to tag.
*/
bool Remove(DryadMTag* tag);
/* this returns the tag with ID enumID if and only if there is
a unique tag with that name in self's list, otherwise it
returns NULL. This call does not modify the tag's reference
count. */
DryadMTag* LookUpTag(UInt16 enumID);
/* the following type-safe lookup methods return non-NULL if and
only if there is a unique tag in self with ID enumID and the
correct type. These calls do not modify the tag's reference
count. */
DryadMTagUnknown* LookUpUnknownTag(UInt16 enumID);
DryadMTagVoid* LookUpVoidTag(UInt16 enumID);
DryadMTagBoolean* LookUpBooleanTag(UInt16 enumID);
DryadMTagInt16* LookUpInt16Tag(UInt16 enumID);
DryadMTagUInt16* LookUpUInt16Tag(UInt16 enumID);
DryadMTagInt32* LookUpInt32Tag(UInt16 enumID);
DryadMTagUInt32* LookUpUInt32Tag(UInt16 enumID);
DryadMTagInt64* LookUpInt64Tag(UInt16 enumID);
DryadMTagUInt64* LookUpUInt64Tag(UInt16 enumID);
DryadMTagString* LookUpStringTag(UInt16 enumID);
DryadMTagGuid* LookUpGuidTag(UInt16 enumID);
DryadMTagTimeStamp* LookUpTimeStampTag(UInt16 enumID);
DryadMTagTimeInterval* LookUpTimeIntervalTag(UInt16 enumID);
DryadMTagDrError* LookUpDrErrorTag(UInt16 enumID);
DryadMTagMetaData* LookUpMetaDataTag(UInt16 enumID);
DryadMTagVertexCommand* LookUpVertexCommandTag(UInt16 enumID);
DryadMTagInputChannelDescription*
LookUpInputChannelDescriptionTag(UInt16 enumID);
DryadMTagOutputChannelDescription*
LookUpOutputChannelDescriptionTag(UInt16 enumID);
DryadMTagVertexProcessStatus* LookUpVertexProcessStatusTag(UInt16 enumID);
DryadMTagVertexStatus* LookUpVertexStatusTag(UInt16 enumID);
DryadMTagVertexCommandBlock* LookUpVertexCommandBlockTag(UInt16 enumID);
/* the following type-safe lookup methods return DrError_OK if and
only if there is a unique tag in self with ID enumID and the
correct type. */
DrError LookUpVoid(UInt16 enumID);
DrError LookUpBoolean(UInt16 enumID, bool* pVal /* out */);
DrError LookUpInt16(UInt16 enumID, Int16* pVal /* out */);
DrError LookUpUInt16(UInt16 enumID, UInt16* pVal /* out */);
DrError LookUpInt32(UInt16 enumID, Int32* pVal /* out */);
DrError LookUpUInt32(UInt16 enumID, UInt32* pVal /* out */);
DrError LookUpInt64(UInt16 enumID, Int64* pVal /* out */);
DrError LookUpUInt64(UInt16 enumID, UInt64* pVal /* out */);
DrError LookUpString(UInt16 enumID, const char** pVal /* out */);
DrError LookUpGuid(UInt16 enumID, const DrGuid** pVal /* out */);
DrError LookUpTimeStamp(UInt16 enumID, DrTimeStamp* pVal /* out */);
DrError LookUpTimeInterval(UInt16 enumID, DrTimeInterval* pVal /* out */);
DrError LookUpDrError(UInt16 enumID, DrError* pVal /* out */);
DrError LookUpMetaData(UInt16 enumID, DryadMetaDataRef* pVal /* out */);
DrError LookUpVertexCommand(UInt16 enumID, DVertexCommand* pVal /* out */);
DrError LookUpInputChannelDescription(UInt16 enumID,
DryadInputChannelDescription**
pVal /* out */);
DrError LookUpOutputChannelDescription(UInt16 enumID,
DryadOutputChannelDescription**
pVal /* out */);
DrError LookUpVertexProcessStatus(UInt16 enumID,
DVertexProcessStatus** pVal /* out */);
DrError LookUpVertexStatus(UInt16 enumID, DVertexStatus** pVal /* out */);
DrError LookUpVertexCommandBlock(UInt16 enumID,
DVertexCommandBlock** pVal /* out */);
/* the following type-safe append methods return true if and only
if the tag was appended. */
bool AppendVoid(UInt16 enumID,
bool allowDuplicateTags);
bool AppendBoolean(UInt16 enumID, bool value,
bool allowDuplicateTags);
bool AppendInt16(UInt16 enumID, Int16 value,
bool allowDuplicateTags);
bool AppendUInt16(UInt16 enumID, UInt16 value,
bool allowDuplicateTags);
bool AppendInt32(UInt16 enumID, Int32 value,
bool allowDuplicateTags);
bool AppendUInt32(UInt16 enumID, UInt32 value,
bool allowDuplicateTags);
bool AppendInt64(UInt16 enumID, Int64 value,
bool allowDuplicateTags);
bool AppendUInt64(UInt16 enumID, UInt64 value,
bool allowDuplicateTags);
bool AppendString(UInt16 enumID, const char* value,
bool allowDuplicateTags);
bool AppendGuid(UInt16 enumID, const DrGuid* value,
bool allowDuplicateTags);
bool AppendTimeStamp(UInt16 enumID, DrTimeStamp value,
bool allowDuplicateTags);
bool AppendTimeInterval(UInt16 enumID, DrTimeInterval value,
bool allowDuplicateTags);
bool AppendDrError(UInt16 enumID, DrError value,
bool allowDuplicateTags);
bool AppendMetaData(UInt16 enumID, DryadMetaData* value,
bool marshalAsAggregate,
bool allowDuplicateTags);
bool AppendVertexCommand(UInt16 enumID, DVertexCommand value,
bool allowDuplicateTags);
bool AppendInputChannelDescription(UInt16 enumID,
DryadInputChannelDescription* value,
bool allowDuplicateTags);
bool AppendOutputChannelDescription(UInt16 enumID,
DryadOutputChannelDescription* value,
bool allowDuplicateTags);
bool AppendVertexProcessStatus(UInt16 enumID, DVertexProcessStatus* value,
bool allowDuplicateTags);
bool AppendVertexStatus(UInt16 enumID, DVertexStatus* value,
bool allowDuplicateTags);
bool AppendVertexCommandBlock(UInt16 enumID, DVertexCommandBlock* value,
bool allowDuplicateTags);
/* This returns an iterator which can be used to access all the
tags with ID enumID (if any) within self. *pEndIter is
filled in with an iterator beyond the last tag with ID
enumID. No reference counts are modified by this call. The
order of tags returned by this iterator is undefined. */
DryadMetaData::TagMapIter
LookUpMulti(UInt16 enumID,
DryadMetaData::TagMapIter* pEndIter);
/* This returns an iterator which can be used to access all the
tags within self in sequence starting from startTag. *pEndIter
is filled in with an iterator beyond the last tag in self. If
startTag is NULL the iterator begins at the first tag (if any)
in self. No reference counts are modified by this call. */
DryadMetaData::TagListIter
LookUpInSequence(DryadMTag* startTag,
DryadMetaData::TagListIter* pEndIter);
/* this returns a recursive clone of self. Leaf tags acquire a new
reference within the cloned object, rather than being copied. The
returned metadata has a single reference owned by the
caller. */
void Clone(DryadMetaDataRef* dstMetaData);
void Serialize(DrMemoryWriter* writer);
void CacheSerialization();
DrMemoryBuffer* SerializeToBuffer();
/* call 'delete []' on the buffer returned by GetText() */
char* GetText();
DrError WriteAsProperty(DrMemoryWriter* writer,
UInt16 propertyTag,
bool writeIfEmpty);
DrError WriteAsAggregate(DrMemoryWriter* writer,
UInt16 propertyTag,
bool writeIfEmpty);
/* these are convenience methods to add error codes. They each add
a DrError tag with ID Prop_Dryad_ErrorCode, value errorCode if
it doesn't already exist. The second also adds a
Prop_Dryad_ErrorString containing errorDescription. */
void AddError(DrError errorCode);
void AddErrorWithDescription(DrError errorCode,
const char* errorDescription);
/* this is a convenience method. If the metadata contains a
DrError tag with ID Prop_Dryad_ErrorCode then the call returns
true and the error in that property is filled in to *pError,
otherwise it returns false and *pError is not modified. */
bool GetErrorCode(DrError* pError /* out */);
/* returns NULL if no error string exists. The returned value is
valid only as long as this instance is not changed */
const char* GetErrorString();
private:
DryadMetaData();
~DryadMetaData();
TagList m_elementList;
TagMap m_elementMap;
DrRef<DrMemoryBuffer> m_cachedSerialization;
CRITSEC m_baseCS;
};
class DryadMetaDataParser : public DrPropertyParser
{
public:
typedef DrError (TagFactory)(DrMemoryReader* reader,
UInt16 enumId, UInt32 dataLen,
DryadMetaDataParser* parent);
typedef DrError (AggregateFactory)(DrMemoryReader* reader,
DryadMTagRef* pTag);
DryadMetaDataParser();
~DryadMetaDataParser();
DryadMetaData* GetMetaData();
void AddTag(DryadMTag* tag);
DrError ParseBuffer(const void* data, UInt32 dataLength);
DrError DryadMetaDataParser::OnParseProperty(DrMemoryReader* reader,
UInt16 enumId,
UInt32 dataLen,
void* cookie);
private:
DryadMetaDataRef m_set;
};
extern void DryadInitMetaDataTable();
extern DrError
DryadAddFactoryToTypeTable(UInt16 typeCode,
DryadMetaDataParser::TagFactory* factory);
extern DrError
DryadAddFactoryToAggregateTable(UInt16 typeCode,
DryadMetaDataParser::AggregateFactory*
factory);
extern DrError DryadAddPropertyToMetaData(UInt16 prop, UInt16 typeCode);