lltextparser.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:7k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file lltextparser.cpp
  3.  *
  4.  * $LicenseInfo:firstyear=2001&license=viewergpl$
  5.  * 
  6.  * Copyright (c) 2001-2010, Linden Research, Inc.
  7.  * 
  8.  * Second Life Viewer Source Code
  9.  * The source code in this file ("Source Code") is provided by Linden Lab
  10.  * to you under the terms of the GNU General Public License, version 2.0
  11.  * ("GPL"), unless you have obtained a separate licensing agreement
  12.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  13.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15.  * 
  16.  * There are special exceptions to the terms and conditions of the GPL as
  17.  * it is applied to this Source Code. View the full text of the exception
  18.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  19.  * online at
  20.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21.  * 
  22.  * By copying, modifying or distributing this software, you acknowledge
  23.  * that you have read and understood your obligations described above,
  24.  * and agree to abide by those obligations.
  25.  * 
  26.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28.  * COMPLETENESS OR PERFORMANCE.
  29.  * $/LicenseInfo$
  30.  */
  31. #include "linden_common.h"
  32. #include "lltextparser.h"
  33. #include "llsd.h"
  34. #include "llsdserialize.h"
  35. #include "llerror.h"
  36. #include "lluuid.h"
  37. #include "llstring.h"
  38. #include "message.h"
  39. #include "llmath.h"
  40. #include "v4color.h"
  41. #include "lldir.h"
  42. // Routines used for parsing text for TextParsers and html
  43. LLTextParser* LLTextParser::sInstance = NULL;
  44. //
  45. // Member Functions
  46. //
  47. LLTextParser::~LLTextParser()
  48. {
  49. sInstance=NULL;
  50. }
  51. // static
  52. LLTextParser* LLTextParser::getInstance()
  53. {
  54. if (!sInstance)
  55. {
  56. sInstance = new LLTextParser();
  57. sInstance->loadFromDisk();
  58. }
  59. return sInstance;
  60. }
  61. // Moved triggerAlerts() to llfloaterchat.cpp to break llui/llaudio library dependency.
  62. S32 LLTextParser::findPattern(const std::string &text, LLSD highlight)
  63. {
  64. if (!highlight.has("pattern")) return -1;
  65. std::string pattern=std::string(highlight["pattern"]);
  66. std::string ltext=text;
  67. if (!(bool)highlight["case_sensitive"])
  68. {
  69. ltext   = utf8str_tolower(text);
  70. pattern= utf8str_tolower(pattern);
  71. }
  72. size_t found=std::string::npos;
  73. switch ((S32)highlight["condition"])
  74. {
  75. case CONTAINS:
  76. found = ltext.find(pattern); 
  77. break;
  78. case MATCHES:
  79.     found = (! ltext.compare(pattern) ? 0 : std::string::npos);
  80. break;
  81. case STARTS_WITH:
  82. found = (! ltext.find(pattern) ? 0 : std::string::npos);
  83. break;
  84. case ENDS_WITH:
  85. S32 pos = ltext.rfind(pattern); 
  86. if (pos >= 0 && (ltext.length()-pattern.length()==pos)) found = pos;
  87. break;
  88. }
  89. return found;
  90. }
  91. LLSD LLTextParser::parsePartialLineHighlights(const std::string &text, const LLColor4 &color, EHighlightPosition part, S32 index)
  92. {
  93. //evil recursive string atomizer.
  94. LLSD ret_llsd, start_llsd, middle_llsd, end_llsd;
  95. for (S32 i=index;i<mHighlights.size();i++)
  96. {
  97. S32 condition = mHighlights[i]["condition"];
  98. if ((S32)mHighlights[i]["highlight"]==PART && condition!=MATCHES)
  99. {
  100. if ( (condition==STARTS_WITH && part==START) ||
  101.      (condition==ENDS_WITH   && part==END)   ||
  102.   condition==CONTAINS    || part==WHOLE )
  103. {
  104. S32 start = findPattern(text,mHighlights[i]);
  105. if (start >= 0 )
  106. {
  107. S32 end =  std::string(mHighlights[i]["pattern"]).length();
  108. S32 len = text.length();
  109. EHighlightPosition newpart;
  110. if (start==0)
  111. {
  112. start_llsd[0]["text"] =text.substr(0,end);
  113. start_llsd[0]["color"]=mHighlights[i]["color"];
  114. if (end < len)
  115. {
  116. if (part==END   || part==WHOLE) newpart=END; else newpart=MIDDLE;
  117. end_llsd=parsePartialLineHighlights(text.substr( end ),color,newpart,i);
  118. }
  119. }
  120. else
  121. {
  122. if (part==START || part==WHOLE) newpart=START; else newpart=MIDDLE;
  123. start_llsd=parsePartialLineHighlights(text.substr(0,start),color,newpart,i+1);
  124. if (end < len)
  125. {
  126. middle_llsd[0]["text"] =text.substr(start,end);
  127. middle_llsd[0]["color"]=mHighlights[i]["color"];
  128. if (part==END   || part==WHOLE) newpart=END; else newpart=MIDDLE;
  129. end_llsd=parsePartialLineHighlights(text.substr( (start+end) ),color,newpart,i);
  130. }
  131. else
  132. {
  133. end_llsd[0]["text"] =text.substr(start,end);
  134. end_llsd[0]["color"]=mHighlights[i]["color"];
  135. }
  136. }
  137. S32 retcount=0;
  138. //FIXME These loops should be wrapped into a subroutine.
  139. for (LLSD::array_iterator iter = start_llsd.beginArray();
  140.  iter != start_llsd.endArray();++iter)
  141. {
  142. LLSD highlight = *iter;
  143. ret_llsd[retcount++]=highlight;
  144. }
  145.    
  146. for (LLSD::array_iterator iter = middle_llsd.beginArray();
  147.  iter != middle_llsd.endArray();++iter)
  148. {
  149. LLSD highlight = *iter;
  150. ret_llsd[retcount++]=highlight;
  151. }
  152.    
  153. for (LLSD::array_iterator iter = end_llsd.beginArray();
  154.  iter != end_llsd.endArray();++iter)
  155. {
  156. LLSD highlight = *iter;
  157. ret_llsd[retcount++]=highlight;
  158. }
  159.    
  160. return ret_llsd;
  161. }
  162. }
  163. }
  164. }
  165. //No patterns found.  Just send back what was passed in.
  166. ret_llsd[0]["text"] =text;
  167. LLSD color_sd = color.getValue();
  168. ret_llsd[0]["color"]=color_sd;
  169. return ret_llsd;
  170. }
  171. bool LLTextParser::parseFullLineHighlights(const std::string &text, LLColor4 *color)
  172. {
  173. for (S32 i=0;i<mHighlights.size();i++)
  174. {
  175. if ((S32)mHighlights[i]["highlight"]==ALL || (S32)mHighlights[i]["condition"]==MATCHES)
  176. {
  177. if (findPattern(text,mHighlights[i]) >= 0 )
  178. {
  179. LLSD color_llsd = mHighlights[i]["color"];
  180. color->setValue(color_llsd);
  181. return TRUE;
  182. }
  183. }
  184. }
  185. return FALSE; //No matches found.
  186. }
  187. std::string LLTextParser::getFileName()
  188. {
  189. std::string path=gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "");
  190. if (!path.empty())
  191. {
  192. path = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "highlights.xml");
  193. }
  194. return path;  
  195. }
  196. LLSD LLTextParser::loadFromDisk()
  197. {
  198. std::string filename=getFileName();
  199. if (filename.empty())
  200. {
  201. llwarns << "LLTextParser::loadFromDisk() no valid user directory." << llendl; 
  202. }
  203. else
  204. {
  205. llifstream file;
  206. file.open(filename.c_str());
  207. if (file.is_open())
  208. {
  209. LLSDSerialize::fromXML(mHighlights, file);
  210. }
  211. file.close();
  212. }
  213. return mHighlights;
  214. }
  215. bool LLTextParser::saveToDisk(LLSD highlights)
  216. {
  217. mHighlights=highlights;
  218. std::string filename=getFileName();
  219. if (filename.empty())
  220. {
  221. llwarns << "LLTextParser::saveToDisk() no valid user directory." << llendl; 
  222. return FALSE;
  223. }
  224. llofstream file;
  225. file.open(filename.c_str());
  226. LLSDSerialize::toPrettyXML(mHighlights, file);
  227. file.close();
  228. return TRUE;
  229. }