[cstdstring] demise Format, replacing with StringUtils::Format
[vuplus_xbmc] / xbmc / addons / AddonCallbacksAddon.cpp
1 /*
2  *      Copyright (C) 2012-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 #include "Application.h"
22 #include "Addon.h"
23 #include "AddonCallbacksAddon.h"
24 #include "utils/log.h"
25 #include "LangInfo.h"
26 #include "dialogs/GUIDialogKaiToast.h"
27 #include "filesystem/File.h"
28 #include "filesystem/Directory.h"
29 #include "utils/URIUtils.h"
30 #include "FileItem.h"
31 #include "network/Network.h"
32 #include "utils/CharsetConverter.h"
33 #include "utils/StringUtils.h"
34 #include "cores/dvdplayer/DVDCodecs/DVDCodecs.h"
35
36 using namespace XFILE;
37
38 namespace ADDON
39 {
40
41 CAddonCallbacksAddon::CAddonCallbacksAddon(CAddon* addon)
42 {
43   m_addon     = addon;
44   m_callbacks = new CB_AddOnLib;
45
46   /* write XBMC addon-on specific add-on function addresses to the callback table */
47   m_callbacks->Log                = AddOnLog;
48   m_callbacks->QueueNotification  = QueueNotification;
49   m_callbacks->WakeOnLan          = WakeOnLan;
50   m_callbacks->GetSetting         = GetAddonSetting;
51   m_callbacks->UnknownToUTF8      = UnknownToUTF8;
52   m_callbacks->GetLocalizedString = GetLocalizedString;
53   m_callbacks->GetDVDMenuLanguage = GetDVDMenuLanguage;
54   m_callbacks->FreeString         = FreeString;
55
56   m_callbacks->OpenFile           = OpenFile;
57   m_callbacks->OpenFileForWrite   = OpenFileForWrite;
58   m_callbacks->ReadFile           = ReadFile;
59   m_callbacks->ReadFileString     = ReadFileString;
60   m_callbacks->WriteFile          = WriteFile;
61   m_callbacks->FlushFile          = FlushFile;
62   m_callbacks->SeekFile           = SeekFile;
63   m_callbacks->TruncateFile       = TruncateFile;
64   m_callbacks->GetFilePosition    = GetFilePosition;
65   m_callbacks->GetFileLength      = GetFileLength;
66   m_callbacks->CloseFile          = CloseFile;
67   m_callbacks->GetFileChunkSize   = GetFileChunkSize;
68   m_callbacks->FileExists         = FileExists;
69   m_callbacks->StatFile           = StatFile;
70   m_callbacks->DeleteFile         = DeleteFile;
71
72   m_callbacks->CanOpenDirectory   = CanOpenDirectory;
73   m_callbacks->CreateDirectory    = CreateDirectory;
74   m_callbacks->DirectoryExists    = DirectoryExists;
75   m_callbacks->RemoveDirectory    = RemoveDirectory;
76 }
77
78 CAddonCallbacksAddon::~CAddonCallbacksAddon()
79 {
80   /* delete the callback table */
81   delete m_callbacks;
82 }
83
84 void CAddonCallbacksAddon::AddOnLog(void *addonData, const addon_log_t addonLogLevel, const char *strMessage)
85 {
86   CAddonCallbacks* addon = (CAddonCallbacks*) addonData;
87   if (addon == NULL || strMessage == NULL)
88   {
89     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__);
90     return;
91   }
92
93   CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon();
94
95   try
96   {
97     int xbmcLogLevel = LOGNONE;
98     switch (addonLogLevel)
99     {
100       case LOG_ERROR:
101         xbmcLogLevel = LOGERROR;
102         break;
103       case LOG_INFO:
104         xbmcLogLevel = LOGINFO;
105         break;
106       case LOG_NOTICE:
107         xbmcLogLevel = LOGNOTICE;
108         break;
109       case LOG_DEBUG:
110       default:
111         xbmcLogLevel = LOGDEBUG;
112         break;
113     }
114
115     CStdString strXbmcMessage = StringUtils::Format("AddOnLog: %s: %s", addonHelper->m_addon->Name().c_str(), strMessage);
116     CLog::Log(xbmcLogLevel, "%s", strXbmcMessage.c_str());
117   }
118   catch (std::exception &e)
119   {
120     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s",
121         __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str());
122   }
123 }
124
125 void CAddonCallbacksAddon::QueueNotification(void *addonData, const queue_msg_t type, const char *strMessage)
126 {
127   CAddonCallbacks* addon = (CAddonCallbacks*) addonData;
128   if (addon == NULL || strMessage == NULL)
129   {
130     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__);
131     return;
132   }
133
134   CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon();
135
136   try
137   {
138     switch (type)
139     {
140       case QUEUE_WARNING:
141         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, addonHelper->m_addon->Name(), strMessage, 3000, true);
142         CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Warning Message: '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage);
143         break;
144
145       case QUEUE_ERROR:
146         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Error, addonHelper->m_addon->Name(), strMessage, 3000, true);
147         CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Error Message : '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage);
148         break;
149
150       case QUEUE_INFO:
151       default:
152         CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, addonHelper->m_addon->Name(), strMessage, 3000, false);
153         CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - %s - Info Message : '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strMessage);
154         break;
155     }
156   }
157   catch (std::exception &e)
158   {
159     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s",
160         __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str());
161   }
162 }
163
164 bool CAddonCallbacksAddon::WakeOnLan(const char *mac)
165 {
166   return g_application.getNetwork().WakeOnLan(mac);
167 }
168
169 bool CAddonCallbacksAddon::GetAddonSetting(void *addonData, const char *strSettingName, void *settingValue)
170 {
171   CAddonCallbacks* addon = (CAddonCallbacks*) addonData;
172   if (addon == NULL || strSettingName == NULL || settingValue == NULL)
173   {
174     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - called with a null pointer", __FUNCTION__);
175     return false;
176   }
177
178   CAddonCallbacksAddon* addonHelper = addon->GetHelperAddon();
179
180   try
181   {
182     CLog::Log(LOGDEBUG, "CAddonCallbacksAddon - %s - add-on '%s' requests setting '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str(), strSettingName);
183
184     if (!addonHelper->m_addon->ReloadSettings())
185     {
186       CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - could't get settings for add-on '%s'", __FUNCTION__, addonHelper->m_addon->Name().c_str());
187       return false;
188     }
189
190     const TiXmlElement *category = addonHelper->m_addon->GetSettingsXML()->FirstChildElement("category");
191     if (!category) // add a default one...
192       category = addonHelper->m_addon->GetSettingsXML();
193
194     while (category)
195     {
196       const TiXmlElement *setting = category->FirstChildElement("setting");
197       while (setting)
198       {
199         const char *id = setting->Attribute("id");
200         const char *type = setting->Attribute("type");
201
202         if (strcmpi(id, strSettingName) == 0 && type)
203         {
204           if (strcmpi(type, "text")   == 0 || strcmpi(type, "ipaddress") == 0 ||
205               strcmpi(type, "folder") == 0 || strcmpi(type, "action")    == 0 ||
206               strcmpi(type, "music")  == 0 || strcmpi(type, "pictures")  == 0 ||
207               strcmpi(type, "folder") == 0 || strcmpi(type, "programs")  == 0 ||
208               strcmpi(type, "file")  == 0 || strcmpi(type, "fileenum")  == 0)
209           {
210             strcpy((char*) settingValue, addonHelper->m_addon->GetSetting(id).c_str());
211             return true;
212           }
213           else if (strcmpi(type, "number") == 0 || strcmpi(type, "enum") == 0 ||
214                    strcmpi(type, "labelenum") == 0)
215           {
216             *(int*) settingValue = (int) atoi(addonHelper->m_addon->GetSetting(id));
217             return true;
218           }
219           else if (strcmpi(type, "bool") == 0)
220           {
221             *(bool*) settingValue = (bool) (addonHelper->m_addon->GetSetting(id) == "true" ? true : false);
222             return true;
223           }
224           else if (strcmpi(type, "slider") == 0)
225           {
226             const char *option = setting->Attribute("option");
227             if (option && strcmpi(option, "int") == 0)
228             {
229               *(int*) settingValue = (int) atoi(addonHelper->m_addon->GetSetting(id));
230               return true;
231             }
232             else
233             {
234               *(float*) settingValue = (float) atof(addonHelper->m_addon->GetSetting(id));
235               return true;
236             }
237           }
238         }
239         setting = setting->NextSiblingElement("setting");
240       }
241       category = category->NextSiblingElement("category");
242     }
243     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - can't find setting '%s' in '%s'", __FUNCTION__, strSettingName, addonHelper->m_addon->Name().c_str());
244   }
245   catch (std::exception &e)
246   {
247     CLog::Log(LOGERROR, "CAddonCallbacksAddon - %s - exception '%s' caught in call in add-on '%s'. please contact the developer of this addon: %s",
248         __FUNCTION__, e.what(), addonHelper->m_addon->Name().c_str(), addonHelper->m_addon->Author().c_str());
249   }
250
251   return false;
252 }
253
254 char* CAddonCallbacksAddon::UnknownToUTF8(const char *strSource)
255 {
256   CStdString string;
257   if (strSource != NULL)
258     g_charsetConverter.unknownToUTF8(strSource, string);
259   else
260     string = "";
261   char* buffer = strdup(string.c_str());
262   return buffer;
263 }
264
265 char* CAddonCallbacksAddon::GetLocalizedString(const void* addonData, long dwCode)
266 {
267   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
268   if (!helper || g_application.m_bStop)
269     return NULL;
270
271   CAddonCallbacksAddon* addonHelper = helper->GetHelperAddon();
272
273   CStdString string;
274   if (dwCode >= 30000 && dwCode <= 30999)
275     string = addonHelper->m_addon->GetString(dwCode).c_str();
276   else if (dwCode >= 32000 && dwCode <= 32999)
277     string = addonHelper->m_addon->GetString(dwCode).c_str();
278   else
279     string = g_localizeStrings.Get(dwCode).c_str();
280
281   char* buffer = strdup(string.c_str());
282   return buffer;
283 }
284
285 char* CAddonCallbacksAddon::GetDVDMenuLanguage(const void* addonData)
286 {
287   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
288   if (!helper)
289     return NULL;
290
291   CStdString string = g_langInfo.GetDVDMenuLanguage();
292
293   char* buffer = strdup(string.c_str());
294   return buffer;
295 }
296
297 void CAddonCallbacksAddon::FreeString(const void* addonData, char* str)
298 {
299   delete[] str;
300 }
301
302 void* CAddonCallbacksAddon::OpenFile(const void* addonData, const char* strFileName, unsigned int flags)
303 {
304   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
305   if (!helper)
306     return NULL;
307
308   CFile* file = new CFile;
309   if (file->Open(strFileName, flags))
310     return ((void*)file);
311
312   delete file;
313   return NULL;
314 }
315
316 void* CAddonCallbacksAddon::OpenFileForWrite(const void* addonData, const char* strFileName, bool bOverwrite)
317 {
318   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
319   if (!helper)
320     return NULL;
321
322   CFile* file = new CFile;
323   if (file->OpenForWrite(strFileName, bOverwrite))
324     return ((void*)file);
325
326   delete file;
327   return NULL;
328 }
329
330 unsigned int CAddonCallbacksAddon::ReadFile(const void* addonData, void* file, void* lpBuf, int64_t uiBufSize)
331 {
332   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
333   if (!helper)
334     return 0;
335
336   CFile* cfile = (CFile*)file;
337   if (!cfile)
338     return 0;
339
340   return cfile->Read(lpBuf, uiBufSize);
341 }
342
343 bool CAddonCallbacksAddon::ReadFileString(const void* addonData, void* file, char *szLine, int iLineLength)
344 {
345   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
346   if (!helper)
347     return false;
348
349   CFile* cfile = (CFile*)file;
350   if (!cfile)
351     return false;
352
353   return cfile->ReadString(szLine, iLineLength);
354 }
355
356 int CAddonCallbacksAddon::WriteFile(const void* addonData, void* file, const void* lpBuf, int64_t uiBufSize)
357 {
358   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
359   if (!helper)
360     return -1;
361
362   CFile* cfile = (CFile*)file;
363   if (!cfile)
364     return -1;
365
366   return cfile->Write(lpBuf, uiBufSize);
367 }
368
369 void CAddonCallbacksAddon::FlushFile(const void* addonData, void* file)
370 {
371   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
372   if (!helper)
373     return;
374
375   CFile* cfile = (CFile*)file;
376   if (!cfile)
377     return;
378
379   cfile->Flush();
380 }
381
382 int64_t CAddonCallbacksAddon::SeekFile(const void* addonData, void* file, int64_t iFilePosition, int iWhence)
383 {
384   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
385   if (!helper)
386     return 0;
387
388   CFile* cfile = (CFile*)file;
389   if (!cfile)
390     return 0;
391
392   return cfile->Seek(iFilePosition, iWhence);
393 }
394
395 int CAddonCallbacksAddon::TruncateFile(const void* addonData, void* file, int64_t iSize)
396 {
397   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
398   if (!helper)
399     return 0;
400
401   CFile* cfile = (CFile*)file;
402   if (!cfile)
403     return 0;
404
405   return cfile->Truncate(iSize);
406 }
407
408 int64_t CAddonCallbacksAddon::GetFilePosition(const void* addonData, void* file)
409 {
410   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
411   if (!helper)
412     return 0;
413
414   CFile* cfile = (CFile*)file;
415   if (!cfile)
416     return 0;
417
418   return cfile->GetPosition();
419 }
420
421 int64_t CAddonCallbacksAddon::GetFileLength(const void* addonData, void* file)
422 {
423   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
424   if (!helper)
425     return 0;
426
427   CFile* cfile = (CFile*)file;
428   if (!cfile)
429     return 0;
430
431   return cfile->GetLength();
432 }
433
434 void CAddonCallbacksAddon::CloseFile(const void* addonData, void* file)
435 {
436   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
437   if (!helper)
438     return;
439
440   CFile* cfile = (CFile*)file;
441   if (cfile)
442   {
443     cfile->Close();
444     delete cfile;
445   }
446 }
447
448 int CAddonCallbacksAddon::GetFileChunkSize(const void* addonData, void* file)
449 {
450   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
451   if (!helper)
452     return 0;
453
454   CFile* cfile = (CFile*)file;
455   if (!cfile)
456     return 0;
457
458   return cfile->GetChunkSize();
459 }
460
461 bool CAddonCallbacksAddon::FileExists(const void* addonData, const char *strFileName, bool bUseCache)
462 {
463   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
464   if (!helper)
465     return false;
466
467   return CFile::Exists(strFileName, bUseCache);
468 }
469
470 int CAddonCallbacksAddon::StatFile(const void* addonData, const char *strFileName, struct __stat64* buffer)
471 {
472   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
473   if (!helper)
474     return -1;
475
476   return CFile::Stat(strFileName, buffer);
477 }
478
479 bool CAddonCallbacksAddon::DeleteFile(const void* addonData, const char *strFileName)
480 {
481   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
482   if (!helper)
483     return false;
484
485   return CFile::Delete(strFileName);
486 }
487
488 bool CAddonCallbacksAddon::CanOpenDirectory(const void* addonData, const char* strURL)
489 {
490   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
491   if (!helper)
492     return false;
493
494   CFileItemList items;
495   return CDirectory::GetDirectory(strURL, items);
496 }
497
498 bool CAddonCallbacksAddon::CreateDirectory(const void* addonData, const char *strPath)
499 {
500   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
501   if (!helper)
502     return false;
503
504   return CDirectory::Create(strPath);
505 }
506
507 bool CAddonCallbacksAddon::DirectoryExists(const void* addonData, const char *strPath)
508 {
509   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
510   if (!helper)
511     return false;
512
513   return CDirectory::Exists(strPath);
514 }
515
516 bool CAddonCallbacksAddon::RemoveDirectory(const void* addonData, const char *strPath)
517 {
518   CAddonCallbacks* helper = (CAddonCallbacks*) addonData;
519   if (!helper)
520     return false;
521
522   // Empty directory
523   CFileItemList fileItems;
524   CDirectory::GetDirectory(strPath, fileItems);
525   for (int i = 0; i < fileItems.Size(); ++i)
526     CFile::Delete(fileItems.Get(i)->GetPath());
527
528   return CDirectory::Remove(strPath);
529 }
530
531 }; /* namespace ADDON */