xmlconfig.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,482 行 · 第 1/4 页

CPP
2,482
字号
			{
			    const char* name = tag->get_attribute("name");
			    if(!name)
			    {
				ERRMSG(m_pMessages,
				       "%s: List tag requires a name attribute",
				       m_filename);
				// Process anyway, give it a dummy name
				name = "XXXBADLIST";
			    }
			    /*
			     * Remove current tag from list, push current list,
			     * create new list, add next level's props.
			     */
			    _RemovePropFromList(pNewList, name);
			    curr_level.AddLevel(name);
			    if (!_PropExists(&curr_level, m_pRegistry))
			    {
				curr_level.RemoveLevel();
				ulListsToIgnore++;
			    }
			    else
			    {
				levlist.AddHead((void*)pNewList);
				if (wspacetag)
				{
				    fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
					strlen(wspacetag->m_cur_attribute->value), fpNew);
				    delete wspacetag;
				    wspacetag = 0;
				}

				fprintf(fpNew, "<List Name=\"%s\">", name);
				pNewList = new CHXSimpleList;
				_AddPropsToList(pNewList, curr_level.CharStar(), m_pRegistry);
			    }
			}
			
		    }
		}
		else if(tag->m_type != XMLEndTag)
		{
		    if (!ulListsToIgnore)
		    {
			const char* name = tag->get_attribute("name");
			const char* value = tag->get_attribute("value");
			if (name)
			{
			    curr_level.AddLevel(name);
			    _RemovePropFromList(pNewList, name);
			    /*
			     * Make sure this prop is still set.
			     */
			    if (_PropExists(&curr_level, m_pRegistry))
			    {
				if (wspacetag)
				{
				    fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
					strlen(wspacetag->m_cur_attribute->value), fpNew);
				    delete wspacetag;
				    wspacetag = 0;
				}

				char* p = _GetPropValueString(curr_level.CharStar(), m_pRegistry);

				if (p)
				{
				    fprintf(fpNew, "<Var %s=\"%s\"/>",
					name,
					p);
				    delete[] p;
				}
			    }
			    curr_level.RemoveLevel();
			}
		    }
		}
		else
		{
		    // An End Tag
		    if(strcasecmp(tag->m_name, "list") == 0)
		    {
			if (ulListsToIgnore)
			{
			    ulListsToIgnore --;
			}
			else
			{
			    /*
			     * Need to add the stuff at this level that was
			     * was not in the config file.
			     */
			    if (pNewList->GetCount() == 0)
			    {
				if (wspacetag)
				{
				    fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
					strlen(wspacetag->m_cur_attribute->value), fpNew);
				}
			    }
			    else
			    {
				fprintf(fpNew, "\n");
				AppendPropsToFile(fpNew, curr_level, pNewList,
				    4, m_pRegistry, pKeyName);
				_IndentFile(fpNew, 4, curr_level, pKeyName);
			    }
			    delete wspacetag;
			    wspacetag = 0;

			    fprintf(fpNew, "</List>");
			    curr_level.RemoveLevel();
			    delete pNewList;
			    pNewList = (CHXSimpleList*)levlist.RemoveHead();
			}
		    }
		}
		break;
	    }
	}

	// Give up if we've lost all hope
	if (HXR_OK != hResult)
	{
	    break;
	}
    }
    if (hResult == HXR_OK && wspacetag)
    {
	fwrite(wspacetag->m_cur_attribute->value, sizeof(char),
	    strlen(wspacetag->m_cur_attribute->value), fpNew);
	delete wspacetag;
	wspacetag = 0;
    }

    /*
     * Ok, done with the whole file. Make sure that all of the base level stuff
     * gets added.
     */
     //XXXPM Calculate this later.
    if (hResult == HXR_OK)
    {
        int indent = 4;
        AppendPropsToFile(fpNew, curr_level, pNewList, indent, m_pRegistry, pKeyName);
    }

    // cleanup
    if (fpNew) fclose(fpNew);
    if (fpOld) fclose(fpOld);
    HX_DELETE(pNewList);
    HX_VECTOR_DELETE(pBuf);
    HX_DELETE(tag);

    return hResult;
}


