// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of NVIDIA CORPORATION nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Copyright (c) 2008-2025 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #include "OmniPvdDefinesInternal.h" #include "OmniPvdReaderImpl.h" #include OmniPvdReaderImpl::OmniPvdReaderImpl() { mMajorVersion = OMNI_PVD_VERSION_MAJOR; mMinorVersion = OMNI_PVD_VERSION_MINOR; mPatch = OMNI_PVD_VERSION_PATCH; mDataBuffer = 0; mDataBuffAllocatedLen = 0; mCmdAttributeDataPtr = 0; mIsReadingStarted = false; mReadBaseClassHandle = 1; } OmniPvdReaderImpl::~OmniPvdReaderImpl() { mCmdAttributeDataPtr = 0; delete[] mDataBuffer; mDataBuffer = 0; mDataBuffAllocatedLen = 0; } void OMNI_PVD_CALL OmniPvdReaderImpl::setLogFunction(OmniPvdLogFunction logFunction) { mLog.setLogFunction(logFunction); } void OMNI_PVD_CALL OmniPvdReaderImpl::setReadStream(OmniPvdReadStream& stream) { mStream = &stream; mStream->openStream(); } bool OMNI_PVD_CALL OmniPvdReaderImpl::startReading(OmniPvdVersionType& majorVersion, OmniPvdVersionType& minorVersion, OmniPvdVersionType& patch) { if (mIsReadingStarted) { return true; } if (mStream) { mStream->readBytes((uint8_t*)&majorVersion, sizeof(OmniPvdVersionType)); mStream->readBytes((uint8_t*)&minorVersion, sizeof(OmniPvdVersionType)); mStream->readBytes((uint8_t*)&patch, sizeof(OmniPvdVersionType)); mCmdMajorVersion = majorVersion; mCmdMinorVersion = minorVersion; mCmdPatch = patch; if ((mCmdMajorVersion == 0) && (mCmdMinorVersion < 3)) { mCmdBaseClassHandle = 0; mReadBaseClassHandle = 0; } else { mCmdBaseClassHandle = 0; mReadBaseClassHandle = 1; } mLog.outputLine("OmniPvdRuntimeReaderImpl::startReading majorVersion(%lu), minorVersion(%lu), patch(%lu)", static_cast(majorVersion), static_cast(minorVersion), static_cast(patch)); if (majorVersion > mMajorVersion) { mLog.outputLine("[parser] major version too new\n"); return false; } else if (majorVersion == mMajorVersion) { if (minorVersion > mMinorVersion) { mLog.outputLine("[parser] minor version too new\n"); return false; } else if (minorVersion == mMinorVersion) { if (patch > mPatch) { mLog.outputLine("[parser] patch too new\n"); return false; } } } mIsReadingStarted = true; return true; } else { return false; } } static OmniPvdDataType::Enum readDataType(OmniPvdReadStream& stream) { OmniPvdDataTypeStorageType dataType; stream.readBytes((uint8_t*)&dataType, sizeof(OmniPvdDataTypeStorageType)); return static_cast(dataType); } bool OmniPvdReaderImpl::readStringFromStream(char* string, uint16_t& stringLength) { mStream->readBytes((uint8_t*)&stringLength, sizeof(uint16_t)); if (stringLength < OMNI_PVD_MAX_STRING_LENGTH) { mStream->readBytes((uint8_t*)string, stringLength); string[stringLength] = 0; // trailing zero return true; } else { uint16_t readBytes = OMNI_PVD_MAX_STRING_LENGTH - 1; mStream->readBytes((uint8_t*)string, readBytes); string[readBytes] = 0; // trailing zero mStream->skipBytes(stringLength - readBytes); mLog.outputLine("[parser] ERROR: string name %s... exceeds max length of %d\n", string, OMNI_PVD_MAX_STRING_LENGTH); return false; } } OmniPvdCommand::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getNextCommand() { OmniPvdCommand::Enum cmdType = OmniPvdCommand::eINVALID; resetCommandParams(); if (!mIsReadingStarted) { if (!startReading(mCmdMajorVersion, mCmdMinorVersion, mCmdPatch)) { return cmdType; } } if (mStream) { OmniPvdCommandStorageType command; if (mStream->readBytes(&command, sizeof(OmniPvdCommandStorageType))) { mCmdMessageParsed = false; switch (command) { case OmniPvdCommand::eREGISTER_CLASS: { cmdType = OmniPvdCommand::eREGISTER_CLASS; mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); //////////////////////////////////////////////////////////////////////////////// // Skip reading the base class if the stream is older or equal to (0,2,x) //////////////////////////////////////////////////////////////////////////////// if (mReadBaseClassHandle) { mStream->readBytes((uint8_t*)&mCmdBaseClassHandle, sizeof(OmniPvdClassHandle)); } readStringFromStream(mCmdClassName, mCmdClassNameLen); mLog.outputLine("[parser] register class (handle: %d, name: %s)\n", mCmdClassHandle, mCmdClassName); } break; case OmniPvdCommand::eREGISTER_ATTRIBUTE: { cmdType = OmniPvdCommand::eREGISTER_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); mCmdAttributeDataType = readDataType(*mStream); if (mCmdAttributeDataType == OmniPvdDataType::eENUM_VALUE) { mStream->readBytes((uint8_t*)&mCmdEnumValue, sizeof(OmniPvdEnumValueType)); } else if (mCmdAttributeDataType == OmniPvdDataType::eFLAGS_WORD) { mStream->readBytes((uint8_t*)&mCmdEnumClassHandle, sizeof(OmniPvdClassHandle)); } else { mCmdEnumValue = 0; mStream->readBytes((uint8_t*)&mCmdAttributeNbElements, sizeof(uint32_t)); } readStringFromStream(mCmdAttributeName, mCmdAttributeNameLen); mLog.outputLine("[parser] register attribute (classHandle: %d, attributeHandle: %d, attributeDataType: %d, nrFields: %d, name: %s)\n", mCmdClassHandle, mCmdAttributeHandle, mCmdAttributeDataType, mCmdAttributeNbElements, mCmdAttributeName); } break; case OmniPvdCommand::eREGISTER_CLASS_ATTRIBUTE: { cmdType = OmniPvdCommand::eREGISTER_CLASS_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeClassHandle, sizeof(OmniPvdClassHandle)); readStringFromStream(mCmdAttributeName, mCmdAttributeNameLen); mLog.outputLine("[parser] register class attribute (classHandle: %d, attributeHandle: %d, attribute classAttributeHandle: %d, name: %s)\n", mCmdClassHandle, mCmdAttributeHandle, mCmdAttributeClassHandle, mCmdAttributeName); } break; case OmniPvdCommand::eREGISTER_UNIQUE_LIST_ATTRIBUTE: { cmdType = OmniPvdCommand::eREGISTER_UNIQUE_LIST_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); mCmdAttributeDataType = readDataType(*mStream); readStringFromStream(mCmdAttributeName, mCmdAttributeNameLen); mLog.outputLine("[parser] register attributeSet (classHandle: %d, attributeHandle: %d, attributeDataType: %d, name: %s)\n", mCmdClassHandle, mCmdAttributeHandle, mCmdAttributeDataType, mCmdAttributeName); } break; case OmniPvdCommand::eSET_ATTRIBUTE: { cmdType = OmniPvdCommand::eSET_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] set attribute (contextHandle:%d, objectHandle: %d, attributeHandle: %d, dataLen: %d)\n", mCmdContextHandle, mCmdObjectHandle, mCmdAttributeHandle, mCmdAttributeDataLen); } break; case OmniPvdCommand::eADD_TO_UNIQUE_LIST_ATTRIBUTE: { cmdType = OmniPvdCommand::eADD_TO_UNIQUE_LIST_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] add to attributeSet (contextHandle:%d, objectHandle: %d, attributeHandle: %d, dataLen: %d)\n", mCmdContextHandle, mCmdObjectHandle, mCmdAttributeHandle, mCmdAttributeDataLen); } break; case OmniPvdCommand::eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE: { cmdType = OmniPvdCommand::eREMOVE_FROM_UNIQUE_LIST_ATTRIBUTE; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); mStream->readBytes((uint8_t*)&mCmdAttributeHandleDepth, sizeof(uint8_t)); uint32_t* attributeHandleStack = mCmdAttributeHandleStack; for (int i = 0; i < mCmdAttributeHandleDepth; i++) { mStream->readBytes((uint8_t*)&mCmdAttributeHandle, sizeof(OmniPvdAttributeHandle)); attributeHandleStack++; } mStream->readBytes((uint8_t*)&mCmdAttributeDataLen, sizeof(uint32_t)); readLongDataFromStream(mCmdAttributeDataLen); mLog.outputLine("[parser] remove from attributeSet (contextHandle:%d, objectHandle: %d, attributeHandle: %d, dataLen: %d)\n", mCmdContextHandle, mCmdObjectHandle, mCmdAttributeHandle, mCmdAttributeDataLen); } break; case OmniPvdCommand::eCREATE_OBJECT: { cmdType = OmniPvdCommand::eCREATE_OBJECT; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdClassHandle, sizeof(OmniPvdClassHandle)); mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); readStringFromStream(mCmdObjectName, mCmdObjectNameLen); mLog.outputLine("[parser] create object (contextHandle: %d, classHandle: %d, objectHandle: %d, name: %s)\n", mCmdContextHandle, mCmdClassHandle, mCmdObjectHandle, mCmdObjectName); } break; case OmniPvdCommand::eDESTROY_OBJECT: { cmdType = OmniPvdCommand::eDESTROY_OBJECT; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdObjectHandle, sizeof(OmniPvdObjectHandle)); mLog.outputLine("[parser] destroy object (contextHandle: %d, objectHandle: %d)\n", mCmdContextHandle, mCmdObjectHandle); } break; case OmniPvdCommand::eSTART_FRAME: { cmdType = OmniPvdCommand::eSTART_FRAME; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdFrameTimeStart, sizeof(uint64_t)); mLog.outputLine("[parser] start frame (contextHandle: %d, timeStamp: %d)\n", mCmdContextHandle, mCmdFrameTimeStart); } break; case OmniPvdCommand::eSTOP_FRAME: { cmdType = OmniPvdCommand::eSTOP_FRAME; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); mStream->readBytes((uint8_t*)&mCmdFrameTimeStop, sizeof(uint64_t)); mLog.outputLine("[parser] stop frame (contextHandle: %d, timeStamp: %d)\n", mCmdContextHandle, mCmdFrameTimeStop); } break; case OmniPvdCommand::eRECORD_MESSAGE: { cmdType = OmniPvdCommand::eRECORD_MESSAGE; mStream->readBytes((uint8_t*)&mCmdContextHandle, sizeof(OmniPvdContextHandle)); // Message. readStringFromStream(mCmdMessage, mCmdMessageLength); // File name. readStringFromStream(mCmdMessageFile, mCmdMessageFileLength); mStream->readBytes((uint8_t*)&mCmdMessageLine, sizeof(uint32_t)); mStream->readBytes((uint8_t*)&mCmdMessageType, sizeof(uint32_t)); mStream->readBytes((uint8_t*)&mCmdMessageClassHandle, sizeof(OmniPvdClassHandle)); mCmdMessageParsed = true; mLog.outputLine("[parser] message (contextHandle: %d, message: %s, file: %s, line: %d, type: %d)\n", mCmdContextHandle, mCmdMessage, mCmdMessageFile, mCmdMessageLine, mCmdMessageType ); } break; default: { } break; } return cmdType; } else { return cmdType; } } else { return cmdType; } } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getMajorVersion() { return mCmdMajorVersion; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getMinorVersion() { return mCmdMinorVersion; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getPatch() { return mCmdPatch; } uint64_t OMNI_PVD_CALL OmniPvdReaderImpl::getContextHandle() { return mCmdContextHandle; } OmniPvdClassHandle OMNI_PVD_CALL OmniPvdReaderImpl::getClassHandle() { return mCmdClassHandle; } OmniPvdClassHandle OMNI_PVD_CALL OmniPvdReaderImpl::getBaseClassHandle() { return mCmdBaseClassHandle; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeHandle() { return mCmdAttributeHandle; } uint64_t OMNI_PVD_CALL OmniPvdReaderImpl::getObjectHandle() { return mCmdObjectHandle; } const char* OMNI_PVD_CALL OmniPvdReaderImpl::getClassName() { return mCmdClassName; } const char* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeName() { return mCmdAttributeName; } const char* OMNI_PVD_CALL OmniPvdReaderImpl::getObjectName() { return mCmdObjectName; } const uint8_t* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataPointer() { return mCmdAttributeDataPtr; } OmniPvdDataType::Enum OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataType() { return mCmdAttributeDataType; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeDataLength() { return mCmdAttributeDataLen; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeNumberElements() { return mCmdAttributeNbElements; } OmniPvdClassHandle OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeClassHandle() { return mCmdAttributeClassHandle; } uint8_t OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeNumberHandles() { return mCmdAttributeHandleDepth; } uint32_t* OMNI_PVD_CALL OmniPvdReaderImpl::getAttributeHandles() { return mCmdAttributeHandleStack; } uint64_t OMNI_PVD_CALL OmniPvdReaderImpl::getFrameTimeStart() { return mCmdFrameTimeStart; } uint64_t OMNI_PVD_CALL OmniPvdReaderImpl::getFrameTimeStop() { return mCmdFrameTimeStop; } bool OMNI_PVD_CALL OmniPvdReaderImpl::getMessageData(const char*& message, const char*& file, uint32_t& line, uint32_t& type, OmniPvdClassHandle& handle) { message = mCmdMessage; file = mCmdMessageFile; line = mCmdMessageLine; type = mCmdMessageType; handle = mCmdMessageClassHandle; return mCmdMessageParsed; } OmniPvdClassHandle OMNI_PVD_CALL OmniPvdReaderImpl::getEnumClassHandle() { return mCmdEnumClassHandle; } uint32_t OMNI_PVD_CALL OmniPvdReaderImpl::getEnumValue() { return mCmdEnumValue; } void OmniPvdReaderImpl::readLongDataFromStream(uint32_t streamByteLen) { if (streamByteLen < 1) return; if (streamByteLen > mDataBuffAllocatedLen) { delete[] mDataBuffer; mDataBuffAllocatedLen = (uint32_t)(streamByteLen * 1.3f); mDataBuffer = new uint8_t[mDataBuffAllocatedLen]; } mCmdAttributeDataPtr = mDataBuffer; mStream->readBytes(mCmdAttributeDataPtr, streamByteLen); } //////////////////////////////////////////////////////////////////////////////// // Resets all command parameters before a new read command is executed, // except for those parameters that are "stateful" which are left commented out. //////////////////////////////////////////////////////////////////////////////// void OmniPvdReaderImpl::resetCommandParams() { //////////////////////////////////////////////////////////////////////////////// // Stateful: Depends on the version of the stream reader //////////////////////////////////////////////////////////////////////////////// // OmniPvdVersionType mMajorVersion; // OmniPvdVersionType mMinorVersion; // OmniPvdVersionType mPatch; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Stateful: Depends on the stream being read and stay the same //////////////////////////////////////////////////////////////////////////////// // OmniPvdVersionType mCmdMajorVersion; // OmniPvdVersionType mCmdMinorVersion; // OmniPvdVersionType mCmdPatch; //////////////////////////////////////////////////////////////////////////////// mCmdContextHandle = OMNI_PVD_INVALID_HANDLE; mCmdObjectHandle = OMNI_PVD_INVALID_HANDLE; mCmdClassHandle = OMNI_PVD_INVALID_HANDLE; mCmdBaseClassHandle = OMNI_PVD_INVALID_HANDLE; mCmdAttributeHandle = OMNI_PVD_INVALID_HANDLE; mCmdClassName[0] = 0; mCmdAttributeName[0] = 0; mCmdObjectName[0] = 0; mCmdClassNameLen = 0; mCmdAttributeNameLen = 0; mCmdObjectNameLen = 0; mCmdAttributeDataPtr = 0; //////////////////////////////////////////////////////////////////////////////// // Unsure how to handle this, a zero value could still be valid //////////////////////////////////////////////////////////////////////////////// //mCmdAttributeDataType = OmniPvdDataType::eINT8; // int 8 is 0 //////////////////////////////////////////////////////////////////////////////// mCmdAttributeDataLen = 0; mCmdAttributeNbElements = 0; mCmdEnumValue = 0; mCmdEnumClassHandle = OMNI_PVD_INVALID_HANDLE; mCmdAttributeClassHandle = OMNI_PVD_INVALID_HANDLE; //////////////////////////////////////////////////////////////////////////////// // Left untouched/dirty : instead depends on the depth parameter below //////////////////////////////////////////////////////////////////////////////// // OmniPvdAttributeHandle mCmdAttributeHandleStack[32]; //////////////////////////////////////////////////////////////////////////////// mCmdAttributeHandleDepth = 0; //////////////////////////////////////////////////////////////////////////////// // Stateful for the duration of a frame //////////////////////////////////////////////////////////////////////////////// // uint64_t mCmdFrameTimeStart; // uint64_t mCmdFrameTimeStop; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Internal scratch buffer, instead the mCmdAttributeDataPtr is set to 0 //////////////////////////////////////////////////////////////////////////////// // uint8_t *mDataBuffer; // uint32_t mDataBuffAllocatedLen; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // Internal message buffer //////////////////////////////////////////////////////////////////////////////// mCmdMessageParsed = false; mCmdMessageLength = 0; mCmdMessage[0] = 0; mCmdMessageFileLength = 0; mCmdMessageFile[0] = 0; mCmdMessageLine = 0; mCmdMessageType = 0; mCmdMessageClassHandle = 0; }