1 #include <memory>
2 #include "webresourcesmanager.h"
3 
4 #include <globals.h>
5 #include <configmanager.h>
6 #include <wx/url.h>
7 
WebResourcesManager()8 WebResourcesManager::WebResourcesManager()
9 {
10 }
11 
~WebResourcesManager()12 WebResourcesManager::~WebResourcesManager()
13 {
14     ClearEntries();
15 }
16 
LoadDetectionConfigurations(const wxArrayString & baseUrls,ProgressHandler * handler)17 bool WebResourcesManager::LoadDetectionConfigurations(const wxArrayString& baseUrls, ProgressHandler* handler )
18 {
19     ClearEntries();
20 
21     bool AnyValid = false;
22 
23     for ( size_t i=0; i<baseUrls.Count(); i++ )
24     {
25 
26         wxString listUrl = baseUrls[i];
27         wxString baseUrl;
28         if ( listUrl.Last() == _T('/') )
29         {
30             baseUrl = listUrl;
31         }
32         else
33         {
34             baseUrl = listUrl.BeforeLast(_T('/'));
35             if ( baseUrl.IsEmpty() )
36             {
37                 baseUrl = listUrl;
38             }
39             baseUrl += _T('/');
40         }
41 
42         std::vector< char > arr;
43         if ( !DoDownload( listUrl, handler, arr ) ) continue;
44 
45         TiXmlDocument doc;
46         if ( doc.Parse( &arr[0], 0, TIXML_DEFAULT_ENCODING ) )
47         {
48             if ( doc.RootElement() )
49             {
50                 if ( !strcmp(doc.RootElement()->Value(),"libfinderlist") )
51                 {
52                     TiXmlElement* root = doc.RootElement();
53                     for ( TiXmlElement* lib = root->FirstChildElement("library");
54                           lib;
55                           lib = lib->NextSiblingElement("library") )
56                     {
57                         wxString ShortCode = wxString( lib->Attribute("short_code"), wxConvUTF8 );
58                         wxString FileName  = wxString( lib->Attribute("file_name"),  wxConvUTF8 );
59                         wxString DigiSign  = wxString( lib->Attribute("sign"),       wxConvUTF8 );
60                         if ( !ShortCode.IsEmpty() && !FileName.IsEmpty() )
61                         {
62                             DetectConfigurationEntry* entry = new DetectConfigurationEntry;
63                             entry->m_Url = baseUrl + FileName;
64                             entry->m_Sign = DigiSign;
65                             entry->m_Next = m_Entries[ ShortCode ];
66                             m_Entries[ ShortCode ] = entry;
67                             AnyValid = true;
68                             continue;
69                         }
70                     }
71 
72                     continue;
73                 }
74             }
75         }
76         if ( handler ) handler->Error( _("Invalid data in libraries list in: ") + listUrl, handler->idDownloadList );
77     }
78 
79     if ( handler ) handler->JobFinished( handler->idDownloadList );
80     return AnyValid;
81 }
82 
DoDownload(const wxString & urlName,ProgressHandler * handler,std::vector<char> & arr)83 bool WebResourcesManager::DoDownload( const wxString& urlName, ProgressHandler* handler, std::vector< char >& arr )
84 {
85     int id = handler ? handler->StartDownloading( urlName ) : 0;
86 
87     if ( handler ) handler->SetProgress( 0.f, id );
88 
89     std::unique_ptr< wxURL > url ( new wxURL( urlName ) );
90     url->SetProxy( ConfigManager::GetProxy() );
91 
92     if ( url->GetError() != wxURL_NOERR )
93     {
94         if ( handler ) handler->Error( _("Couldn't open url: ") + urlName, id );
95         return false;
96     }
97 
98     std::unique_ptr< wxInputStream > stream ( url->GetInputStream() );
99     if ( !stream.get() || !stream->IsOk() )
100     {
101         if ( handler ) handler->Error( _("Couldn't open url: ") + urlName, id );
102         return false;
103     }
104 
105     wxFileOffset length = stream->GetLength();
106     if ( !length )
107     {
108         return true;
109     }
110 
111     static const int BlockSize = 0x1000;
112 
113     if ( length != wxInvalidOffset )
114     {
115         arr.resize( length+1 );
116         arr[length] = 0;
117 
118         wxFileOffset left = length;
119         wxFileOffset read = 0;
120         if ( handler ) handler->SetProgress( 0.f, id  );
121         while ( left )
122         {
123             size_t nowRead = stream->Read( &arr[read], ( left > BlockSize ) ? BlockSize : left ).LastRead();
124             if ( !nowRead )
125             {
126                 if ( handler ) handler->Error( _("Read error from url: ") + urlName, id );
127                 return false;
128             }
129 
130             left -= nowRead;
131             read += nowRead;
132 
133             if ( handler ) handler->SetProgress( 100.f * read / length, id );
134         }
135     }
136     else
137     {
138         if ( handler ) handler->SetProgress( -1.f, id );
139         size_t read = 0;
140         do
141         {
142             arr.resize( read + BlockSize + 1 );
143             size_t nowRead = stream->Read( &arr[read], BlockSize ).LastRead();
144             if ( !nowRead ) break;
145             read += nowRead;
146             if ( handler ) handler->SetProgress( -1.f, id );
147         }
148         while ( !stream->Eof() );
149 
150         arr.resize( read+1 );
151         arr[read] = 0;
152     }
153     if ( handler ) handler->JobFinished( id );
154     return true;
155 }
156 
ClearEntries()157 void WebResourcesManager::ClearEntries()
158 {
159     for ( EntriesT::iterator i = m_Entries.begin(); i!=m_Entries.end(); ++i )
160     {
161         for ( DetectConfigurationEntry * entry = i->second, *next; entry; entry = next )
162         {
163             next = entry->m_Next;
164             delete entry;
165         }
166     }
167     m_Entries.clear();
168 }
169 
LoadDetectionConfig(const wxString & shortcut,std::vector<char> & content,ProgressHandler * handler)170 bool WebResourcesManager::LoadDetectionConfig( const wxString& shortcut, std::vector< char >& content, ProgressHandler* handler )
171 {
172     DetectConfigurationEntry* entry = m_Entries[ shortcut ];
173     for ( ; entry ; entry = entry->m_Next )
174     {
175         if ( DoDownload( entry->m_Url, handler, content ) )
176         {
177             if ( handler ) handler->JobFinished( handler->idDownloadConfig );
178             return true;
179         }
180     }
181     if ( handler ) handler->Error( _("Couldn't download any configuration"), handler->idDownloadConfig );
182     return false;
183 }
184