Files
znc/include/znc/Template.h
2014-12-31 11:28:38 +01:00

191 lines
6.1 KiB
C++

/*
* Copyright (C) 2004-2015 ZNC, see the NOTICE file for details.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _TEMPLATE_H
#define _TEMPLATE_H
#include <znc/zncconfig.h>
#include <znc/ZNCString.h>
#include <iostream>
#include <list>
#include <memory>
class CTemplate;
class CTemplateTagHandler {
public:
CTemplateTagHandler() {}
virtual ~CTemplateTagHandler() {}
virtual bool HandleVar(CTemplate& Tmpl, const CString& sName, const CString& sArgs, CString& sOutput) {
return false;
}
virtual bool HandleTag(CTemplate& Tmpl, const CString& sName, const CString& sArgs, CString& sOutput) {
return false;
}
virtual bool HandleIf(CTemplate& Tmpl, const CString& sName, const CString& sArgs, CString& sOutput) {
return HandleVar(Tmpl, sName, sArgs, sOutput);
}
virtual bool HandleValue(CTemplate& Tmpl, CString& sValue, const MCString& msOptions) {
return false;
}
private:
};
class CTemplate;
class CTemplateOptions {
public:
CTemplateOptions() {
m_eEscapeFrom = CString::EASCII;
m_eEscapeTo = CString::EASCII;
}
virtual ~CTemplateOptions() {}
void Parse(const CString& sLine);
// Getters
CString::EEscape GetEscapeFrom() const { return m_eEscapeFrom; }
CString::EEscape GetEscapeTo() const { return m_eEscapeTo; }
// !Getters
private:
CString::EEscape m_eEscapeFrom;
CString::EEscape m_eEscapeTo;
};
class CTemplateLoopContext {
public:
CTemplateLoopContext(unsigned long uFilePos, const CString& sLoopName, bool bReverse, std::vector<CTemplate*>* pRows) {
m_uFilePosition = uFilePos;
m_sName = sLoopName;
m_uRowIndex = 0;
m_bReverse = bReverse;
m_pvRows = pRows;
m_bHasData = false;
}
virtual ~CTemplateLoopContext() {}
// Setters
void SetHasData(bool b = true) { m_bHasData = b; }
void SetName(const CString& s) { m_sName = s; }
void SetRowIndex(unsigned int u) { m_uRowIndex = u; }
unsigned int IncRowIndex() { return ++m_uRowIndex; }
unsigned int DecRowIndex() { if (m_uRowIndex == 0) { return 0; } return --m_uRowIndex; }
void SetFilePosition(unsigned int u) { m_uFilePosition = u; }
// !Setters
// Getters
bool HasData() const { return m_bHasData; }
const CString& GetName() const { return m_sName; }
unsigned long GetFilePosition() const { return m_uFilePosition; }
unsigned int GetRowIndex() const { return m_uRowIndex; }
size_t GetRowCount() { return m_pvRows->size(); }
std::vector<CTemplate*>* GetRows() { return m_pvRows; }
CTemplate* GetNextRow() { return GetRow(IncRowIndex()); }
CTemplate* GetCurRow() { return GetRow(m_uRowIndex); }
CTemplate* GetRow(unsigned int uIndex);
CString GetValue(const CString& sName, bool bFromIf = false);
// !Getters
private:
bool m_bReverse; //!< Iterate through this loop in reverse order
bool m_bHasData; //!< Tells whether this loop has real data or not
CString m_sName; //!< The name portion of the <?LOOP name?> tag
unsigned int m_uRowIndex; //!< The index of the current row we're on
unsigned long m_uFilePosition; //!< The file position of the opening <?LOOP?> tag
std::vector<CTemplate*>* m_pvRows; //!< This holds pointers to the templates associated with this loop
};
class CTemplate : public MCString {
public:
CTemplate() : MCString(), m_spOptions(new CTemplateOptions) {
Init();
}
CTemplate(const CString& sFileName) : MCString(), m_sFileName(sFileName), m_spOptions(new CTemplateOptions) {
Init();
}
CTemplate(const std::shared_ptr<CTemplateOptions>& Options, CTemplate* pParent = NULL) : MCString(), m_spOptions(Options) {
Init();
m_pParent = pParent;
}
virtual ~CTemplate();
//! Class for implementing custom tags in subclasses
void AddTagHandler(std::shared_ptr<CTemplateTagHandler> spTagHandler) {
m_vspTagHandlers.push_back(spTagHandler);
}
std::vector<std::shared_ptr<CTemplateTagHandler> >& GetTagHandlers() {
if (m_pParent) {
return m_pParent->GetTagHandlers();
}
return m_vspTagHandlers;
}
CString ResolveLiteral(const CString& sString);
void Init();
CTemplate* GetParent(bool bRoot);
CString ExpandFile(const CString& sFilename, bool bFromInc = false);
bool SetFile(const CString& sFileName);
void SetPath(const CString& sPath); // Sets the dir:dir:dir type path to look at for templates, as of right now no ../../.. protection
CString MakePath(const CString& sPath) const;
void PrependPath(const CString& sPath, bool bIncludesOnly = false);
void AppendPath(const CString& sPath, bool bIncludesOnly = false);
void RemovePath(const CString& sPath);
void ClearPaths();
bool PrintString(CString& sRet);
bool Print(std::ostream& oOut);
bool Print(const CString& sFileName, std::ostream& oOut);
bool ValidIf(const CString& sArgs);
bool ValidExpr(const CString& sExpr);
bool IsTrue(const CString& sName);
bool HasLoop(const CString& sName);
CString GetValue(const CString& sName, bool bFromIf = false);
CTemplate& AddRow(const CString& sName);
CTemplate* GetRow(const CString& sName, unsigned int uIndex);
std::vector<CTemplate*>* GetLoop(const CString& sName);
void DelCurLoopContext();
CTemplateLoopContext* GetCurLoopContext();
CTemplate* GetCurTemplate();
// Getters
const CString& GetFileName() const { return m_sFileName; }
// !Getters
private:
CTemplate* m_pParent;
CString m_sFileName;
std::list<std::pair<CString, bool> > m_lsbPaths;
std::map<CString, std::vector<CTemplate*> > m_mvLoops;
std::vector<CTemplateLoopContext*> m_vLoopContexts;
std::shared_ptr<CTemplateOptions> m_spOptions;
std::vector<std::shared_ptr<CTemplateTagHandler> > m_vspTagHandlers;
};
#endif // !_TEMPLATE_H