/* IEView Plugin for Miranda IM Copyright (C) 2005-2010 Piotr Piastucki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "stdafx.h" TokenDef::TokenDef(const char *tokenString) { this->tokenString = tokenString; this->tokenLen = (int)mir_strlen(tokenString); this->token = 0; this->escape = 0; } TokenDef::TokenDef(const char *tokenString, int token, int escape) { this->tokenString = tokenString; this->token = token; this->tokenLen = (int)mir_strlen(tokenString); this->escape = escape; } Token::Token(int type, const char *text, int escape) { next = nullptr; this->type = type; this->escape = escape; this->text = mir_strdup(text); } Token::~Token() { mir_free(text); } Token* Token::getNext() { return next; } void Token::setNext(Token *ptr) { next = ptr; } int Token::getType() { return type; } int Token::getEscape() { return escape; } const char* Token::getText() { return text; } Template::Template(const char *name, const char *text) { m_next = nullptr; m_tokens = nullptr; m_text = mir_strdup(text); m_name = mir_strdup(name); tokenize(); } Template::~Template() { mir_free(m_text); mir_free(m_name); Token *ptr = m_tokens, *ptr2; m_tokens = nullptr; for (; ptr != nullptr; ptr = ptr2) { ptr2 = ptr->getNext(); delete ptr; } } bool Template::equals(const char *name) { if (!mir_strcmp(m_name, name)) return true; return false; } static TokenDef tokenNames[] = { TokenDef("%name%", Token::INAME, 0), TokenDef("%time%", Token::TIME, 0), TokenDef("%text%", Token::TEXT, 0), TokenDef("%date%", Token::DATE, 0), TokenDef("%base%", Token::BASE, 0), TokenDef("%avatar%", Token::AVATAR, 0), TokenDef("%cid%", Token::CID, 0), TokenDef("%proto%", Token::PROTO, 0), TokenDef("%avatarIn%", Token::AVATARIN, 0), TokenDef("%avatarOut%", Token::AVATAROUT, 0), TokenDef("%nameIn%", Token::NAMEIN, 0), TokenDef("%nameOut%", Token::NAMEOUT, 0), TokenDef("%uin%", Token::UIN, 0), TokenDef("%uinIn%", Token::UININ, 0), TokenDef("%uinOut%", Token::UINOUT, 0), TokenDef("%nickIn%", Token::NICKIN, 0), TokenDef("%nickOut%", Token::NICKOUT, 1), TokenDef("%statusMsg%", Token::STATUSMSG, 0), TokenDef("%\\name%", Token::INAME, 1), TokenDef("%\\time%", Token::TIME, 1), TokenDef("%\\text%", Token::TEXT, 1), TokenDef("%\\date%", Token::DATE, 1), TokenDef("%\\base%", Token::BASE, 1), TokenDef("%\\avatar%", Token::AVATAR, 1), TokenDef("%\\cid%", Token::CID, 1), TokenDef("%\\proto%", Token::PROTO, 1), TokenDef("%\\avatarIn%", Token::AVATARIN, 1), TokenDef("%\\avatarOut%", Token::AVATAROUT, 1), TokenDef("%\\nameIn%", Token::NAMEIN, 1), TokenDef("%\\nameOut%", Token::NAMEOUT, 1), TokenDef("%\\uin%", Token::UIN, 1), TokenDef("%\\uinIn%", Token::UININ, 1), TokenDef("%\\uinOut%", Token::UINOUT, 1), TokenDef("%\\nickIn%", Token::NICKIN, 1), TokenDef("%\\nickOut%", Token::NICKOUT, 1), TokenDef("%\\statusMsg%", Token::STATUSMSG, 1), }; void Template::tokenize() { if (m_text == nullptr) return; char *str = mir_strdup(m_text); Token *lastToken = nullptr; int lastTokenType = Token::PLAIN; int lastTokenEscape = 0; int l = (int)mir_strlen(str); for (int i = 0, lastTokenStart = 0; i <= l;) { Token *newToken; int newTokenType = 0, newTokenSize = 0, newTokenEscape = 0; if (str[i] == '\0') { newTokenType = Token::END; newTokenSize = 1; newTokenEscape = 0; } else { bool found = false; for (unsigned int j = 0; j < (sizeof(tokenNames) / sizeof(tokenNames[0])); j++) { if (!strncmp(str + i, tokenNames[j].tokenString, tokenNames[j].tokenLen)) { newTokenType = tokenNames[j].token; newTokenSize = tokenNames[j].tokenLen; newTokenEscape = tokenNames[j].escape; found = true; break; } } if (!found) { newTokenType = Token::PLAIN; newTokenSize = 1; newTokenEscape = 0; } } if (newTokenType != Token::PLAIN) { if (str[i + newTokenSize] == '%') { //newTokenSize++; } str[i] = '\0'; } if ((lastTokenType != newTokenType || lastTokenEscape != newTokenEscape) && i != lastTokenStart) { if (lastTokenType == Token::PLAIN) newToken = new Token(lastTokenType, str + lastTokenStart, lastTokenEscape); else newToken = new Token(lastTokenType, nullptr, lastTokenEscape); if (lastToken != nullptr) lastToken->setNext(newToken); else m_tokens = newToken; lastToken = newToken; lastTokenStart = i; } lastTokenEscape = newTokenEscape; lastTokenType = newTokenType; i += newTokenSize; } mir_free(str); } TemplateMap* TemplateMap::m_mapList = nullptr; TemplateMap::TemplateMap(const char *name) { m_entries = nullptr; m_next = nullptr; m_filename = nullptr; m_name = mir_strdup(name); m_grouping = false; m_rtl = false; } TemplateMap::~TemplateMap() { mir_free(m_name); mir_free(m_filename); clear(); } TemplateMap* TemplateMap::add(const char *id, const wchar_t *filename) { TemplateMap *map; for (map = m_mapList; map != nullptr; map = map->m_next) { if (!mir_strcmp(map->m_name, id)) { map->clear(); map->setFilename(filename); return map; } } map = new TemplateMap(id); map->setFilename(filename); map->m_next = m_mapList; m_mapList = map; return map; } void TemplateMap::addTemplate(const char *name, const char *text) { Template *tmplate = new Template(name, text); tmplate->m_next = m_entries; m_entries = tmplate; } void TemplateMap::clear() { Template *ptr, *ptr2; ptr = m_entries; m_entries = nullptr; for (; ptr != nullptr; ptr = ptr2) { ptr2 = ptr->getNext(); delete ptr; } } static TokenDef templateNames[] = { TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef(""), TokenDef("") }; TemplateMap* TemplateMap::loadTemplateFile(const wchar_t *id, const wchar_t *filename, bool onlyInfo) { char lastTemplate[1024], tmp2[1024]; if (filename == nullptr || mir_wstrlen(filename) == 0) return nullptr; FILE *fh = _wfopen(filename, L"rt"); if (fh == nullptr) return nullptr; TemplateMap *tmap; if (!onlyInfo) tmap = TemplateMap::add(_T2A(id), filename); else tmap = new TemplateMap(_T2A(id)); char store[4096]; bool wasTemplate = false; CMStringA templateText; while (fgets(store, sizeof(store), fh) != nullptr) { if (sscanf(store, "%s", tmp2) == EOF) continue; //template start bool bFound = false; for (auto &it : templateNames) if (!strncmp(store, it.tokenString, it.tokenLen)) { bFound = true; break; } if (bFound) { if (wasTemplate) tmap->addTemplate(lastTemplate, templateText); templateText.Empty(); wasTemplate = true; sscanf(store, "