void
XMLConfig::_AddPropsToList(CHXSimpleList* pList, const char* pName,
			  IHXRegistry2* preg)
{
    IHXValues* pValues = 0;
    UINT32 ul;
    const char* pPropName;
    preg->GetPropListByName(pName, pValues);

    if (pValues)
    {
	if (HXR_OK == pValues->GetFirstPropertyULONG32(pPropName, ul))
	{
	    XMLPropInfo* pInfo = new XMLPropInfo;
	    pInfo->m_pName = new char[strlen(pPropName) + 1 - strlen(pName)];
	    strcpy(pInfo->m_pName, &(pPropName[strlen(pName) + 1])); /* Flawfinder: ignore */
	    pInfo->m_Type = preg->GetTypeByName(pPropName);
	    pList->AddHead((void*)pInfo);

	    while (HXR_OK == pValues->GetNextPropertyULONG32(pPropName, ul))
	    {
		XMLPropInfo* pInfo = new XMLPropInfo;
		pInfo->m_pName = new char[strlen(pPropName) + 1 - strlen(pName)];
		strcpy(pInfo->m_pName, &(pPropName[strlen(pName) + 1]));
		pInfo->m_Type = preg->GetTypeByName(pPropName);
		pList->AddHead((void*)pInfo);
	    }
	}
	pValues->Release();
    }
}

void
XMLConfig::_RemovePropFromList(CHXSimpleList* pList, const char* pName)
{
    LISTPOSITION pos;
    pos = pList->GetHeadPosition();

    XMLPropInfo* pProp;

    
    while (pos)
    {
	pProp = (XMLPropInfo*)pList->GetAt(pos);
	if (!pProp)
	{
	    return;
	}
	if (!strcasecmp(pProp->m_pName, pName))
	{
	    pList->RemoveAt(pos);
	    delete pProp;
	    return;
	}
	pList->GetNext(pos);

    }
}

char*
XMLConfig::_GetPropValueString(const char* pName, IHXRegistry2* pReg)
{
    int vartype;
    IHXBuffer* pBuffer;
    INT32 l;
    char* ret;

    vartype = pReg->GetTypeByName(pName);
    if(vartype == PT_INTEGER)
    {
	if(HXR_OK == pReg->GetIntByName(pName, l))
	{
	    char num[32]; /* Flawfinder: ignore */
	    sprintf(num, "%d", l); /* Flawfinder: ignore */
	    ret = new char[strlen(num) + 1];
	    strcpy(ret, num); /* Flawfinder: ignore */
	    return ret;
	}
	else
	{
	    return 0;
	}
    }
    else if(vartype == PT_STRING)
    {
	if(HXR_OK == pReg->GetStrByName(pName,
	    pBuffer) && pBuffer)
	{
	    ret = new char[pBuffer->GetSize()+1];
	    strcpy(ret, (const char*)pBuffer->GetBuffer()); /* Flawfinder: ignore */
	    pBuffer->Release();
	    return ret;
	}
	else
	{
	    return 0;
	}
    }
    return 0;
}

void
XMLConfig::_CleanList(CHXSimpleList* pList)
{
    XMLPropInfo* pInfo;
    while (!pList->IsEmpty())
    {
	pInfo = (XMLPropInfo*)pList->RemoveHead();
	delete pInfo;
    }
}

void
XMLConfig::AppendPropsToFile(FILE* fp, XMLConfigString level,
    CHXSimpleList* pList, int indent_per_level,
    IHXRegistry2* hxreg, const char* pBase)
{
    XMLPropInfo* pInfo = 0;
    while (!pList->IsEmpty())
    {
	pInfo = (XMLPropInfo*)pList->RemoveHead();
	level.AddLevel(pInfo->m_pName);
	_AppendPropToFile(fp, level, indent_per_level, hxreg, pBase);
	level.RemoveLevel();
	delete pInfo;
    }
}

void
XMLConfig::_IndentFile(FILE* fp, int indent_per_level,
			 XMLConfigString level,
			 const char* pBase)
{
    int dots_to_ignore = 1;
    INT32 i;
    const char* pc;
    pc = pBase;
    while (*pc)
    {
	if (*pc == '.')
	{
	    dots_to_ignore ++;
	}
	pc++;
    }
    pc = level.CharStar();
    while (*pc)
    {
	if (*pc == '.')
	{
	    if (dots_to_ignore)
	    {
		dots_to_ignore--;
	    }
	    else
	    {
		for (i = 0; i < indent_per_level; i++)
		{
		    fprintf(fp, " ");
		}
	    }
	}
	pc ++;
    }
}

