////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
// All rights reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// THIS IS AUTO-GENERATED CODE.  PLEASE DO NOT EDIT (File bug reports against tools).
///
/// Auto-generated by: Parameter Parser V7.4.1 (8cca6579792b9fcef3bc725ff070c5ec453c7c85)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  parameterfilesymboltable.h
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PARAMETERSYMBOLTABLE_H
#define PARAMETERSYMBOLTABLE_H

#include "parametertypes.h"
#include "parameterfilesymboltableentry.h"
#include "parametermodule.h"
#include <unordered_map>

class ParameterFileSymbolTable
{
public:
    struct SectionInfo
    {
        SectionInfo()
        {
            Offset = 0;
            Size   = 0;
        }
        SectionInfo(UINT32 offset, UINT32 size)
        {
            Offset = offset;
            Size   = size;
        }
        UINT32 Offset;
        UINT32 Size;
    };

    ParameterFileSymbolTable(
        ParameterSetManager* const setManager,
        BYTE                       alignment,
        const VersionUnion&        version);

    ~ParameterFileSymbolTable();

    void ClearDefinitions(
        bool all);

    bool Load(
        BYTE* const                buffer,
        UINT32 const               bufLength,
        const CHAR* const          fileName,
        ParameterBinaryFile* const file,
        UINT32 const               fileLength,
        const SectionInfo&         symbolTable,
        const SectionInfo&         dataTable,
        const SectionInfo&         data,
        const SectionInfo&         definitions,
        IModeTable* const          modeTable,
        bool const                 fbcEnabled);

    PARAMETER_INLINE ModuleData* GetModule(
        UINT32 const index)
    {
        if (index < m_modules.Count())
        {
            return m_modules[index];
        }
        else
        {
            return nullptr;
        }
    }

    PARAMETER_INLINE UINT32 Count()
    {
        return m_count;
    }

    PARAMETER_INLINE UINT32 DTCount()
    {
        return m_dtCount;
    }

    PARAMETER_INLINE UINT32 ModuleCount()
    {
        return m_modules.Count();
    }

    bool Find(
        ParameterFileSymbolTableEntry& entry,
        UINT32 id,
        bool const isModule = true);

    bool ReadPointerEntry(
        ParameterFileSymbolTableEntry&       pointerEntry,
        ParameterFileSymbolTableEntry* const entry);

    PARAMETER_INLINE DupObjInfo* GetDupObject(
        bool const   isModule,
        UINT32 const id,
        INT32 const  location)
    {
        return GetDupObjectInternal(isModule, id, location, true);
    }

    DupObjInfo* SetDupObject(
        bool const   isModule,
        UINT32 const id,
        void* const  obj,
        INT32        location);

    bool ReleaseDupObject(
        void* const obj);

    template<typename T> static void ReleaseObjectArray(
        ParameterFileSymbolTable* table,
        T*&                       array,
        UINT32 const              count)
    {
        if (array != nullptr)
        {
            if (table == nullptr || table-> ReleaseDupObject(array))
            {
                for (UINT32 i = 0; array != nullptr && i < count; i++)
                {
                    ReleaseObject(table, array[i]);
                }
                PARAMETER_DELETE[] array;
            }
            array = nullptr;
        }
    }

    static void ReleaseStringFixedArray(
        ParameterFileSymbolTable* table,
        CHAR**                    array,
        UINT32 const              count)
    {
        if (array != nullptr)
        {
            if (table == nullptr || table-> ReleaseDupObject(array))
            {
                for (UINT32 i = 0; array != nullptr && i < count; i++)
                {
                    ReleaseObject(table, array[i]);
                }
            }
        }
    }

    template<typename T> static void ReleaseObject(
        ParameterFileSymbolTable* table,
        T&                        obj)
    {
        if (obj != nullptr)
        {
            if (table == nullptr || table->ReleaseDupObject(obj))
            {
                PARAMETER_DELETE[] obj;
            }
            obj = nullptr;
        }
    }

    UINT32 GetSymbolEntrySize();

    UINT32 GetDataTableEntrySize();

    UINT32 GetModeEntrySize();

    ParameterDefinitionElement* BuildModuleElement(
        UINT64      nameHash);
    ParameterDefinitionStructure* FindModuleStructure(
        UINT64 nameHash);
    ParameterDefinitionStructure* FindStructure(
        UINT32 structID);

    void FreeEntryData();
    void FreeLookupData();

    void FileReference(
        INT32 adjust);

    ParameterSetManager*  SetManager;
    VersionUnion          Version;
    VersionUnion          MultiModeTableVersion;
    VersionUnion          StructSymbolsVersion;
    VersionUnion          AlignedEndVersion;
    VersionUnion          ModeFlagsVersion;
    VersionUnion          LinkVersion;
    VersionUnion          DataTableVersion;  // Mode Table Name and Data Table version
    const CHAR*           FileName;
    ParameterBinaryFile*  File;
    UINT32                FileLength;
    UINT32                SymbolTableSize;
    UINT32                SymbolTableOffset;
    UINT32                DataTableSize;
    UINT32                DataTableOffset;
    UINT32                DataOffset;
    UINT32                DataSize;
    UINT8*                Data;
    IModeTable*           ModeTable;
    BYTE                  Alignment;

    std::unordered_map<UINT64, ParameterDefinitionModule*>*    ModuleDefinitions;
    std::unordered_map<UINT32, ParameterDefinitionStructure*>* StructureDefinitions;

private:
    class EntryData
    {
    public:
        EntryData()
        {
            Dup      = 0;
            Position = 0;
        }
        UINT32 Dup;
        UINT32 Position;
    };

    bool ReadTable(
        BYTE* const                    buffer,
        UINT32 const                   length,
        UINT32&                        pos,
        UINT32                         count,
        ParameterFileSymbolTableEntry* entries,
        EntryData* const               entryLookup,
        UINT32&                        dupCount,
        PList<DupObjInfo*>*&           dupEntries,
        UINT32 const                   dataOffset,
        IModeTable* const              modeTable,
        const bool                     isModule);

    bool ReadDefinitions(
        BYTE* const  buffer,
        UINT32 const length,
        UINT32&      pos,
        UINT32       size,
        bool const   fbcEnabled);

    DupObjInfo* FindDupObject(
        void* const obj);

    DupObjInfo* GetDupObjectInternal(
        bool const   isModule,
        UINT32 const id,
        INT32 const  location,
        bool         lock);

    UINT32                         m_count;
    UINT32                         m_dtCount;
    PList<ModuleData*>             m_modules;
    EntryData*                     m_entryLookup;
    EntryData*                     m_dtEntryLookup;
    PList<DupObjInfo*>*            m_dupEntries;
    PList<DupObjInfo*>*            m_dtDupEntries;
    UINT32                         m_dupCount;
    UINT32                         m_dtDupCount;
    INT32                          m_fileRef;     // Reference count file access
    ParameterFileSymbolTableEntry* m_entries;
    ParameterFileSymbolTableEntry* m_dtEntries;
#ifdef PARAMETER_USE_MUTEX
    // Protect changes to m_dupInfoMap and DubObjInfo objects
#ifdef PARAMETER_USE_UNIQUE
    ParameterMutex    m_dupInfoMutex;
#else
    std::shared_mutex m_dupInfoMutex;
#endif
#endif
    std::unordered_map<void*, DupObjInfo*> m_dupInfoMap;
};

#endif
