/configuration/TranslationFile.cpp

http://cssmatch-plugin.googlecode.com/ · C++ · 196 lines · 148 code · 13 blank · 35 comment · 16 complexity · 8953ef25949a15ea39f5212696380332 MD5 · raw file

  1. /*
  2. * Copyright 2008-2013 Nicolas Maingot
  3. *
  4. * This file is part of CSSMatch.
  5. *
  6. * CSSMatch is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * CSSMatch is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with CSSMatch; if not, see <http://www.gnu.org/licenses>.
  18. *
  19. * Additional permission under GNU GPL version 3 section 7
  20. *
  21. * If you modify CSSMatch, or any covered work, by linking or combining
  22. * it with "Source SDK" (or a modified version of that SDK), containing
  23. * parts covered by the terms of Source SDK licence, the licensors of
  24. * CSSMatch grant you additional permission to convey the resulting work.
  25. */
  26. #include "TranslationFile.h"
  27. using namespace cssmatch;
  28. using std::string;
  29. using std::list;
  30. using std::map;
  31. void TranslationFile::parse() throw(TranslationException)
  32. {
  33. list<string> lines;
  34. getLines(lines);
  35. // I - Where is the header ?
  36. parseHeader(lines);
  37. // No header => no translations
  38. if (header.empty())
  39. throw TranslationException("The file " + filePath + " does not have a valid header");
  40. // II - Header found, try to get the translations
  41. parseTranslations(lines);
  42. }
  43. void TranslationFile::parseHeader(list<string> & lines)
  44. {
  45. while((! lines.empty()) && header.empty())
  46. {
  47. list<string>::const_reference line = lines.front();
  48. // Search for [some header] statement
  49. size_t iHeaderBegins = line.find("[");
  50. if (iHeaderBegins != string::npos)
  51. {
  52. size_t iHeaderEnds = line.find("]");
  53. if (iHeaderEnds != string::npos)
  54. {
  55. setHeader(line.substr(iHeaderBegins, iHeaderEnds - iHeaderBegins + 1));
  56. //Msg("Found header: '%s'\n",translationFile->getHeader().c_str());
  57. }
  58. }
  59. // Else we ignore this invalid line
  60. lines.pop_front();
  61. }
  62. }
  63. // BEURK !
  64. void TranslationFile::parseTranslations(list<string> & lines)
  65. {
  66. // Search for "keyword = translation" statement
  67. // (quotation marks are optionnals, but can delimit the begin/end of a string)
  68. while(! lines.empty())
  69. {
  70. list<string>::const_reference line = lines.front();
  71. size_t iEqual = string::npos;
  72. size_t lineSize = line.size();
  73. bool betweenQuotes = false; // true if we are between quotation marks
  74. // Where is the "=" symbol ?
  75. string::const_iterator itChar = line.begin();
  76. string::const_iterator lastChar = line.end();
  77. bool equalFound = false;
  78. while((itChar != lastChar) && (! equalFound))
  79. {
  80. iEqual++;
  81. switch(*itChar)
  82. {
  83. case '"': // Quoted string
  84. betweenQuotes = (! betweenQuotes);
  85. break;
  86. case '=':
  87. equalFound = (! betweenQuotes); // We found the equal symbol
  88. break;
  89. }
  90. itChar++;
  91. }
  92. // Is the symbol between quotation marks ?
  93. if (iEqual != lineSize-1)
  94. { // No, we can get the data
  95. string dataName = line.substr(0, iEqual); //
  96. ConfigurationFile::trim(dataName);
  97. // Keyword part :
  98. size_t iLastCharDataName = dataName.size() - 1;
  99. if (iLastCharDataName>0)
  100. {
  101. // Remove the quotes if needed
  102. if ((dataName[0] == '"') && (dataName[iLastCharDataName] == '"'))
  103. dataName = dataName.substr(1, iLastCharDataName - 1);
  104. // Get the translation value part
  105. string dataValue = line.substr(iEqual+1, lineSize); // +1 to pass the equal symbol
  106. ConfigurationFile::trim(dataValue);
  107. // Translation part :
  108. // Remove the quotes if needed
  109. size_t iLastCharDataValue = dataValue.size()-1;
  110. if (iLastCharDataValue>0)
  111. {
  112. if ((dataValue[0] == '"') && (dataValue[iLastCharDataValue] == '"'))
  113. dataValue = dataValue.substr(1, iLastCharDataValue - 1);
  114. // \n are replaced by the corresponding escape sequence
  115. size_t iEndLine = dataValue.find("\\n");
  116. while (iEndLine != string::npos)
  117. {
  118. dataValue.replace(iEndLine, 2, "\n", 0, 1);
  119. iEndLine = dataValue.find("\\n");
  120. }
  121. if ((dataName.size() > 0) && (dataValue.size() > 0))
  122. {
  123. addTranslation(dataName, dataValue);
  124. //Msg("Found: '%s'='%s'\n",dataName.c_str(),dataValue.c_str());
  125. }
  126. // Else we ignore this invalid line
  127. }
  128. }
  129. }
  130. // Else we ignore this invalid line
  131. lines.pop_front();
  132. }
  133. }
  134. TranslationFile::TranslationFile(const string & filePath) throw(ConfigurationFileException,
  135. TranslationException)
  136. : ConfigurationFile(filePath)
  137. {
  138. parse();
  139. }
  140. TranslationFile::~TranslationFile()
  141. {}
  142. string TranslationFile::getHeader() const
  143. {
  144. return header;
  145. }
  146. void TranslationFile::setHeader(const string & newHeader)
  147. {
  148. header = newHeader;
  149. }
  150. void TranslationFile::addTranslation(const string & keyword, const string & translation)
  151. {
  152. translations[keyword] = translation;
  153. }
  154. bool TranslationFile::keywordExists(const string & keyword) const
  155. {
  156. return translations.find(keyword) != translations.end();
  157. }
  158. string TranslationFile::operator [](const string & keyword) throw (TranslationException)
  159. {
  160. if (keywordExists(keyword))
  161. return translations[keyword];
  162. else
  163. throw TranslationException(
  164. keyword + " does not correspond to a known translation in the file " + filePath);
  165. }