// This code is a part of the Telephony Framework C++ Library.
// Copyright (C) 1997 Chris Sells. All rights reserved.
// tVarData.cpp: CtVariableData class implementation

#include "stdafx.h"
#include "tVarData.h"

TRESULT CtVariableData::UpdateData()
{
    // Empirically, this often works the first time...
    // Note: This number must be at least as big as the
    // largest variably-sized structure in TAPI or some
    // TSPs will complain about being too small and not
    // fill in m_pd->dwNeededSize.
    DWORD   dwNeededSize = 512;
    TRESULT tr = 0;

    do
    {
        // Get some more memory if we don't have enough
        if( !m_pd || m_pd->dwTotalSize < dwNeededSize )
        {
            if( m_pd = (VARDATA*)::realloc(m_pd, dwNeededSize) )
            {
                m_pd->dwTotalSize = dwNeededSize;
            }
            else
            {
                return LINEERR_NOMEM;
            }
        }

        // Call the derived call to fill in the buffer
        tr = FillBuffer();

        // Check how much memory we need
        if( tr == LINEERR_STRUCTURETOOSMALL ||
            // Some TSPs succeed even if the data size is too small
            (TSUCCEEDED(tr) && m_pd->dwTotalSize < m_pd->dwNeededSize) )
        {
            dwNeededSize = m_pd->dwNeededSize;
            tr = LINEERR_STRUCTURETOOSMALL;
        }
    }
    while( tr == LINEERR_STRUCTURETOOSMALL );

    // Trim excess memory use
    if( TSUCCEEDED(tr) &&
        m_pd->dwUsedSize < m_pd->dwTotalSize )
    {
        m_pd = (VARDATA*)::realloc(m_pd, m_pd->dwUsedSize);
        assert(m_pd);
        m_pd->dwTotalSize = m_pd->dwUsedSize;
    }
    // Release unset memory
    else if( TFAILED(tr) && m_pd )
    {
        ::free(m_pd);
        m_pd = 0;
    }

    return tr;
}
