bool TRI_RegisterFunctionAql (TRI_associative_pointer_t* functions,
                              const char* const externalName,
                              const char* const internalName,
                              const bool isDeterministic,
                              const bool isGroup,
                              const char* const argPattern,
                              void (*optimise)(const TRI_aql_node_t* const, TRI_aql_context_t* const, TRI_aql_field_access_t*)) {
  TRI_aql_function_t* function;

  function = (TRI_aql_function_t*) TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_aql_function_t), false);

  if (function == NULL) {
    return false;
  }

  function->_externalName = TRI_UpperAsciiStringZ(TRI_UNKNOWN_MEM_ZONE, externalName);

  if (function->_externalName == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function);
    return false;
  }

  // normalize name by upper-casing it
  function->_internalName = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, internalName);

  if (function->_internalName == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function);
    return false;
  }
  
  function->_argPattern = TRI_DuplicateStringZ(TRI_UNKNOWN_MEM_ZONE, argPattern);

  if (function->_argPattern == NULL) {
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_internalName);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function);
    return false;
  }
  

  if (TRI_InsertKeyAssociativePointer(functions, function->_externalName, function, false)) {
    // function already registered
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_externalName);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function->_internalName);
    TRI_Free(TRI_UNKNOWN_MEM_ZONE, function);
    return false;
  }

  function->_isDeterministic = isDeterministic;
  function->_isGroup = isGroup;
  function->optimise = optimise;

  // set minArgs and maxArgs
  SetArgumentCount(function);

  return true;
}
示例#2
0
HRESULT DrVertexCommandBlock::ParseProperty(DrPropertyReaderPtr reader, UINT16 enumID,
                                            UINT32 /* unused dataLen */)
{
    HRESULT err;

    switch (enumID)
    {
    default:
        DrLogW("Unknown property in vertex command message enumID %u", (UINT32) enumID);
        err = reader->SkipNextPropertyOrAggregate();
        break;

    case DrProp_VertexCommand:
        UINT32 marshaledCommand;
        err = reader->ReadNextProperty(enumID, marshaledCommand);
        if (err == S_OK)
        {
            if (marshaledCommand < DrVC_Max)
            {
                m_command = (DrVertexCommand) marshaledCommand;
            }
            else
            {
                DrLogW("Unknown vertex command %u", marshaledCommand);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
        }
        break;

    case DrProp_VertexArgumentCount:
        UINT32 nArguments;
        err = reader->ReadNextProperty(enumID, nArguments);
        if (err == S_OK)
        {
            if (nArguments < 0x80000000)
            {
                SetArgumentCount((int) nArguments);
            }
            else
            {
                DrLogW("Too large argument count %u", nArguments);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
        }
        break;

    case DrProp_VertexArgument:
        if (m_nextArgumentToRead >= m_argument->Allocated())
        {
            DrLogW("Too many arguments nextArgumentToRead=%d, nArguments=%d",
                   m_nextArgumentToRead, m_argument->Allocated());
            err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
        }
        else
        {
            DrString arg;
            err = reader->ReadNextProperty(enumID, arg);
            if (err == S_OK)
            {
                m_argument[m_nextArgumentToRead] = arg;
                ++m_nextArgumentToRead;
            }
        }
        break;

    case DrProp_VertexSerializedBlock:
        UINT32 blockLength;
        err = reader->PeekNextPropertyTag(&enumID, &blockLength);
        if (err == S_OK)
        {
            if (blockLength < 0x80000000)
            {
                DrByteArrayRef block = DrNew DrByteArray((int) blockLength);
                {
                    DRPIN(BYTE) data = &(block[0]);
                    err = reader->ReadNextProperty(enumID, (UINT32) blockLength, data);
                }
                if (err == S_OK)
                {
                    m_serializedBlock = block;
                }
            }
            else
            {
                DrLogW("Block too large %u", blockLength);
                err = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
            }
        }
        break;

    case DrProp_DebugBreak:
        err = reader->ReadNextProperty(enumID, m_setBreakpointOnCommandArrival);
        break;

    case DrProp_BeginTag:
        UINT16 tagValue;
        err = reader->PeekNextAggregateTag(&tagValue);
        if (err != S_OK)
        {
            DrLogW("Error reading DrProp_BeginTag %d", err);
        }
        else
        {
            switch (tagValue)
            {
            case DrTag_VertexProcessStatus:
                err = reader->ReadAggregate(tagValue, m_processStatus);
                break;

            default:
                DrLogW("Unexpected tag %d", tagValue);
                err = reader->SkipNextPropertyOrAggregate();
            }
        }
        break;
    }

    return err;
}