////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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 V5.5.1 (2411131018)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  parameterfilesymboltableentry.cpp
/// @brief Auto-generated Chromatix parameter file
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "parametersetmanager.h"
#include "parameterfilesymboltableentry.h"
#include "parameterfilesymboltable.h"

ParameterFileSymbolTableEntry::ParameterFileSymbolTableEntry()
{
    Table       = nullptr;
    ID          = 0;
    DuplicateID = 0;
    Module      = nullptr;
    Position    = 0;
    Data        = nullptr;
    DataSize    = 0;
    File        = nullptr;
    Offset      = 0;
    SetManager  = nullptr;
}

ParameterFileSymbolTableEntry::~ParameterFileSymbolTableEntry()
{
    PARAMETER_DELETE Module;
    Module = nullptr;

    if (File != nullptr)
    {
        PARAMETER_DELETE[] Data;
    }

    Data = nullptr;
}

void ParameterFileSymbolTableEntry::Init(
    ParameterFileSymbolTable* const table)
{
    Table      = table;
    SetManager = table->SetManager;
    Position   = 0;
    Data       = nullptr;
}

bool ParameterFileSymbolTableEntry::Load(
    BYTE* const                buffer,
    const CHAR* const          fileName,
    ParameterBinaryFile* const file,
    UINT32 const               length,
    UINT32* const              pos,
    UINT32 const               dataOffset,
    IModeTable*                modeTable,
    bool const                 isModule,
    BYTE const                 alignment)
{
    UINT32 offset = 0;
    CHAR   type[TYPE_LEN + 1];
    UINT32 readSize   = length;
    UINT32 readPos    = *pos;
    UINT8* readBuffer = buffer;

    if (file != nullptr)
    {
        const UINT32 tableOffset = isModule || Table->DataTableOffset == 0 ? Table->SymbolTableOffset : Table->DataTableOffset;
        readSize   = Table->GetSymbolEntrySize(alignment);
        readBuffer = file->Read(tableOffset + readPos, readSize);
        readPos    = 0;
    }

    bool result = readBuffer != nullptr;
    if (result)
    {
        UINT64 versionValue = 0;
        UINT32 modeId       = 0;
        result = ParameterUtils::Read(&ID, readBuffer, readSize, &readPos, alignment, SetManager);

        if (result && isModule)
        {
            UINT64 modeValue = 0;

            result = ParameterUtils::ReadString(type, readBuffer, readSize, &readPos, TYPE_LEN + 1, TYPE_LEN, alignment, SetManager);
            if (result)
            {
                result = ParameterUtils::Read(&versionValue, readBuffer, readSize, &readPos, alignment, SetManager);
            }

            if (alignment == 1 && Table->Version < Table->AlignedEndVersion)
            {
                // Alignment 1 is legacy (V 1.0.x) binary format, read mode, submode, and group
                if (result)
                {
                    result = ParameterUtils::Read(&modeValue, readBuffer, readSize, &readPos, alignment, SetManager);
                }
            }

            if (result)
            {
                result = ParameterUtils::Read(&modeId, readBuffer, readSize, &readPos, alignment, SetManager);
            }
        }

        if (result)
        {
            result = ParameterUtils::Read(&offset,   readBuffer, readSize, &readPos, alignment, SetManager);
        }
        if (result)
        {
            result = ParameterUtils::Read(&DataSize, readBuffer, readSize, &readPos, alignment, SetManager);
        }

        if (Table->Version > Table->AlignedEndVersion)
        {
            // Versions after 3.0.1 (aligned end version) have an duplicate ID entry.
            // If DuplicateID != ID, then this entry's data is a duplicate of DuplicateID's
            if (result)
            {
                result = ParameterUtils::Read(&DuplicateID, readBuffer, readSize, &readPos, alignment, SetManager);
                if (isModule && DuplicateID > Table->Count())
                {
                    PARAMETER_LOG_ERROR(SetManager, "Invalid DuplicateID value %u, should be less than module table count: %u\n",
                        DuplicateID, Table->Count());
                }
                else if (!isModule && DuplicateID > Table->DTCount())
                {
                    PARAMETER_LOG_ERROR(SetManager, "Invalid DuplicateID value %u, should be less than data table count: %u\n",
                        DuplicateID, Table->DTCount());
                }
            }
        }
        else
        {
            DuplicateID = ID;
        }

        if (isModule && ParameterFileSymbolTableEntry::CheckIsModule(modeId))
        {
            Module = PARAMETER_NEW ModuleData(ID, DuplicateID, modeTable, type, versionValue, modeId, SetManager);
        }

        if (fileName == nullptr)
        {
            Data   = buffer + dataOffset + offset;
            File   = nullptr;
            Offset = 0;
            *pos   = readPos;
        }
        else
        {
            PARAMETER_DELETE[] readBuffer;
            Data   = DataSize > 0 ? file->Read(dataOffset + offset, DataSize) : 0;
            File   = fileName;
            Offset = 0;
            *pos   = *pos + readPos;
        }
    }

    return result;
}

bool ParameterFileSymbolTableEntry::ReadString(
    CHAR** const value,
    UINT32 const maxChars,
    BYTE   const alignment)
{
     constexpr const CHAR* const file {__FILE__};
     constexpr INT32 line {LINE_CONST};
     DupObjInfo* const dupInfo = GetDupObject(1U, file, line);

    *value = nullptr;
    if (dupInfo != nullptr)
    {
        *value = (CHAR*)dupInfo->Object;
    }

    if (*value == nullptr)
    {
        if (Data != nullptr)
        {
            *value = ParameterUtils::ReadString(Data, DataSize, &Position, maxChars, alignment);

            if (*value != nullptr)
            {
                SetDupObject(*value, 1U, file, line);
            }
        }
    }
    else
    {
        Position += maxChars;
    }
    return *value != nullptr;
}

UINT32 ParameterFileSymbolTableEntry::ReadEnum(
    bool* const result,
    BYTE const  alignment)
{
    UINT32 value = 0;
    if (Data != nullptr)
    {
        *result = ParameterUtils::Read(&value, Data, DataSize, &Position, alignment, SetManager);
    }
    return value;
}

DupObjInfo* ParameterFileSymbolTableEntry::GetDupObject(
    UINT32 const      count,
    const CHAR* const file,
    UINT32 const      line)
{
    return Table->GetDupObject(IsModule(), DuplicateID, count, file, line);
}

DupObjInfo* ParameterFileSymbolTableEntry::SetDupObject(
    void* const       obj,
    UINT32 const      count,
    const CHAR* const file,
    UINT32 const      line)
{
    return Table->SetDupObject(IsModule(), DuplicateID, obj, count, file, line);
}
