Beispiel #1
0
bool SstGlobalTypes::LoadTypes( Retriever& retriever, const module mod )
/**********************************************************************/
{
    char*       buffer;
    unsigned_32 length;
    if ( ! retriever.ReadSubsection(buffer,length,sstTypes,mod) ) {
        return FALSE;
    }
    char*       end = &buffer[length];
    if ( * (unsigned_32 *) buffer != CV4_HEADER ) {
        ::Warning("invalid header dectected in types.");
    }
    // skip the header.
    buffer += LONG_WORD;
    // if it is the first module, just load the types into the global
    // table without packing.
    if ( mod == 1 ) {
        while ( buffer < end ) {
            _globalTypingInfo.Insert( new LFGlobalTypeRecord(ToTypeIndex(_globalTypingInfo.Entries()),buffer));
            buffer += WORD + * (unsigned_16 *) buffer;
        }
        TypeMap.Set( CV_FIRST_NONPRIM + _globalTypingInfo.Entries() );
        return TRUE;
    } else {
        while ( buffer < end ) {
            _localTypingInfo.Insert( new LFLocalTypeRecord(ToTypeIndex(_localTypingInfo.Entries()),buffer));
            buffer += WORD + * (unsigned_16 *) buffer;
        }
        TypeMap.Reset(_localTypingInfo.Entries());
    }
    uint oldCount = _globalTypingInfo.Entries();

    // Full type packing is not implemented due to its long running time
    // when input is relatively big.  Here only packs records that can be
    // hashed, these records are structs, unions, enums, class.  And they
    // will likely reference a lot of other records, so partial packing
    // is not that bad after all.

    WCPtrSListIter<LFTypeRecord> iter(_localTypingInfo._hashRecords);
    while ( ++iter ) {
        if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
            ProcessTypes( iter.current() );
        }
    }
    // Anything that is left will be inserted as a new type into the global
    // table.
    iter.reset(_localTypingInfo._otherRecords);
    while ( ++iter ) {
        if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
            InsertNewType( iter.current() );
        }
    }
    FixUpTypes(ToTypeIndex(oldCount));

    // Selectively destruct the types in the local table.  If the type is
    // a new type, then only release the memory of a bare LFLocalTypeRecord.
    // Otherwise, release the memory of a bare record plus the pointer to
    // LFLeafStruct.  This is bad style, but can boost performance by not
    // having to create a constructor and do a pointer copy only when
    // transfer types from the local table to the global table.  See the
    // LFGlobalTypeRecord declaration for more details.

    for ( uint i = CV_FIRST_NONPRIM;
          i < ToTypeIndex(_localTypingInfo.Entries()); i++ ) {
        if ( ! TypeMap.IsNewType(i) ) {
        // If not a new type, release pointer memory as well.
            _localTypingInfo[i]->ManualDestruct();
        }
        // release bare LFLocalTypeRecord memory.
        /*
        if (_localTypingInfo[i]) {
        delete _localTypingInfo[i];
            _localTypingInfo[i]=NULL;
        }
        */
    }
    _localTypingInfo.Clear();
    return TRUE;
}
Beispiel #2
0
/*
 * Routine: ProcessSet
 * Purpose: Read distribution settings
 * Algorithm:
 * Data Structures:
 *
 * Params:
 * Returns:
 * Called By:
 * Calls:
 * Assumptions:
 * Side Effects:
 * TODO: None
 *
 * NOTE: if QERR_SYNTAX can be a valid return value, we have a problem.
 */
int
ProcessSet (char *stmt, token_t * tokens)
{
    int nRetCode = 0,
        i;
    char *cp = NULL;

    cp = SafeStrtok (NULL, " \t=");
    switch (i = FindToken (cp))
    {
    case TKN_WEIGHTS:
        cp = SafeStrtok (NULL, " \t");	/* discard = */
        pCurrentIndexEntry->w_width = ProcessInt (stmt, tokens);
        if (pCurrentIndexEntry->w_width == QERR_SYNTAX)
            nRetCode = QERR_RANGE_ERROR;
        else
        {
            if (pCurrentIndexEntry->w_width > nMaxWeightWidth)
            {
                arWeights = (int *) REALLOC (arWeights,
                                             pCurrentIndexEntry->w_width *
                                             sizeof (int));
                if (arWeights == NULL)
                    nRetCode = QERR_NO_MEMORY;
            }
            else
                nMaxWeightWidth = pCurrentIndexEntry->w_width;
        }
        pCurrentIndexEntry->dist->weight_sets =
            (int **) MALLOC (pCurrentIndexEntry->w_width * sizeof (int *));
        if (pCurrentIndexEntry->dist->weight_sets == NULL)
            nRetCode = QERR_NO_MEMORY;
        memset(pCurrentIndexEntry->dist->weight_sets, 0, pCurrentIndexEntry->w_width * sizeof(int *));
        break;
    case TKN_TYPES:
        pCurrentIndexEntry->v_width = ProcessTypes (stmt, tokens);
        if (pCurrentIndexEntry->v_width == QERR_SYNTAX)
            nRetCode = QERR_RANGE_ERROR;
        else
        {
            if (pCurrentIndexEntry->v_width > nMaxValueWidth)
            {
                arValues =
                    (char **) REALLOC (arValues,
                                       pCurrentIndexEntry->v_width *
                                       sizeof (char *));
                arValueLengths =
                    (int *) REALLOC (arValueLengths,
                                     pCurrentIndexEntry->v_width *
                                     sizeof (int));
            }
            if (arValues == NULL || arValueLengths == NULL)
                nRetCode = QERR_NO_MEMORY;
            else
            {
                for (i=nMaxValueWidth; i < pCurrentIndexEntry->v_width; i++)
                {
                    arValueLengths[i] = 0;
                    arValues[i] = NULL;
                }
                nMaxValueWidth = pCurrentIndexEntry->v_width;
            }
        }
        pCurrentIndexEntry->dist->value_sets =
            (int **) MALLOC (pCurrentIndexEntry->v_width * sizeof (int *));
        if (pCurrentIndexEntry->dist->value_sets == NULL)
            nRetCode = QERR_NO_MEMORY;
        memset(pCurrentIndexEntry->dist->value_sets, 0, pCurrentIndexEntry->v_width * sizeof(int *));
        break;
    case TKN_NAMES:
        if ((pCurrentIndexEntry->v_width <= 0) || (pCurrentIndexEntry->w_width <= 0))
            return(QERR_NAMES_EARLY);
        pCurrentIndexEntry->name_space = ProcessNames(stmt, tokens);
        break;
    default:
        nRetCode = QERR_SYNTAX;
    }

    return (nRetCode);
}