void
XMLConfig::_AppendPropToFile(FILE* fp, XMLConfigString level,
			     int indent_per_level,
			     IHXRegistry2* hxreg,
			     const char* pBase)
{
    /*
     * Indent a proper amount.
     */
    INT32 i;
    IHXBuffer* pBuf = 0;

    _IndentFile(fp, indent_per_level, level, pBase);

    HXPropType type = hxreg->GetTypeByName(level.CharStar());
    switch (type)
    {
    case PT_COMPOSITE:
	fprintf(fp, "<List Name=\"%s\">\n", level.Top());
	IHXValues* pValues;
	if (HXR_OK == hxreg->GetPropListByName(level.CharStar(),
	    pValues) && pValues)
	{
	    HX_RESULT res;
	    UINT32 ul;
	    const char* pName;
	    res = pValues->GetFirstPropertyULONG32(pName, ul);
	    while (res == HXR_OK)
	    {
		const char* pc = pName + strlen(pName);
		while (pc > pName)
		{
		    pc--;
		    if (*pc == '.')
		    {
			pc++;
			level.AddLevel(pc);
			_AppendPropToFile(fp, level, indent_per_level, hxreg, pBase);
			level.RemoveLevel();
			res = pValues->GetNextPropertyULONG32(pName, ul);
			break;
		    }
		}
	    }
	    pValues->Release();
	}
	_IndentFile(fp, indent_per_level, level, pBase);
	fprintf(fp, "</List>\n");
	break;

    case PT_INTEGER:
	if (HXR_OK == hxreg->GetIntByName(level.CharStar(), i))
	{
	    fprintf(fp, "<Var %s=\"%ld\"/>\n", level.Top(),
		i);
	}
	break;

    case PT_STRING:
	if (HXR_OK == hxreg->GetStrByName(level.CharStar(), pBuf)
	    && pBuf)
	{
	    fprintf(fp, "<Var %s=\"%s\"/>\n", level.Top(),
		(const char*)pBuf->GetBuffer());
	    pBuf->Release();
	    pBuf = 0;
	}
	break;
    }
}

int
XMLConfig::_PropExists(XMLConfigString* p, IHXRegistry2* preg)
{
    return (preg->GetPropStatusByName(p->CharStar()) == HXR_OK) ? TRUE : FALSE;
}

/*
 * IHXRegConfig::WriteKey
 */
STDMETHODIMP
XMLConfig::WriteKey(const char* pKeyName)
{
    /*
     * If there is a filename then we got it from a file.
     */
    if (m_filename)
    {
	WriteToFile(pKeyName, m_filename);
	return HXR_OK;
    }

    HX_ASSERT(0);
    return HXR_FAIL;
}

HX_RESULT
XMLConfig::Reconfigure(IHXReconfigServerResponse* pResp)
{
    if (m_pReconfigureResponse)
    {
	return HXR_UNEXPECTED;
    }
    m_pReconfigureResponse = pResp;
    m_pReconfigureResponse->AddRef();

    /*
     * If they started from a config file, then reload
     * from the config file.
     */
    if (m_filename)
    {
	return Reconfigure(m_filename);
    }

    /*
     * If we got here there was a booboo
     */
    m_pReconfigureResponse->ReconfigServerDone(HXR_OK, 0, 0);
    m_pReconfigureResponse->Release();
    m_pReconfigureResponse = 0;

    return HXR_OK;
}

