//*****************************************************************************
// Given an StgIO, opens compressed streams and do proper initialization.
// This is a helper for other Init functions.
//*****************************************************************************
__checkReturn 
HRESULT 
CLiteWeightStgdbRW::InitFileForRead(
    StgIO * pStgIO,     // For file i/o.
    int     bReadOnly)  // If read-only open.
{
    TiggerStorage * pStorage = NULL;
    void          * pvData;
    ULONG           cbData;
    HRESULT         hr = NOERROR;
    
    // Allocate a new storage object which has IStorage on it.
    pStorage = new (nothrow) TiggerStorage();
    IfNullGo(pStorage);
    
    // Init the storage object on the backing storage.
    OptionValue ov;
    IfFailGo(m_MiniMd.GetOption(&ov));
    IfFailGo(pStorage->Init(pStgIO, ov.m_RuntimeVersion));
    
    // Save pointers to header structure for version string.
    _ASSERTE((m_pvMd == NULL) && (m_cbMd == 0));
    IfFailGo(pStorage->GetHeaderPointer(&m_pvMd, &m_cbMd));
    
    // Check to see if this is a minimal metadata
    if (SUCCEEDED(pStorage->OpenStream(MINIMAL_MD_STREAM, &cbData, &pvData)))
    {
        m_MiniMd.m_fMinimalDelta = TRUE;
    }
    
    // Load the string pool.
    if (SUCCEEDED(hr = pStorage->OpenStream(STRING_POOL_STREAM, &cbData, &pvData)))
    {
        // String pool has to end with a null-terminator, therefore we don't have to check string pool 
        // content on access.
        // Shrink size of the pool to the last null-terminator found.
        while (cbData != 0)
        {
            if (((LPBYTE)pvData)[cbData - 1] == 0)
            {   // We have found last null terminator
                break;
            }
            // Shrink size of the pool
            cbData--;
            Debug_ReportError("String heap/pool does not end with null-terminator ... shrinking the heap.");
        }
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolStrings, pvData, cbData, bReadOnly));
    }
    else
    {
        if (hr != STG_E_FILENOTFOUND)
        {
            IfFailGo(hr);
        }
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolStrings, NULL, 0, bReadOnly));
    }
    
    // Load the user string blob pool.
    if (SUCCEEDED(hr = pStorage->OpenStream(US_BLOB_POOL_STREAM, &cbData, &pvData)))
    {
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, pvData, cbData, bReadOnly));
    }
    else
    {
        if (hr != STG_E_FILENOTFOUND)
        {
            IfFailGo(hr);
        }
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, NULL, 0, bReadOnly));
    }
    
    // Load the guid pool.
    if (SUCCEEDED(hr = pStorage->OpenStream(GUID_POOL_STREAM, &cbData, &pvData)))
    {
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolGuids, pvData, cbData, bReadOnly));
    }
    else
    {
        if (hr != STG_E_FILENOTFOUND)
        {
            IfFailGo(hr);
        }
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolGuids, NULL, 0, bReadOnly));
    }
    
    // Load the blob pool.
    if (SUCCEEDED(hr = pStorage->OpenStream(BLOB_POOL_STREAM, &cbData, &pvData)))
    {
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolBlobs, pvData, cbData, bReadOnly));
    }
    else
    {
        if (hr != STG_E_FILENOTFOUND)
        {
            IfFailGo(hr);
        }
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolBlobs, NULL, 0, bReadOnly));
    }
    
    // Open the metadata.
    hr = pStorage->OpenStream(COMPRESSED_MODEL_STREAM, &cbData, &pvData);
    if (hr == STG_E_FILENOTFOUND)
    {
        IfFailGo(pStorage->OpenStream(ENC_MODEL_STREAM, &cbData, &pvData));
    }
    IfFailGo(m_MiniMd.InitOnMem(pvData, cbData, bReadOnly));
    IfFailGo(m_MiniMd.PostInit(0));
    
