树节点逻辑关系记录及节点查找功能(二)

对前面的文章:数据结构树节点深度和广度关系递归记录进行了延伸,下面给出演示代码:

      
    typedef struct NODEINFO {
        NODEINFO() {
            pParent = nullptr;
            pBefore = nullptr;
            pAfter = nullptr;
            pChild = nullptr;
        }
        NODEINFO(FPD_Object Parent, FPD_Object Before, FPD_Object After,
            FPD_Object Child)
        {
            pParent = Parent;
            pBefore = Before;
            pAfter = After;
            pChild = Child;
        }
        FPD_Object pParent;
        FPD_Object pBefore;
        FPD_Object pAfter;
        FPD_Object pChild;
    }*LPNODEINFO;


   	    void       GetTreeTopologyInfo(FPD_Bookmark pCurrentBM);
        void       InsertNode(FPD_Bookmark pCurrentBM);
        void       SetParent(FPD_Bookmark pCurrentBM, FPD_Bookmark pParent);
        FPD_Object       GetParent(FPD_Object fpdObject);
        void       SetPrevSibling(FPD_Bookmark pCurrentBM, FPD_Bookmark pBefore);
        FPD_Object       GetPrevSibling(FPD_Object fpdObject);
        FPD_Object       GetNextSibling(FPD_Object fpdObject);
		
		.......
		std::map<FPD_Object, NODEINFO>m_mapTreeData;
		
		//获得上层的父节点,父节点可能没有直接指向子节点
    //是为了UI的便捷性
    void CPDF_Bookmark::InsertNode(FPD_Bookmark pCurrentBM)
    {
        FPD_Object fpdCurrentBM = FPDBookmarkGetDictionary(pCurrentBM);
        if (!fpdCurrentBM)return;
        NODEINFO  nodeInfo;
        m_mapTreeData.insert(std::pair<FPD_Object, NODEINFO>(fpdCurrentBM, nodeInfo));
    }

    void CPDF_Bookmark::SetParent(FPD_Bookmark pCurrentBM, FPD_Bookmark pParent)
    {
        FPD_Object fpdCurrentBM = FPDBookmarkGetDictionary(pCurrentBM);
        if (!fpdCurrentBM)return;
        FPD_Object fpdParentBM = nullptr;
        if (pParent)
            fpdParentBM = FPDBookmarkGetDictionary(pParent);
        m_mapTreeData[fpdCurrentBM].pParent = fpdParentBM;
    }

    FPD_Object CPDF_Bookmark::GetParent(FPD_Object fpdObject)
    {
        if (!fpdObject)
            return nullptr;
        return m_mapTreeData[fpdObject].pParent;
    }

    void CPDF_Bookmark::SetPrevSibling(FPD_Bookmark pCurrentBM, FPD_Bookmark pBefore)
    {
        FPD_Object fpdCurrentBM = FPDBookmarkGetDictionary(pCurrentBM);
        if (!fpdCurrentBM)return;
        FPD_Object fpdBeforeBM = nullptr;
        if (pBefore)
            fpdBeforeBM = FPDBookmarkGetDictionary(pBefore);
        m_mapTreeData[fpdCurrentBM].pBefore = fpdBeforeBM;
    }

    FPD_Object CPDF_Bookmark::GetPrevSibling(FPD_Object fpdObject)
    {
        if (!fpdObject)
            return nullptr;
        return m_mapTreeData[fpdObject].pBefore;
    }

    FPD_Object CPDF_Bookmark::GetNextSibling(FPD_Object fpdObject)
    {
        FPD_Bookmark bmPrev = FPDBookmarkNew(fpdObject);
        FPD_Bookmark bmNext = FPDBookmarkNew(nullptr);
        FPDBookmarkGetNextSibling(m_fpdDoc, bmPrev, &bmNext);
        FPD_Object pNext = FPDBookmarkGetDictionary(bmNext);

        FPDBookmarkDestroy(bmNext);
        FPDBookmarkDestroy(bmPrev);
        return pNext;
    }
	
	void CPDF_Bookmark::GetTreeTopologyInfo(FPD_Bookmark pCurrentBM)
    {
        if (pCurrentBM)
        {
            InsertNode(pCurrentBM);
        }

        FPD_Bookmark pdf_BM1 = FPDBookmarkNew(nullptr);
        FPDBookmarkGetFirstChild(m_fpdDoc, pCurrentBM, &pdf_BM1);

        if (!FPDBookmarkGetDictionary(pdf_BM1))
        {
            FPDBookmarkDestroy(pdf_BM1);
            return;
        }
        else
        {
            SetParent(pdf_BM1, pCurrentBM);
            GetTreeTopologyInfo(pdf_BM1);
        }

        FPD_Bookmark  temp1 = pdf_BM1;
        while (1)
        {
            FPD_Bookmark pdf_BM2 = FPDBookmarkNew(nullptr);
            FPDBookmarkGetNextSibling(m_fpdDoc, temp1, &pdf_BM2);

            if (!FPDBookmarkGetDictionary(pdf_BM2))
            {
                FPDBookmarkDestroy(pdf_BM2);
                FPDBookmarkDestroy(pdf_BM1);
                return;
            }
            else {
                SetParent(pdf_BM2, pCurrentBM);
                SetPrevSibling(pdf_BM2, temp1);
                if (temp1&&temp1 != pdf_BM1)
                {
                    FPDBookmarkDestroy(temp1);
                }
                GetTreeTopologyInfo(pdf_BM2);
                temp1 = pdf_BM2;
            }

        }
        FPDBookmarkDestroy(pdf_BM1);
    }
	
	//查找部分
	typedef struct BMInfo {
    explicit BMInfo(FS_LPCWSTR title) {
        if (title)
        {
             m_title = FSWideStringNew3(title, -1);
        }
        else {
            m_title = nullptr;
        }
        m_flagEnd = false;
        m_resultBm = nullptr;
    }
    ~BMInfo() {
        if (m_title)
            FSWideStringDestroy(m_title);
    }
    FS_WideString m_title;
    bool m_flagEnd;
    FPD_Object  m_resultBm;

}*LPBMInfo;