HX_RESULT
XMLConfig::Reconfigure(const char* pFileName)
{
    if (!pFileName)
    {
	return HXR_FAIL;
    }

    FILE* fp = fopen(pFileName, "r");
    if (!fp)
    {
	return HXR_FAIL;
    }

    /*
     * Pretend that there is one outstanding just to keep
     * the done methods from getting called, seeing a 0,
     * and sending the response until the end of this 
     * func.
     */
    m_ActiveSetsOutstanding++;

    const char* pKeyName = "config";
    int l = 0;
    BOOL filedone = 0;
    XMLTag*   tag = 0;
    CBigByteQueue queue(MAX_TAG_SIZE);
    XMLParser parser;
    HX_RESULT hResult = HXR_OK;

    /*
     * Files are all aready.  Now we need to build our config levels list.
     */
    CHXSimpleList levlist;
    /*
     *  Add for level 0.
     */
    CHXSimpleList* pNewList = new CHXSimpleList;
    IHXValues* pValues = 0;

    _AddPropsToList(pNewList, pKeyName, m_pRegistry);
    XMLConfigString curr_level;
    curr_level.AddLevel(pKeyName);

    // read the config file into the byte queue
    INT32 nBufSize = 16384;
    BYTE* pBuf = new BYTE[nBufSize];
    while (!filedone && hResult == HXR_OK)
    {
        l = fread(pBuf, 1, nBufSize, fp);
        if (l > 0)
        {
            if (!queue.EnQueue(pBuf, l))
            {
                if (!queue.Grow(l))
                {
                    ERRMSG(m_pMessages,
                           "error expanding data structure while parsing %s",
                           pFileName);
                    hResult = HXR_FAIL;
                }
                if (!queue.EnQueue(pBuf, l))
                {
                    ERRMSG(m_pMessages,
                           "unknown error while parsing %s",
                           pFileName);
                    hResult = HXR_FAIL;
                }
            }
	}
	else
	{
            filedone = TRUE;
	}
    }

    UINT32 bytesUsed=0;
    UINT32 bytesAvail=0;
    BYTE* p=0;
    while (hResult == HXR_OK && (bytesAvail = queue.GetQueuedItemCount()) > 0)
    {
	if (bytesAvail > nBufSize)
        {
            HX_VECTOR_DELETE(pBuf);
            pBuf = new BYTE[bytesAvail];
            nBufSize = bytesAvail;
        }
	p = pBuf;

	queue.DeQueue(pBuf, bytesAvail);
	bytesUsed = bytesAvail;

        HX_DELETE(tag);
	XMLParseResult res = parser.Parse((const char*&)p, bytesAvail, tag);
	queue.EnQueue(p, bytesAvail - (p - pBuf));

	switch(res)
	{
	    case XMLPNoClose:
		// A tag opener was found, but no closer yet.
		if (filedone)
		{
		    pBuf[bytesAvail - 1] = '\0';
		    if (bytesAvail > MAX_ERROR_CHARS)
		    {
			pBuf[MAX_ERROR_CHARS - 1] = '\0';
		    }
		    ERRMSG(m_pMessages,
		    "%s: Missing close for tag %s...", m_filename, pBuf);
		    hResult = HXR_FAIL;
		}
		break;
	    case XMLPNoTagType:
		*p = 0;
		ERRMSG(m_pMessages,
		       "%s: Badly formed tag %s", m_filename, pBuf);
		break;
	    case XMLPBadAttribute:
		*p = 0;
		ERRMSG(m_pMessages,
		       "%s: Badly formed attribute in %s", m_filename,
		       pBuf);
		break;
	    case XMLPPlainText:
		break;
	    case XMLPBadEndTag:
		*p = 0;
		ERRMSG(m_pMessages,
		       "%s: Unexpected tag %s", m_filename, pBuf);
		break;
	    case XMLPComment:
		break;
	    case XMLPDirective:
		// A directive.  We don't handle any yet.
		break;
	    case XMLPProcInst:
		// A processing Instruction, whee!
		break;
	    case XMLPTag:
	    {
		if(Expand(tag, &queue))
		    break;

		if(tag->m_need_close)
		{
		    if(strcasecmp(tag->m_name, "list") == 0)
		    {
			const char* name = tag->get_attribute("name");
			if(!name)
			{
			    ERRMSG(m_pMessages,
				   "%s: List tag requires a name attribute",
				   m_filename);
			    // Process anyway, give it a dummy name
			    name = "XXXBADLIST";
			}
			/*
			 * Remove current tag from list, push current list,
			 * create new list, add next level's props.
			 */
			_RemovePropFromList(pNewList, name);
			curr_level.AddLevel(name);
			levlist.AddHead((void*)pNewList);
			pNewList = new CHXSimpleList;
			_AddPropsToList(pNewList, curr_level.CharStar(), m_pRegistry);
			
		    }
		}
		else if(tag->m_type != XMLEndTag)
		{
		    const char* name = tag->get_attribute("name");
		    const char* value = tag->get_attribute("value");
		    if (name)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?