summaryrefslogtreecommitdiffstats
path: root/src/usr/errl/errlsctn.C
blob: 707bbf14b180193c0d72a5ede6661317781d4f8f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
 *  @file errlsctn.C
 *
 *  @brief Implementation of ErrlSctn class
 */

/*****************************************************************************/
// I n c l u d e s
/*****************************************************************************/
#include <trace/interface.H>
#include "errlsctn.H"
#include <assert.h>

namespace ERRORLOG
{

extern trace_desc_t* g_trac_errl;


///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ErrlSctn::ErrlSctn(const compId_t i_compId,
                   const uint8_t i_sctnVer,
                   const uint8_t i_subSect)
:iv_ErrlSctnHdr(i_compId, i_sctnVer, i_subSect),iv_pData(NULL),iv_cbData(0)
{
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
ErrlSctn::~ErrlSctn()
{
    delete iv_pData;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
uint64_t ErrlSctn::addData(const void *i_data, const uint64_t i_size)
{
    uint64_t l_rc = 0;

    // Expected new size of user data.
    uint64_t l_newsize = iv_cbData + i_size;

    // Resize memory block
    iv_pData = static_cast<uint8_t*>(realloc(iv_pData, l_newsize));

    // Make sure reallocate call succeeds
    if (iv_pData != NULL)
    {
        // Copy new data to new area, past existing data (if any)
        memcpy( iv_pData+iv_cbData, i_data, i_size );

        // Save new size of the user-provided data.
        l_rc = iv_cbData = l_newsize;
    }
    else
    {
        TRACFCOMP( g_trac_errl,
                   "ErrlFFDC::addData() - Reallocate memory failed!");
    }
    return l_rc;
}


////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
uint64_t ErrlSctn::flattenedSize()
{
    return sizeof(section_header_t) + iv_cbData;
}

////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
uint64_t ErrlSctn::flatten( void* io_pBuffer, uint64_t i_bufsize )
{
    uint64_t l_flatCount = 0;

    do
    {
        l_flatCount = flattenedSize();
        if( i_bufsize < l_flatCount )
        {
            // error path, return 0
            TRACFCOMP( g_trac_errl, "Invalid buffer size" );
            l_flatCount = 0;
            break;
        }

        // CPPASSERT() makes an assertion to the compiler, and if the
        // expression is false, the compile will end in error.  If these
        // compiler asserts should fail, then the packed structures
        // defined in errl/errltypes.H will need to be adjusted.
        CPPASSERT( 2 == sizeof(iv_ErrlSctnHdr.iv_compId));
        CPPASSERT( 1 == sizeof(iv_ErrlSctnHdr.iv_sctnVer));
        CPPASSERT( 1 == sizeof(iv_ErrlSctnHdr.iv_subSect));
        CPPASSERT( 0 == sizeof( section_header_t ) %  sizeof( uint32_t ));


        // Marshall the data into a section_header_t
        section_header_t l_Header;
        memset( &l_Header, 0, sizeof( l_Header ));
        l_Header.cbHeader   = sizeof( l_Header );
        l_Header.cbSection  = iv_cbData;
        l_Header.compId     = iv_ErrlSctnHdr.iv_compId;
        l_Header.sctnVer    = iv_ErrlSctnHdr.iv_sctnVer;
        l_Header.subSect    = iv_ErrlSctnHdr.iv_subSect;


        // Write data to caller's memory.
        char * l_pchar = static_cast<char *>(io_pBuffer);
        memcpy( l_pchar, &l_Header, sizeof( l_Header ));
        l_pchar += sizeof( l_Header );

        // Write any user-defined data.
        if( iv_cbData )
        {
            memcpy( l_pchar, iv_pData, iv_cbData );
        }
    }
    while( 0 );

    return l_flatCount;
}



} // end namespace
OpenPOWER on IntegriCloud