ErrExit:
    if (pStorage != NULL)
    {
        delete pStorage;
    }
    return hr;
} // CLiteWeightStgdbRW::InitFileForRead
//*****************************************************************************
// Given an StgIO, opens compressed streams and do proper initialization.
// This is a helper for other Init functions.
//*****************************************************************************
HRESULT CLiteWeightStgdbRW::InitFileForRead(
    StgIO       *pStgIO,                // For file i/o.
    int         bReadOnly)              // If read-only open.
{

    TiggerStorage *pStorage = 0;        // Storage object.
    void        *pvData;
    ULONG       cbData;
    HRESULT     hr = NOERROR;

    // Allocate a new storage object which has IStorage on it.
    if ((pStorage = new (nothrow) TiggerStorage) == 0)
        IfFailGo( E_OUTOFMEMORY);

    // Init the storage object on the backing storage.
    OptionValue ov;
    m_MiniMd.GetOption(&ov);
    IfFailGo( hr = pStorage->Init(pStgIO, ov.m_RuntimeVersion) );

    // Save pointers to header structure for version string.
    _ASSERTE(m_pvMd == NULL && m_cbMd == 0);
    IfFailGo(pStorage->GetHeaderPointer(&m_pvMd, &m_cbMd));

    // Check to see if this is a minimal metadata
    if (SUCCEEDED(pStorage->OpenStream(MINIMAL_MD_STREAM, &cbData, &pvData)))
        m_MiniMd.m_fMinimalDelta = TRUE;

    // Load the string pool.
    if (SUCCEEDED(hr=pStorage->OpenStream(STRING_POOL_STREAM, &cbData, &pvData)))
        IfFailGo( m_MiniMd.InitPoolOnMem(MDPoolStrings, pvData, cbData, bReadOnly) );
    else 
    {
        if (hr != STG_E_FILENOTFOUND)
            IfFailGo(hr);
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolStrings, 0, 0, 0));
    }

    // Load the user string blob pool.
    if (SUCCEEDED(hr=pStorage->OpenStream(US_BLOB_POOL_STREAM, &cbData, &pvData)))
        IfFailGo( m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, pvData, cbData, bReadOnly) );
    else 
    {
        if (hr != STG_E_FILENOTFOUND)
            IfFailGo(hr);
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolUSBlobs, 0, 0, 0));
    }

    // Load the guid pool.
    if (SUCCEEDED(hr=pStorage->OpenStream(GUID_POOL_STREAM,  &cbData, &pvData)))
        IfFailGo( m_MiniMd.InitPoolOnMem(MDPoolGuids, pvData, cbData, bReadOnly) );
    else 
    {
        if (hr != STG_E_FILENOTFOUND)
            IfFailGo(hr);
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolGuids, 0, 0, 0));
    }

    // Load the blob pool.
    if (SUCCEEDED(hr=pStorage->OpenStream(BLOB_POOL_STREAM, &cbData, &pvData)))
        IfFailGo( m_MiniMd.InitPoolOnMem(MDPoolBlobs, pvData, cbData, bReadOnly) );
    else 
    {
        if (hr != STG_E_FILENOTFOUND)
            IfFailGo(hr);
        IfFailGo(m_MiniMd.InitPoolOnMem(MDPoolBlobs, 0, 0, 0));
    }

    // Open the metadata.
    hr = pStorage->OpenStream(COMPRESSED_MODEL_STREAM, &cbData, &pvData);
    if (hr == STG_E_FILENOTFOUND)
    {
        IfFailGo(pStorage->OpenStream(ENC_MODEL_STREAM, &cbData, &pvData) );
    }
    IfFailGo( m_MiniMd.InitOnMem(pvData, cbData, bReadOnly) ); 
    IfFailGo( m_MiniMd.PostInit(0) );
    
ErrExit:
    if (pStorage)
        delete pStorage;
    return hr;
} // HRESULT CLiteWeightStgdbRW::InitFileForRead()