| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| 6 | |
| 7 #include "xfa/src/fde/css/fde_csscache.h" | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "core/include/fxcrt/fx_ext.h" | |
| 12 | |
| 13 FDE_CSSCacheItem::FDE_CSSCacheItem(IFDE_CSSStyleSheet* p) | |
| 14 : pStylesheet(p), dwActivity(0) { | |
| 15 FXSYS_assert(pStylesheet); | |
| 16 pStylesheet->AddRef(); | |
| 17 } | |
| 18 FDE_CSSCacheItem::~FDE_CSSCacheItem() { | |
| 19 pStylesheet->Release(); | |
| 20 } | |
| 21 IFDE_CSSStyleSheetCache* IFDE_CSSStyleSheetCache::Create() { | |
| 22 return new CFDE_CSSStyleSheetCache; | |
| 23 } | |
| 24 | |
| 25 CFDE_CSSStyleSheetCache::CFDE_CSSStyleSheetCache() | |
| 26 : m_pFixedStore(NULL), m_iMaxItems(5) {} | |
| 27 | |
| 28 CFDE_CSSStyleSheetCache::~CFDE_CSSStyleSheetCache() { | |
| 29 for (const auto& pair : m_Stylesheets) { | |
| 30 FXTARGET_DeleteWith(FDE_CSSCacheItem, m_pFixedStore, pair.second); | |
| 31 } | |
| 32 m_Stylesheets.clear(); | |
| 33 if (m_pFixedStore) { | |
| 34 m_pFixedStore->Release(); | |
| 35 } | |
| 36 } | |
| 37 void CFDE_CSSStyleSheetCache::AddStyleSheet(const CFX_ByteStringC& szKey, | |
| 38 IFDE_CSSStyleSheet* pStyleSheet) { | |
| 39 FXSYS_assert(pStyleSheet != NULL); | |
| 40 if (m_pFixedStore == NULL) { | |
| 41 m_pFixedStore = | |
| 42 FX_CreateAllocator(FX_ALLOCTYPE_Fixed, std::max(10, m_iMaxItems), | |
| 43 sizeof(FDE_CSSCacheItem)); | |
| 44 FXSYS_assert(m_pFixedStore != NULL); | |
| 45 } | |
| 46 auto it = m_Stylesheets.find(szKey); | |
| 47 if (it != m_Stylesheets.end()) { | |
| 48 FDE_CSSCacheItem* pItem = it->second; | |
| 49 if (pItem->pStylesheet != pStyleSheet) { | |
| 50 pItem->pStylesheet->Release(); | |
| 51 pItem->pStylesheet = pStyleSheet; | |
| 52 pItem->pStylesheet->AddRef(); | |
| 53 pItem->dwActivity = 0; | |
| 54 } | |
| 55 } else { | |
| 56 while (static_cast<int32_t>(m_Stylesheets.size()) >= m_iMaxItems) { | |
| 57 RemoveLowestActivityItem(); | |
| 58 } | |
| 59 m_Stylesheets[szKey] = | |
| 60 FXTARGET_NewWith(m_pFixedStore) FDE_CSSCacheItem(pStyleSheet); | |
| 61 } | |
| 62 } | |
| 63 IFDE_CSSStyleSheet* CFDE_CSSStyleSheetCache::GetStyleSheet( | |
| 64 const CFX_ByteStringC& szKey) const { | |
| 65 auto it = m_Stylesheets.find(szKey); | |
| 66 if (it == m_Stylesheets.end()) { | |
| 67 return nullptr; | |
| 68 } | |
| 69 FDE_CSSCacheItem* pItem = it->second; | |
| 70 pItem->dwActivity++; | |
| 71 pItem->pStylesheet->AddRef(); | |
| 72 return pItem->pStylesheet; | |
| 73 } | |
| 74 void CFDE_CSSStyleSheetCache::RemoveStyleSheet(const CFX_ByteStringC& szKey) { | |
| 75 auto it = m_Stylesheets.find(szKey); | |
| 76 if (it == m_Stylesheets.end()) { | |
| 77 return; | |
| 78 } | |
| 79 FXTARGET_DeleteWith(FDE_CSSCacheItem, m_pFixedStore, it->second); | |
| 80 m_Stylesheets.erase(it); | |
| 81 } | |
| 82 void CFDE_CSSStyleSheetCache::RemoveLowestActivityItem() { | |
| 83 auto found = m_Stylesheets.end(); | |
| 84 for (auto it = m_Stylesheets.begin(); it != m_Stylesheets.end(); ++it) { | |
| 85 switch (it->first.GetID()) { | |
| 86 case FXBSTR_ID('#', 'U', 'S', 'E'): | |
| 87 case FXBSTR_ID('#', 'A', 'G', 'E'): | |
| 88 continue; | |
| 89 } | |
| 90 if (found == m_Stylesheets.end() || | |
| 91 it->second->dwActivity > found->second->dwActivity) { | |
| 92 found = it; | |
| 93 } | |
| 94 } | |
| 95 if (found != m_Stylesheets.end()) { | |
| 96 FXTARGET_DeleteWith(FDE_CSSCacheItem, m_pFixedStore, found->second); | |
| 97 m_Stylesheets.erase(found); | |
| 98 } | |
| 99 } | |
| 100 FDE_CSSTagCache::FDE_CSSTagCache(FDE_CSSTagCache* parent, | |
| 101 IFDE_CSSTagProvider* tag) | |
| 102 : pTag(tag), | |
| 103 pParent(parent), | |
| 104 dwIDHash(0), | |
| 105 dwTagHash(0), | |
| 106 iClassIndex(0), | |
| 107 dwClassHashs(1) { | |
| 108 FXSYS_assert(pTag != NULL); | |
| 109 CFX_WideStringC wsValue, wsName = pTag->GetTagName(); | |
| 110 dwTagHash = | |
| 111 FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE); | |
| 112 FX_POSITION pos = pTag->GetFirstAttribute(); | |
| 113 while (pos != NULL) { | |
| 114 pTag->GetNextAttribute(pos, wsName, wsValue); | |
| 115 FX_DWORD dwNameHash = | |
| 116 FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE); | |
| 117 static const FX_DWORD s_dwIDHash = FX_HashCode_String_GetW(L"id", 2, TRUE); | |
| 118 static const FX_DWORD s_dwClassHash = | |
| 119 FX_HashCode_String_GetW(L"class", 5, TRUE); | |
| 120 if (dwNameHash == s_dwClassHash) { | |
| 121 FX_DWORD dwHash = | |
| 122 FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength()); | |
| 123 dwClassHashs.Add(dwHash); | |
| 124 } else if (dwNameHash == s_dwIDHash) { | |
| 125 dwIDHash = FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength()); | |
| 126 } | |
| 127 } | |
| 128 } | |
| 129 FDE_CSSTagCache::FDE_CSSTagCache(const FDE_CSSTagCache& it) | |
| 130 : pTag(it.pTag), | |
| 131 pParent(it.pParent), | |
| 132 dwIDHash(it.dwIDHash), | |
| 133 dwTagHash(it.dwTagHash), | |
| 134 iClassIndex(0), | |
| 135 dwClassHashs(1) { | |
| 136 if (it.dwClassHashs.GetSize() > 0) { | |
| 137 dwClassHashs.Copy(it.dwClassHashs); | |
| 138 } | |
| 139 } | |
| 140 void CFDE_CSSAccelerator::OnEnterTag(IFDE_CSSTagProvider* pTag) { | |
| 141 FDE_CSSTagCache* pTop = GetTopElement(); | |
| 142 FDE_CSSTagCache item(pTop, pTag); | |
| 143 m_Stack.Push(item); | |
| 144 } | |
| 145 void CFDE_CSSAccelerator::OnLeaveTag(IFDE_CSSTagProvider* pTag) { | |
| 146 FXSYS_assert(m_Stack.GetTopElement()); | |
| 147 FXSYS_assert(m_Stack.GetTopElement()->GetTag() == pTag); | |
| 148 m_Stack.Pop(); | |
| 149 } | |
| OLD | NEW |