struct DeleterFPDBookmark
{
    inline void operator() (FPD_Bookmark pValue)
    {
        if (pValue)
        {
            FPDBookmarkDestroy(pValue);
        }
    }
};

struct DeleterFSWideString
{
    inline void operator() (FS_WideString pValue)
    {
        if (pValue)
        {
            FSWideStringDestroy(pValue);
        }
    }
};

    void GetBookmarkByName(FPD_Bookmark pCurrentBM, BMInfo& bmInfo)
    {
        if (pCurrentBM)
        {
            FS_WideString wStrTitle = FSWideStringNew();
            FPDBookmarkGetTitle(pCurrentBM,&wStrTitle);
            auto  strTitle = FSWideStringCastToLPCWSTR(wStrTitle);
            if (FSWideStringCompare2(wStrTitle, bmInfo.m_title) == 0)
            {
                FSWideStringDestroy(wStrTitle);
                bmInfo.m_resultBm=FPDBookmarkGetDictionary(pCurrentBM);
                bmInfo.m_flagEnd = true;
                return;
            }
            FSWideStringDestroy(wStrTitle);
        }

        FPD_Bookmark pdf_BM1 = FPDBookmarkNew(nullptr);
        FPDBookmarkGetFirstChild(m_fpdDoc, pCurrentBM, &pdf_BM1);

        if (!FPDBookmarkGetDictionary(pdf_BM1))
        {
            FPDBookmarkDestroy(pdf_BM1);
            return;
        }
        else
        {
            GetBookmarkByName(pdf_BM1, bmInfo);
        }

        while (!bmInfo.m_flagEnd)
        {
            if (FPDBookmarkGetNextSibling(m_fpdDoc, pdf_BM1, &pdf_BM1))
            {
                GetBookmarkByName(pdf_BM1, bmInfo);
            }
            else {
                break;
            }

        }
        FPDBookmarkDestroy(pdf_BM1);
    }
	
	TEST_F(BookmarkTest, MoveNode)
{
    //doucument operation.
    FS_LPCWSTR      title_bookmark = L"Untitled4";
    FS_LPCWSTR      titleMove = L"Untitled3";
    {
        m_fpdDoc = FPDDocOpen(m_pathIn, "");
        ASSERT_NE(m_fpdDoc, nullptr);
        BMInfo  bmInfo(title_bookmark);
        GetBookmarkByName(nullptr, bmInfo);
        ASSERT_NE(bmInfo.m_resultBm, nullptr);

        BMInfo  bmInfoMove(titleMove);
        GetBookmarkByName(nullptr, bmInfoMove);
        ASSERT_NE(bmInfoMove.m_resultBm, nullptr);

        std::unique_ptr<IPDF_Bookmark> pBookmark = FX_CreateBookmark(m_fpdDoc);

        pBookmark->MoveNode(bmInfoMove.m_resultBm, bmInfo.m_resultBm);
        bool saved = FPDDocSave2(m_fpdDoc, m_pathOut, FPD_SAVE_DEFAULT, false);
        FPDDocClose(m_fpdDoc);

    }
    //Read file.
    {
        m_fpdDoc = FPDDocOpen(m_pathOut, "");
        BMInfo  bmInfo(title_bookmark);
        GetBookmarkByName(nullptr, bmInfo);
        ASSERT_NE(bmInfo.m_resultBm, nullptr);

        std::unique_ptr< _t_FPD_Bookmark, DeleterFPDBookmark>unique_bm1 =
            std::unique_ptr< _t_FPD_Bookmark, DeleterFPDBookmark>(FPDBookmarkNew(bmInfo.m_resultBm));
        std::unique_ptr< _t_FPD_Bookmark, DeleterFPDBookmark>unique_bm2 =
            std::unique_ptr< _t_FPD_Bookmark, DeleterFPDBookmark>(FPDBookmarkNew(nullptr));
        auto pBookmark2 = unique_bm2.get();
   

        FPDBookmarkGetNextSibling(m_fpdDoc, unique_bm1.get(), &pBookmark2);
        FS_WideString  wTitle = FSWideStringNew();
        FPDBookmarkGetTitle(unique_bm2.get(), &wTitle);
        FS_INT32 compareResult =FSWideStringCompare(wTitle, titleMove);
        ASSERT_EQ(compareResult, 0);
        FPDDocClose(m_fpdDoc);
    }

}
	
	
	

需要注意的是在进行遍历查找的时候,递归传递一个引用值,如果找到Targer Node,则通过修改循环中的Flag而使之前的栈都退出掉,以此达到及时退出的目的;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值