Text.cpp 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834
  1. //---Include---
  2. #include "Text.h"
  3. #include <iomanip>
  4. #include <math.h>
  5. #include <sstream>
  6. #ifndef WIN32
  7. # include <string.h>
  8. #endif
  9. #include "Regex.h"
  10. using namespace Framework;
  11. DynamicBuffer::DynamicBuffer(std::function<int(std::stringbuf&)> onAppend)
  12. : std::stringbuf(),
  13. onAppend(onAppend)
  14. {}
  15. int DynamicBuffer::sync()
  16. {
  17. return onAppend(*this);
  18. }
  19. FlushingOStream::FlushingOStream(
  20. DynamicBuffer* buffer, std::function<void()> onDestroy)
  21. : std::ostream(buffer),
  22. onDestroy(onDestroy)
  23. {}
  24. FlushingOStream::FlushingOStream(const Framework::FlushingOStream& stream)
  25. : std::ostream(stream.rdbuf())
  26. {}
  27. FlushingOStream::~FlushingOStream()
  28. {
  29. flush();
  30. onDestroy();
  31. }
  32. Text::Text(char* t, int l)
  33. : ReferenceCounter(),
  34. txt(0),
  35. length(0),
  36. suchGBeg(0),
  37. suchGEnd(0),
  38. precision(-1),
  39. stringWriter(0)
  40. {
  41. length = l;
  42. txt = t; // create new text
  43. }
  44. // Content of the Text class from Text.h
  45. // Constructor
  46. Text::Text()
  47. : ReferenceCounter(),
  48. txt(0),
  49. length(0),
  50. suchGBeg(0),
  51. suchGEnd(0),
  52. precision(-1),
  53. stringWriter(0)
  54. {
  55. setText("");
  56. }
  57. Text::Text(const Text& txt)
  58. : ReferenceCounter(),
  59. txt(0),
  60. length(0),
  61. suchGBeg(0),
  62. suchGEnd(0),
  63. precision(-1),
  64. stringWriter(0)
  65. {
  66. setText(txt, txt.length);
  67. }
  68. Text::Text(const char* t)
  69. : ReferenceCounter(),
  70. txt(0),
  71. length(0),
  72. suchGBeg(0),
  73. suchGEnd(0),
  74. precision(-1),
  75. stringWriter(0)
  76. {
  77. setText(t); // set text
  78. }
  79. Framework::Text::Text(const char* txt, int offset, int length)
  80. : ReferenceCounter(),
  81. txt(0),
  82. length(0),
  83. suchGBeg(0),
  84. suchGEnd(0),
  85. precision(-1),
  86. stringWriter(0)
  87. {
  88. this->length = length;
  89. this->txt = new char[length + 1];
  90. memcpy(this->txt, txt + offset, length);
  91. this->txt[length] = 0;
  92. }
  93. Text::Text(int zahl)
  94. : ReferenceCounter(),
  95. txt(0),
  96. length(0),
  97. suchGBeg(0),
  98. suchGEnd(0),
  99. precision(-1),
  100. stringWriter(0)
  101. {
  102. *this = zahl;
  103. }
  104. // Creates a new Text object with a number as text
  105. // num: The number that should be in the text
  106. Text::Text(double num)
  107. : Text()
  108. {
  109. *this = num;
  110. }
  111. // Creates a new Text object with a number as text
  112. // num: The number that should be in the text
  113. Text::Text(float num)
  114. : Text()
  115. {
  116. *this = num;
  117. }
  118. // Destructor
  119. Text::~Text()
  120. {
  121. if (stringWriter) delete stringWriter;
  122. delete[] txt;
  123. }
  124. void Framework::Text::setTextZ(char* t, int l)
  125. {
  126. delete[] txt; // delete old text
  127. length = l;
  128. txt = t; // create new text
  129. }
  130. void Text::toUpperCase()
  131. {
  132. if (!txt) return;
  133. for (int i = 0; i < length; i++)
  134. {
  135. if (txt[i] >= 'a' && txt[i] <= 'z') txt[i] = (char)(txt[i] - 32);
  136. switch (txt[i])
  137. {
  138. case SpecialCharacters::SMALL_UE:
  139. txt[i] = SpecialCharacters::BIG_UE;
  140. break;
  141. case SpecialCharacters::SMALL_OE:
  142. txt[i] = SpecialCharacters::BIG_OE;
  143. break;
  144. case SpecialCharacters::SMALL_AE:
  145. txt[i] = SpecialCharacters::BIG_AE;
  146. break;
  147. }
  148. }
  149. }
  150. void Text::toLowerCase()
  151. {
  152. if (!txt) return;
  153. for (int i = 0; i < length; i++)
  154. {
  155. if (txt[i] >= 'A' && txt[i] <= 'Z') txt[i] = (char)(txt[i] + 32);
  156. switch (txt[i])
  157. {
  158. case SpecialCharacters::BIG_UE:
  159. txt[i] = SpecialCharacters::SMALL_UE;
  160. break;
  161. case SpecialCharacters::BIG_OE:
  162. txt[i] = SpecialCharacters::SMALL_OE;
  163. break;
  164. case SpecialCharacters::BIG_AE:
  165. txt[i] = SpecialCharacters::SMALL_AE;
  166. break;
  167. }
  168. }
  169. }
  170. // non-constant
  171. void Text::setSuchGrenzen(
  172. char gBeg, char gEnd) // for every search function, does not search between
  173. // the characters gBeg and gEnd
  174. {
  175. suchGBeg = gBeg;
  176. suchGEnd = gEnd;
  177. }
  178. void Text::setText(const char* t) // replaces the text
  179. {
  180. setText(t, textLength(t)); // set text
  181. }
  182. // non-constant
  183. void Text::setText(const char* t, int l) // replaces the text
  184. {
  185. delete[] txt; // delete old text
  186. length = l;
  187. txt = new char[(__int64)length + 1]; // create new text
  188. for (int i = 0; i < length; ++i) // fill text
  189. txt[i] = t[i];
  190. txt[length] = '\0'; // set text end
  191. }
  192. void Text::setText(const Text& t)
  193. {
  194. setText(t, t.getLength()); // set text
  195. }
  196. void Text::append(char c) // appends to the text
  197. {
  198. append(&c, 1);
  199. }
  200. void Text::append(const char* t) // appends to the text
  201. {
  202. int tl = (int)textLength(t); // length of the argument
  203. char* res = new char[(__int64)tl + length + 1]; // create new text
  204. for (int i = 0; i < length; ++i) // fill with current text
  205. res[i] = txt[i];
  206. for (int i = 0; i < tl; ++i) // append argument
  207. res[length + i] = t[i];
  208. res[length + tl] = '\0'; // set text end
  209. setTextZ(res, length + tl); // set text
  210. }
  211. void Text::appendHex(char num) // appends the number in hex to the text
  212. {
  213. char* res = new char[(__int64)length + sizeof(char) * 2 + 1];
  214. for (int i = 0; i < length; ++i)
  215. res[i] = txt[i];
  216. std::stringstream stream;
  217. stream << std::setfill('0') << std::setw((int)sizeof(char) * 2) << std::hex
  218. << (int)num;
  219. std::string str = stream.str();
  220. for (int i = length; i < length + (int)sizeof(char) * 2; ++i)
  221. res[i] = str.c_str()[i - length];
  222. res[length + sizeof(char) * 2] = 0;
  223. setTextZ(res, length + sizeof(char) * 2);
  224. }
  225. void Framework::Text::appendHex(short num)
  226. {
  227. char* res = new char[(__int64)length + sizeof(short) * 2 + 1];
  228. for (int i = 0; i < length; ++i)
  229. res[i] = txt[i];
  230. std::stringstream stream;
  231. stream << std::setfill('0') << std::setw((int)sizeof(short) * 2) << std::hex
  232. << num;
  233. std::string str = stream.str();
  234. for (int i = length; i < length + (int)sizeof(short) * 2; ++i)
  235. res[i] = str.c_str()[i - length];
  236. res[length + sizeof(short) * 2] = 0;
  237. setTextZ(res, length + sizeof(short) * 2);
  238. }
  239. void Text::appendHex(int num) // appends the number in hex to the text
  240. {
  241. char* res = new char[(__int64)length + sizeof(int) * 2 + 1];
  242. for (int i = 0; i < length; ++i)
  243. res[i] = txt[i];
  244. std::stringstream stream;
  245. stream << std::setfill('0') << std::setw((int)sizeof(int) * 2) << std::hex
  246. << num;
  247. std::string str = stream.str();
  248. for (int i = length; i < length + (int)sizeof(int) * 2; ++i)
  249. res[i] = str.c_str()[i - length];
  250. res[length + sizeof(int) * 2] = 0;
  251. setTextZ(res, length + sizeof(int) * 2);
  252. }
  253. void Text::appendHex(__int64 num) // appends the number in hex to the text
  254. {
  255. char* res = new char[(__int64)length + sizeof(__int64) * 2 + 1];
  256. for (int i = 0; i < length; ++i)
  257. res[i] = txt[i];
  258. std::stringstream stream;
  259. stream << std::setfill('0') << std::setw((int)sizeof(__int64) * 2)
  260. << std::hex << num;
  261. std::string str = stream.str();
  262. for (int i = length; i < length + (int)sizeof(__int64) * 2; ++i)
  263. res[i] = str.c_str()[i - length];
  264. res[length + sizeof(__int64) * 2] = 0;
  265. setTextZ(res, length + sizeof(__int64) * 2);
  266. }
  267. void Text::append(const char* t, int l) // appends to the text
  268. { // length of the text
  269. char* res = new char[(__int64)l + length + 1]; // create new text
  270. for (int i = 0; i < length; ++i) // fill with current text
  271. res[i] = txt[i];
  272. for (int i = 0; i < l; ++i) // append argument
  273. res[length + i] = t[i];
  274. res[length + l] = '\0'; // set text end
  275. setTextZ(res, length + l); // set text
  276. }
  277. void Text::append(const Text& t)
  278. {
  279. if (t.getLength() > 0) // check for invalid argument
  280. append(t, t.getLength()); // append text
  281. }
  282. void Text::append(int num)
  283. {
  284. std::stringstream ss;
  285. ss << num;
  286. std::string string = ss.str();
  287. append(string.c_str(), (int)string.length());
  288. }
  289. // Appends a number to the end of the text
  290. // num: The number to convert to text and append at the end
  291. void Text::append(__int64 num)
  292. {
  293. std::stringstream ss;
  294. ss << num;
  295. std::string string = ss.str();
  296. append(string.c_str(), (int)string.length());
  297. }
  298. void Text::append(unsigned int num)
  299. {
  300. std::stringstream ss;
  301. ss << num;
  302. std::string string = ss.str();
  303. append(string.c_str(), (int)string.length());
  304. }
  305. void Text::append(double num)
  306. {
  307. std::stringstream ss;
  308. if (precision >= 0) ss.precision(precision);
  309. ss << std::fixed << num;
  310. std::string string = ss.str();
  311. const char* str = string.c_str();
  312. int len = (int)string.length();
  313. for (int i = len - 1; i > 0; i--)
  314. {
  315. if (str[i] == '0')
  316. len--;
  317. else
  318. {
  319. if (str[i] == '.') len--;
  320. break;
  321. }
  322. }
  323. append(str, len);
  324. }
  325. void Text::append(float num)
  326. {
  327. std::stringstream ss;
  328. if (precision >= 0) ss.precision(precision);
  329. ss << std::fixed << num;
  330. std::string string = ss.str();
  331. const char* str = string.c_str();
  332. int len = (int)string.length();
  333. for (int i = len - 1; i > 0; i--)
  334. {
  335. if (str[i] == '0')
  336. len--;
  337. else
  338. {
  339. if (str[i] == '.') len--;
  340. break;
  341. }
  342. }
  343. append(str, len);
  344. }
  345. //! Returns an ostream that appends all output to this text
  346. FlushingOStream Text::append()
  347. {
  348. if (!stringWriter)
  349. {
  350. stringWriter = new DynamicBuffer([this](std::stringbuf& buf) {
  351. std::string str = buf.str();
  352. this->append(str.c_str(), (int)str.length());
  353. buf.str("");
  354. return 0;
  355. });
  356. }
  357. return FlushingOStream(stringWriter);
  358. }
  359. void Text::insert(int p, char c) // inserts at position p
  360. {
  361. if (p > length || p < 0) // check for invalid argument
  362. return;
  363. char* res = new char[(__int64)length + 2]; // create new text
  364. for (int i = 0; i < p; ++i) // fill text
  365. res[i] = txt[i];
  366. res[p] = c;
  367. for (int i = p; i < length; ++i) // fill text
  368. res[i + 1] = txt[i];
  369. res[length + 1] = '\0'; // set text end
  370. setTextZ(res, length + 1); // set text
  371. }
  372. void Text::insert(int p, const char* t) // inserts at position p
  373. {
  374. insert(p, t, textLength(t)); // insert text
  375. }
  376. void Framework::Text::insert(int p, const char* t, int len)
  377. {
  378. if (p > length || p < 0 || len <= 0) // check for invalid argument
  379. return; // length of argument
  380. char* res = new char[(__int64)len + length + 1]; // create new text
  381. for (int i = 0; i < p; ++i) // fill text
  382. res[i] = txt[i];
  383. for (int i = 0; i < len; ++i) // insert text
  384. res[i + p] = t[i];
  385. for (int i = p; i < length; ++i) // fill text
  386. res[i + len] = txt[i];
  387. res[len + length] = '\0'; // set text end
  388. setTextZ(res, length + len); // set text
  389. }
  390. void Text::insert(int p, const Text& t)
  391. {
  392. insert(p, t, t.getLength()); // insert text
  393. }
  394. void Framework::Text::regexReplace(
  395. const char* regex, const char* replacement, Regex::RegexConfig* config)
  396. {
  397. regexReplace(
  398. regex, [replacement](Regex::Result&) { return replacement; }, config);
  399. }
  400. void Framework::Text::regexReplace(const char* regex,
  401. std::function<Text(Regex::Result&)> replacementFunction,
  402. Regex::RegexConfig* config)
  403. {
  404. auto matcher
  405. = config == 0 ? Regex::parse(regex) : Regex::parse(regex, *config);
  406. if (!matcher) return;
  407. auto result = matcher->match(txt, length);
  408. if (result->getEntryCount() > 0)
  409. {
  410. int replacedLength = 0;
  411. int replacementLength = 0;
  412. Text* replacements = new Text[result->getEntryCount()];
  413. int i = 0;
  414. #ifdef WIN32
  415. # pragma warning(push)
  416. # pragma warning(disable : 6385)
  417. #endif
  418. for (Regex::Result* match : *result)
  419. {
  420. replacedLength += match->getEnd() - match->getStart();
  421. replacements[i] = replacementFunction(*match);
  422. replacementLength += replacements[i].getLength();
  423. i++;
  424. }
  425. int newLength = length - replacedLength + replacementLength;
  426. char* newText = new char[(__int64)newLength + 1];
  427. int pos = 0;
  428. int newPos = 0;
  429. int j = 0;
  430. for (Regex::Result* match : *result)
  431. {
  432. for (int i = 0; i < match->getStart() - pos; i++)
  433. {
  434. newText[newPos + i] = txt[pos + i];
  435. }
  436. newPos += match->getStart() - pos;
  437. pos = match->getEnd();
  438. for (int i = 0; i < replacements[j].getLength(); i++)
  439. {
  440. newText[newPos + i] = replacements[j][i];
  441. }
  442. newPos += replacements[j].getLength();
  443. j++;
  444. }
  445. for (int i = pos; i < getLength(); i++)
  446. {
  447. newText[newPos + i - pos] = txt[i];
  448. }
  449. #ifdef WIN32
  450. # pragma warning(pop)
  451. #endif
  452. newText[newLength] = '\0';
  453. setTextZ(newText, newLength);
  454. delete[] replacements;
  455. }
  456. result->release();
  457. matcher->release();
  458. }
  459. void Text::replace(int p1, int p2, const char* t) // replaces text from p1 to p2
  460. {
  461. replace(p1, p2, t, textLength(t)); // replace text
  462. }
  463. void Framework::Text::replace(int p1, int p2, const char* t, int len)
  464. {
  465. if (p1 > p2)
  466. {
  467. int x = p1; // swap p1 and p2
  468. p1 = p2;
  469. p2 = x;
  470. }
  471. remove(p1, p2); // delete text section from p1 to p2
  472. if (len > 0)
  473. {
  474. insert(p1, t, len); // insert argument at p1
  475. }
  476. }
  477. void Text::replace(int p1, int p2, const Text& t)
  478. {
  479. replace(p1, p2, t, t.getLength()); // replace text
  480. }
  481. void Text::replace(char c1, char c2) // replaces every c1 with c2
  482. {
  483. if (c1 == '\0' || c2 == '\0') // check for invalid argument
  484. return;
  485. if (!has(c1)) // check if c1 exists
  486. return;
  487. int suchGCount = 0;
  488. if (suchGBeg && suchGEnd)
  489. {
  490. for (int i = 0; i < length; ++i) // search text
  491. {
  492. bool b = suchGCount != 0;
  493. if (txt[i] == c1 && !suchGCount) txt[i] = c2; // replace text
  494. if (txt[i] == suchGBeg) ++suchGCount;
  495. if (txt[i] == suchGEnd) --suchGCount;
  496. if (txt[i] == c1 && !suchGCount && b) txt[i] = c2; // replace text
  497. }
  498. }
  499. else
  500. {
  501. for (int i = 0; i < length; ++i) // search text
  502. {
  503. if (txt[i] == c1) txt[i] = c2; // replace text
  504. }
  505. }
  506. }
  507. void Text::replace(const char* t1, const char* t2) // replaces every t1 with t2
  508. {
  509. replace(t1, textLength(t1), t2, textLength(t2)); // replace text
  510. }
  511. void Framework::Text::replace(
  512. const char* t1, int len1, const char* t2, int len2)
  513. {
  514. if (len1 > length || len1 <= 0) // check for invalid argument
  515. return;
  516. if (!has(t1, len1)) // check if t1 exists
  517. return;
  518. int anz = countOf(t1, len1); // count of t1 in text
  519. int* begin = new int[anz];
  520. int* end = new int[anz];
  521. int searchStart = 0;
  522. for (int i = 0; i < anz; ++i) // save positions of t1
  523. {
  524. begin[i] = positionOf(searchStart, t1, len1);
  525. end[i] = begin[i] + len1;
  526. searchStart = end[i];
  527. }
  528. int resl = (length - (anz * len1)) + (anz * len2) + 1; // length of result
  529. char* res = new char[resl]; // create new text
  530. int rep = 0; // stores which t1 we are at
  531. int last = 0; // fill position in txt
  532. int neu = 0; // fill position in res
  533. for (; neu < resl; ++neu) // fill text
  534. {
  535. if (rep < anz && last == begin[rep]) // replace text
  536. {
  537. last = end[rep];
  538. ++rep;
  539. for (int ii = 0; ii < len2; ++ii)
  540. {
  541. if (neu >= resl) break;
  542. res[neu] = t2[ii];
  543. ++neu;
  544. }
  545. if (neu >= resl) break;
  546. --neu;
  547. }
  548. else // copy text
  549. {
  550. res[neu] = txt[last];
  551. ++last;
  552. }
  553. }
  554. res[resl - 1] = '\0'; // set text end
  555. setTextZ(res, resl); // set text
  556. delete[] begin; // free memory
  557. delete[] end;
  558. }
  559. void Text::replace(const Text& t1, const char* t2)
  560. {
  561. replace(t1, t1.getLength(), t2, textLength(t2)); // replace text
  562. }
  563. void Text::replace(const char* t1, const Text& t2)
  564. {
  565. replace(t1, textLength(t1), t2, t2.getLength()); // replace text
  566. }
  567. void Text::replace(const Text& t1, const Text& t2)
  568. {
  569. replace(t1, t1.getLength(), t2, t2.getLength()); // replace text
  570. }
  571. void Text::replace(int index, char c1, char c2) // replaces the i-th c1 with c2
  572. {
  573. if (c1 == '\0' || c2 == '\0' || index < 0) // check for invalid argument
  574. return;
  575. if (!has(c1)) // check if c1 exists
  576. return;
  577. int anz = countOf(c1);
  578. if (index >= anz) // check if an i-th c1 exists
  579. return;
  580. txt[positionOf(c1, index)] = c2;
  581. }
  582. void Text::replace(int index,
  583. const char* t1,
  584. const char* t2) // replaces the i-th t1 with t2
  585. {
  586. replace(index, t1, textLength(t1), t2, textLength(t2)); // replace text
  587. }
  588. void Framework::Text::replace(
  589. int index, const char* t1, int len1, const char* t2, int len2)
  590. {
  591. if (len1 >= length || len1 <= 0 || index < 0) // check for invalid argument
  592. return;
  593. if (!has(t1)) // check if t1 exists
  594. return;
  595. int anz = countOf(t1, len1); // count of t1 in text
  596. if (index >= anz) // check if an i-th t1 exists
  597. return;
  598. int begin = positionOf(index, len1, t1);
  599. int end = begin + len1;
  600. replace(begin, end, t2, len2); // replace
  601. }
  602. void Text::replace(int i, const Text& t1, const char* t2)
  603. {
  604. replace(i, t1, t1.getLength(), t2, textLength(t2)); // replace
  605. }
  606. void Text::replace(int i, const char* t1, const Text& t2)
  607. {
  608. replace(i, t1, textLength(t1), t2, t2.getLength()); // replace
  609. }
  610. void Text::replace(int i, const Text& t1, const Text& t2)
  611. {
  612. replace(i, t1, t1.getLength(), t2,
  613. t2.getLength()); // replace
  614. }
  615. void Text::fillText(
  616. char c, int len) // sets the text to as many c as len is large
  617. {
  618. char* res = new char[(__int64)len + 1];
  619. for (int i = 0; i < len; ++i)
  620. res[i] = c;
  621. res[len] = '\0';
  622. setTextZ(res, len);
  623. }
  624. void Text::remove(int p) // deletes p
  625. {
  626. if (p < 0 || p >= length) // check for invalid argument
  627. return;
  628. char* res = new char[length]; // create new text
  629. for (int i = 0; i < p && i < length; ++i) // fill text
  630. res[i] = txt[i];
  631. for (int i = p + 1; i < length; ++i)
  632. res[i - 1] = txt[i];
  633. res[length - 1] = 0;
  634. setTextZ(res, length - 1); // set text
  635. }
  636. void Text::remove(int p1, int p2) // deletes from p1 to p2 (p2 is kept)
  637. {
  638. if (p1 == p2) return;
  639. if (p1 > p2) // swap p1 and p2
  640. {
  641. int x = p1;
  642. p1 = p2;
  643. p2 = x;
  644. }
  645. if (p1 < 0) // check for invalid argument
  646. p1 = 0;
  647. if (p2 > length) p2 = length;
  648. int resl = length - (p2 - p1); // length of result
  649. char* res = new char[(__int64)resl + 1]; // create new text
  650. memcpy(res, txt, p1);
  651. memcpy(res + p1, txt + p2, length - p2);
  652. res[resl] = '\0'; // set text end
  653. setTextZ(res, resl); // set text
  654. }
  655. void Text::remove(char c) // deletes every c
  656. {
  657. if (!has(c)) // check if c exists
  658. return;
  659. int anz = countOf(c); // count of c
  660. char* res = new char[(__int64)length - anz + 1]; // create new text
  661. int anz2 = 0;
  662. int suchGCount = 0;
  663. for (int i = 0; i < length; ++i) // fill text
  664. {
  665. bool b = suchGCount != 0;
  666. if (txt[i] == c && !suchGCount)
  667. ++anz2;
  668. else
  669. res[i - anz2] = txt[i];
  670. if (txt[i] == suchGBeg) ++suchGCount;
  671. if (txt[i] == suchGEnd) --suchGCount;
  672. if (b)
  673. {
  674. if (txt[i] == c && !suchGCount)
  675. ++anz2;
  676. else
  677. res[i - anz2] = txt[i];
  678. }
  679. }
  680. res[length - anz] = '\0'; // set text end
  681. setTextZ(res, length - anz); // set text
  682. }
  683. void Text::remove(const char* t) // deletes every t
  684. {
  685. remove(t, textLength(t)); // delete text
  686. }
  687. void Framework::Text::remove(const char* t, int len)
  688. {
  689. if (len <= 0 || len > length) // check for invalid argument
  690. return;
  691. if (!has(t, len)) // check if text contains t
  692. return;
  693. int anz = countOf(t, len); // count of t
  694. int* begin = new int[anz];
  695. for (int i = 0; i < anz; ++i) // find start of all t's
  696. begin[i] = positionOf(i, len, t);
  697. int resl = length - (anz * len); // length of result
  698. char* res = new char[(__int64)resl + 1]; // create new text
  699. int del = 0;
  700. for (int i = 0; i < length; ++i) // fill text
  701. {
  702. if (del < anz && i == begin[del]) // skip text
  703. {
  704. i += len - 1;
  705. ++del;
  706. }
  707. else
  708. res[i - (del * len)] = txt[i]; // fill text
  709. }
  710. res[resl] = '\0'; // set text end
  711. setTextZ(res, resl); // set text
  712. delete[] begin;
  713. }
  714. void Text::remove(const Text& t)
  715. {
  716. remove(t, t.getLength()); // delete text
  717. }
  718. void Text::remove(int index, char c)
  719. {
  720. if (index < 0 || !has(c)) // check for invalid argument
  721. return;
  722. int anz = countOf(c); // count of c's
  723. if (index >= anz) // check if an i-th c exists
  724. return;
  725. int pos = positionOf(c, index); // position of the i-th c
  726. if (pos < 0) return;
  727. if (!length) return;
  728. char* res = new char[length]; // create new text
  729. for (int i = 0; i < pos && i < length; ++i) // fill text
  730. res[i] = txt[i];
  731. for (int i = pos + 1; i < length; ++i)
  732. res[i - 1] = txt[i];
  733. res[length - 1] = '\0'; // set text end
  734. setTextZ(res, length - 1); // set text
  735. }
  736. void Text::remove(int index, const char* t) // deletes the i-th t
  737. {
  738. remove(index, t, textLength(t)); // delete text
  739. }
  740. void Framework::Text::remove(int index, const char* t, int len)
  741. {
  742. if (index < 0 || !has(t, len) || len <= 0) // check for invalid argument
  743. return;
  744. int anz = countOf(t, len); // count of t's
  745. if (index >= anz) // check if an i-th t exists
  746. return;
  747. int pos = positionOf(index, len, t); // position of the i-th t
  748. if (pos < 0) return;
  749. if (!length) return;
  750. char* res = new char[(__int64)length - len + 1]; // create new text
  751. for (int i = 0; i < pos && i < length - len + 1; ++i) // fill text
  752. res[i] = txt[i];
  753. for (int i = pos + len; i < length; ++i)
  754. res[i - len] = txt[i];
  755. res[length - len] = '\0'; // set text end
  756. setTextZ(res, length - len); // set text
  757. }
  758. void Text::remove(int i, const Text& t)
  759. {
  760. remove(i, t, t.getLength()); // delete text
  761. }
  762. // Deletes all ' ', '\n', '\r', '\t' until a different character
  763. // pos: The position of the first character
  764. int Text::removeWhitespaceAfter(int pos)
  765. {
  766. int removedLength = 0;
  767. for (int i = pos; i < length; i++)
  768. {
  769. if (txt[i] == ' ' || txt[i] == '\n' || txt[i] == '\r' || txt[i] == '\t')
  770. removedLength++;
  771. else
  772. break;
  773. }
  774. remove(pos, pos + removedLength);
  775. return length;
  776. }
  777. // Deletes all ' ', '\n', '\r', '\t' until a different character
  778. // pos: The position of the first character (starts at pos-1)
  779. int Text::removeWhitespaceBefore(int pos)
  780. {
  781. int length = 0;
  782. for (int i = pos - 1; i >= 0; i--)
  783. {
  784. if (txt[i] == ' ' || txt[i] == '\n' || txt[i] == '\r' || txt[i] == '\t')
  785. length++;
  786. else
  787. break;
  788. }
  789. remove(pos - length, pos);
  790. return length;
  791. }
  792. void Text::setPrecision(int p) // sets the number of decimal places for doubles
  793. {
  794. precision = p;
  795. }
  796. // constant
  797. int Text::getLength() const // returns the text length
  798. {
  799. return length;
  800. }
  801. int Text::getLKick(int pos) const
  802. {
  803. if (txt[pos - 1] == ' ')
  804. {
  805. int ret = 1;
  806. for (; ret < pos && txt[pos - ret - 1] == ' '
  807. && txt[pos - ret - 1] != '\n';
  808. ++ret)
  809. ;
  810. return pos - ret;
  811. }
  812. else
  813. {
  814. int ret = 1;
  815. for (; ret < pos && txt[pos - ret - 1] != ' '
  816. && txt[pos - ret - 1] != '\n';
  817. ++ret)
  818. ;
  819. return pos - ret;
  820. }
  821. }
  822. int Text::getOKick(int pos) const
  823. {
  824. if (!has('\n')) return 0;
  825. int lpos = 0;
  826. while (pos - lpos - 1 > 0 && txt[pos - lpos - 1] != '\n')
  827. ++lpos;
  828. int vllen = 1;
  829. while (pos - lpos - vllen - 1 >= 0 && txt[pos - lpos - vllen - 1] != '\n')
  830. ++vllen;
  831. if (vllen > lpos)
  832. return pos - vllen;
  833. else
  834. return pos - lpos - 1;
  835. }
  836. int Text::getRKick(int pos) const
  837. {
  838. if (txt[pos] == ' ')
  839. {
  840. int ret = 1;
  841. for (; ret + pos < length && txt[pos + ret] == ' '
  842. && txt[pos + ret] != '\n';
  843. ++ret)
  844. ;
  845. return pos + ret;
  846. }
  847. else
  848. {
  849. int ret = 1;
  850. for (; ret + pos < length && txt[pos + ret] != ' '
  851. && txt[pos + ret] != '\n';
  852. ++ret)
  853. ;
  854. return pos + ret;
  855. }
  856. }
  857. int Text::getUKick(int pos) const
  858. {
  859. if (!has('\n')) return length;
  860. int lpos = 0;
  861. while (pos - lpos > 0 && txt[pos - lpos - 1] != '\n')
  862. ++lpos;
  863. int llen = 1;
  864. while (pos + llen - 1 < length && txt[pos + llen - 1] != '\n')
  865. ++llen;
  866. int vllen = 1;
  867. while (
  868. pos + llen + vllen - 1 < length && txt[pos + llen + vllen - 1] != '\n')
  869. ++vllen;
  870. if (vllen == 1) return pos + llen < length ? pos + llen : length;
  871. if (vllen < lpos) return pos + llen + vllen - 1;
  872. return pos + llen + lpos;
  873. }
  874. bool Text::has(const Text& t) const // does the text contain t
  875. {
  876. return has(t, t.getLength()); // check text
  877. }
  878. bool Text::has(const char* t) const
  879. {
  880. return has(t, textLength(t)); // check text
  881. }
  882. bool Framework::Text::has(const char* t, int len) const
  883. {
  884. return has(0, t, len);
  885. }
  886. bool Framework::Text::has(int searchStartIndex, const char* t) const
  887. {
  888. return has(searchStartIndex, t, textLength(t)); // check text
  889. }
  890. bool Framework::Text::has(int searchStartIndex, const char* t, int len) const
  891. {
  892. if (len <= 0
  893. || len > length - searchStartIndex) // check for invalid argument
  894. return 0;
  895. int suchGCount = 0;
  896. for (int i = searchStartIndex; i + len <= length; ++i) // search text
  897. {
  898. bool searched = 0;
  899. if (!suchGCount)
  900. {
  901. bool b = 1;
  902. for (int ii = 0; ii < len; ++ii) // check text
  903. b &= txt[i + ii] == t[ii];
  904. if (b) return 1;
  905. searched = 1;
  906. }
  907. if (txt[i] == suchGBeg) ++suchGCount;
  908. if (txt[i] == suchGEnd) --suchGCount;
  909. if (!suchGCount && !searched)
  910. {
  911. bool b = 1;
  912. for (int ii = 0; ii < len; ++ii) // check text
  913. b &= txt[i + ii] == t[ii];
  914. if (b) return 1;
  915. }
  916. }
  917. return 0;
  918. }
  919. // Checks whether the text contains the content of another text
  920. // t: The text whose content to search for
  921. // return: (true) if the content is found. (false) otherwise
  922. // pos: the position where the string should begin
  923. bool Text::hasAt(int pos, const Text& t) const
  924. {
  925. return hasAt(pos, t, t.getLength()); // check text
  926. }
  927. // Checks whether the text contains a specific string
  928. // t: The string to search for
  929. // return: (true) if the string is found. (false) otherwise
  930. // pos: the position where the string should begin
  931. bool Text::hasAt(int pos, const char* t) const
  932. {
  933. return hasAt(pos, t, textLength(t)); // check text
  934. }
  935. bool Framework::Text::hasAt(int pos, const char* t, int len) const
  936. {
  937. if (len <= 0 || len + pos > length) // check for invalid argument
  938. return 0;
  939. bool b = 1;
  940. for (int i = 0; i < len; ++i) // check text
  941. b &= txt[pos + i] == t[i];
  942. return b;
  943. }
  944. bool Text::has(char c) const // contains c
  945. {
  946. bool ret = 0;
  947. int suchGCount = 0;
  948. for (int i = 0; i < length; ++i) // search
  949. {
  950. bool b = suchGCount != 0;
  951. if (!suchGCount) // check
  952. ret |= txt[i] == c;
  953. if (txt[i] == suchGBeg) ++suchGCount;
  954. if (txt[i] == suchGEnd) --suchGCount;
  955. if (!suchGCount && b) // check
  956. ret |= txt[i] == c;
  957. }
  958. return ret;
  959. }
  960. bool Text::beginnsWith(const char* t) const
  961. {
  962. return hasAt(0, t);
  963. }
  964. bool Text::endsWith(const char* t) const
  965. {
  966. int len = textLength(t);
  967. return hasAt(length - len, t, len);
  968. }
  969. bool Text::isEqual(const char* t) const // checks if the text equals t
  970. {
  971. return isEqual(t, textLength(t)); // check text
  972. }
  973. bool Text::isEqual(const char* t, int len) const // checks if the text equals t
  974. {
  975. if (length != len) // check for invalid argument
  976. return 0;
  977. if (length == -1) return 1;
  978. bool ret = true;
  979. for (int i = 0; i < len; ++i) // check
  980. ret &= txt[i] == t[i];
  981. return ret;
  982. }
  983. bool Text::isEqual(const Text& t) const
  984. {
  985. return isEqual(t, t.getLength()); // check text
  986. }
  987. const char* Text::getText() const // returns the text
  988. {
  989. return txt;
  990. }
  991. int Text::countOf(char c) const // returns the count of c in the text
  992. {
  993. int ret = 0;
  994. int suchGCount = 0;
  995. if (suchGBeg && suchGEnd)
  996. {
  997. for (int i = 0; i < length; ++i) // search
  998. {
  999. bool b = suchGCount != 0;
  1000. ret += txt[i] == c && !suchGCount; // count
  1001. if (txt[i] == suchGBeg) ++suchGCount;
  1002. if (txt[i] == suchGEnd) --suchGCount;
  1003. ret += txt[i] == c && !suchGCount && b; // count
  1004. }
  1005. }
  1006. else
  1007. {
  1008. for (int i = 0; i < length; ++i) // search
  1009. {
  1010. ret += txt[i] == c; // count
  1011. }
  1012. }
  1013. return ret;
  1014. }
  1015. int Text::countOf(const char* t) const // returns the count of t in the text
  1016. {
  1017. return countOf(t, textLength(t)); // check text
  1018. }
  1019. int Framework::Text::countOf(const char* t, int len) const
  1020. {
  1021. if (len <= 0 || len > length) // check for invalid argument
  1022. return 0;
  1023. int ret = 0;
  1024. int suchGCount = 0;
  1025. for (int i = 0; i + len <= length; ++i) // search
  1026. {
  1027. bool b = suchGCount != 0;
  1028. if (!suchGCount)
  1029. {
  1030. bool b = 1;
  1031. for (int ii = 0; ii < len; ++ii) // check
  1032. b &= txt[i + ii] == t[ii];
  1033. if (b) ++ret; // count
  1034. }
  1035. if (txt[i] == suchGBeg) ++suchGCount;
  1036. if (txt[i] == suchGEnd) --suchGCount;
  1037. if (!suchGCount && b)
  1038. {
  1039. bool b = 1;
  1040. for (int ii = 0; ii < len; ++ii) // check
  1041. b &= txt[i + ii] == t[ii];
  1042. if (b) ++ret; // count
  1043. }
  1044. }
  1045. return ret;
  1046. }
  1047. int Text::countOf(const Text& t) const
  1048. {
  1049. return countOf(t, t.getLength()); // check text
  1050. }
  1051. int Text::positionOf(char c) const // returns the position of the first c
  1052. {
  1053. int suchGCount = 0;
  1054. for (int i = 0; i < length; ++i) // search
  1055. {
  1056. bool b = suchGCount != 0;
  1057. if (txt[i] == c && !suchGCount) // check
  1058. return i;
  1059. if (txt[i] == suchGBeg) ++suchGCount;
  1060. if (txt[i] == suchGEnd) --suchGCount;
  1061. if (txt[i] == c && !suchGCount && b) // check
  1062. return i;
  1063. }
  1064. return -1;
  1065. }
  1066. int Text::positionOf(const char* t) const // returns the position of the first t
  1067. {
  1068. return positionOf(textLength(t), t);
  1069. }
  1070. int Framework::Text::positionOf(int len, const char* t) const
  1071. {
  1072. return positionOf(0, t, len);
  1073. }
  1074. int Text::positionOf(int searchStart, const char* t, int len) const
  1075. {
  1076. if (len <= 0 || len > length - searchStart) // check for invalid argument
  1077. return -1;
  1078. int suchGCount = 0;
  1079. for (int i = searchStart; i + len <= length; ++i) // search
  1080. {
  1081. bool b = suchGCount != 0;
  1082. if (!suchGCount)
  1083. {
  1084. bool b = 1;
  1085. for (int ii = 0; ii < len; ++ii) // check
  1086. b &= txt[i + ii] == t[ii];
  1087. if (b) return i;
  1088. }
  1089. if (txt[i] == suchGBeg) ++suchGCount;
  1090. if (txt[i] == suchGEnd) --suchGCount;
  1091. if (!suchGCount && b)
  1092. {
  1093. bool b = 1;
  1094. for (int ii = 0; ii < len; ++ii) // check
  1095. b &= txt[i + ii] == t[ii];
  1096. if (b) return i;
  1097. }
  1098. }
  1099. return -1;
  1100. }
  1101. int Text::positionOf(const Text& t) const
  1102. {
  1103. return positionOf(t.getLength(), t); // check text
  1104. }
  1105. int Text::positionOf(
  1106. char c, int index) const // returns the position of the i-th c
  1107. {
  1108. int ii = 0;
  1109. int suchGCount = 0;
  1110. for (int i = 0; i < length; ++i) // search
  1111. {
  1112. bool b = suchGCount != 0;
  1113. if (txt[i] == c && !suchGCount) // check
  1114. {
  1115. if (ii == index)
  1116. return i;
  1117. else
  1118. ++ii;
  1119. }
  1120. if (txt[i] == suchGBeg) ++suchGCount;
  1121. if (txt[i] == suchGEnd) --suchGCount;
  1122. if (txt[i] == c && !suchGCount && b) // check
  1123. {
  1124. if (ii == index)
  1125. return i;
  1126. else
  1127. ++ii;
  1128. }
  1129. }
  1130. return -1;
  1131. }
  1132. int Text::positionOf(
  1133. const char* t, int index) const // returns the position of the i-th t
  1134. {
  1135. return positionOf(index, textLength(t), t); // check text
  1136. }
  1137. int Framework::Text::positionOf(int index, int len, const char* t) const
  1138. {
  1139. if (len <= 0 || len > length) // check for invalid argument
  1140. return 0;
  1141. int i2 = 0;
  1142. int suchGCount = 0;
  1143. for (int i = 0; i + len <= length; ++i) // search
  1144. {
  1145. bool b = suchGCount != 0;
  1146. if (!suchGCount)
  1147. {
  1148. bool b = 1;
  1149. for (int ii = 0; ii < len; ++ii) // check
  1150. b &= txt[i + ii] == t[ii];
  1151. if (b)
  1152. {
  1153. if (i2 == index)
  1154. return i;
  1155. else
  1156. ++i2;
  1157. }
  1158. }
  1159. if (txt[i] == suchGBeg) ++suchGCount;
  1160. if (txt[i] == suchGEnd) --suchGCount;
  1161. if (!suchGCount && b)
  1162. {
  1163. bool b = 1;
  1164. for (int ii = 0; ii < len; ++ii) // check
  1165. b &= txt[i + ii] == t[ii];
  1166. if (b)
  1167. {
  1168. if (i2 == index)
  1169. return i;
  1170. else
  1171. ++i2;
  1172. }
  1173. }
  1174. }
  1175. return -1;
  1176. }
  1177. int Text::positionOf(const Text& t, int i) const
  1178. {
  1179. return positionOf(i, t.getLength(), t); // check text
  1180. }
  1181. Text* Text::getTeilText(int p1, int p2) const // returns the text from p1 to p2
  1182. {
  1183. if (p1 > p2) // swap p1 and p2
  1184. {
  1185. int x = p1;
  1186. p1 = p2;
  1187. p2 = x;
  1188. }
  1189. if (p1 < 0 || p2 > length) // check for invalid argument
  1190. return new Text("");
  1191. char* cp = new char[(__int64)p2 - p1 + 1]; // create new text
  1192. for (int i = p1; i < p2; ++i) // fill text
  1193. {
  1194. cp[i - p1] = txt[i];
  1195. }
  1196. cp[p2 - p1] = '\0';
  1197. return new Text(cp, p2 - p1); // return text
  1198. }
  1199. Text* Text::getTeilText(int p) const // returns the text from p to the end
  1200. {
  1201. return getTeilText(p, getLength()); // return text
  1202. }
  1203. // calculates the hash code of the text
  1204. int Text::hashCode() const
  1205. {
  1206. int result = 0;
  1207. for (int i = 0; i < length; i++)
  1208. result += (int)pow(txt[i] * 31, length - 1 - i);
  1209. return result;
  1210. }
  1211. // Operators
  1212. Text& Text::operator+=(const int num)
  1213. {
  1214. append(num);
  1215. return *this;
  1216. }
  1217. // Appends a number to the end of the text
  1218. Text& Text::operator+=(const __int64 num)
  1219. {
  1220. append(num);
  1221. return *this;
  1222. }
  1223. Text& Text::operator+=(const double num)
  1224. {
  1225. append(num);
  1226. return *this;
  1227. }
  1228. Text& Text::operator+=(const float num)
  1229. {
  1230. append(num);
  1231. return *this;
  1232. }
  1233. Text& Text::operator+=(const char* txt)
  1234. {
  1235. append(txt);
  1236. return *this;
  1237. }
  1238. Text& Text::operator+=(const Text& txt)
  1239. {
  1240. append(txt, txt.getLength());
  1241. return *this;
  1242. }
  1243. Text& Text::operator=(const int num)
  1244. {
  1245. setText("", 0);
  1246. append(num);
  1247. return *this;
  1248. }
  1249. Text& Text::operator=(const double num)
  1250. {
  1251. setText("", 0);
  1252. append(num);
  1253. return *this;
  1254. }
  1255. Text& Text::operator=(const float num)
  1256. {
  1257. setText("", 0);
  1258. append(num);
  1259. return *this;
  1260. }
  1261. Text& Text::operator=(const char* txt)
  1262. {
  1263. setText(txt);
  1264. return *this;
  1265. }
  1266. Text& Text::operator=(const Text& txt)
  1267. {
  1268. setText(txt, txt.getLength());
  1269. return *this;
  1270. }
  1271. Text::operator const char*() const
  1272. {
  1273. return txt;
  1274. }
  1275. Text::operator int() const
  1276. {
  1277. if (length > 2 && txt[0] == '0' && txt[1] == 'x')
  1278. return TextZuInt((txt + 2), 16);
  1279. return TextZuInt(txt, 10);
  1280. }
  1281. Text::operator __int64() const
  1282. {
  1283. if (length > 2 && txt[0] == '0' && txt[1] == 'x')
  1284. return TextZuInt64((txt + 2), 16);
  1285. return TextZuInt64(txt, 10);
  1286. }
  1287. Text::operator double() const
  1288. {
  1289. return TextZuDouble(txt);
  1290. }
  1291. Text::operator float() const
  1292. {
  1293. return TextZuFloat(txt);
  1294. }
  1295. bool Text::operator>(Text& t) const
  1296. {
  1297. int len2 = t.getLength();
  1298. const char* txt2 = t;
  1299. for (int i = 0; i < length && i < len2; ++i)
  1300. {
  1301. if (txt[i] > txt2[i]) return 1;
  1302. if (txt[i] < txt2[i]) return 0;
  1303. }
  1304. if (length > len2) return 1;
  1305. return 0;
  1306. }
  1307. bool Text::operator<(Text& t) const
  1308. {
  1309. int len2 = t.getLength();
  1310. const char* txt2 = t;
  1311. for (int i = 0; i < length && i < len2; ++i)
  1312. {
  1313. if (txt[i] < txt2[i]) return 1;
  1314. if (txt[i] > txt2[i]) return 0;
  1315. }
  1316. if (length < len2) return 1;
  1317. return 0;
  1318. }
  1319. // Creates a new text consisting of this and t2
  1320. Text Text::operator+(const Text& t2) const
  1321. {
  1322. return Text(*this) += t2;
  1323. }
  1324. // Creates a new text consisting of this and t2
  1325. Text Text::operator+(const char* t2) const
  1326. {
  1327. return Text(*this) += t2;
  1328. }
  1329. // Creates a new text consisting of this and num
  1330. Text Text::operator+(const int num) const
  1331. {
  1332. return Text(*this) += num;
  1333. }
  1334. // Creates a new text consisting of this and num
  1335. Text Text::operator+(const __int64 num) const
  1336. {
  1337. return Text(*this) += num;
  1338. }
  1339. // Creates a new text consisting of this and num
  1340. Text Text::operator+(const double num) const
  1341. {
  1342. return Text(*this) += num;
  1343. }
  1344. // Creates a new text consisting of this and num
  1345. Text Text::operator+(const float num) const
  1346. {
  1347. return Text(*this) += num;
  1348. }
  1349. bool Text::operator==(const Text& right) const
  1350. {
  1351. return isEqual(right, right.getLength());
  1352. }
  1353. Text Text::fromArray(char* arr, int len)
  1354. {
  1355. return Text(arr, len);
  1356. }
  1357. const Text Text::EMPTY = "";
  1358. // Content of the TextReader class
  1359. // Constructor
  1360. // txt: The text to be read. It is not copied but read directly.
  1361. TextReader::TextReader(Text* txt)
  1362. : ReferenceCounter()
  1363. {
  1364. this->txt = txt;
  1365. lPos = 0;
  1366. }
  1367. // Destructor
  1368. TextReader::~TextReader()
  1369. {
  1370. txt->release();
  1371. }
  1372. // Sets the position of the byte to be read next
  1373. // pos: The index of the byte
  1374. // ende: 1 if the index counts from the end of the text. 0 if from the
  1375. // beginning
  1376. void TextReader::setReadPosition(__int64 pos, bool ende)
  1377. {
  1378. int l = txt->getLength();
  1379. lPos = ende ? l - pos : pos;
  1380. if (lPos < 0) lPos = 0;
  1381. if (lPos > l) lPos = l;
  1382. }
  1383. // Reads from the text
  1384. // bytes: An array to be filled with bytes from the text
  1385. // len: How many bytes to read from the text
  1386. void TextReader::read(char* bytes, int len)
  1387. {
  1388. int l = txt->getLength();
  1389. len = (int)MIN(l - lPos, len);
  1390. for (__int64 i = lPos; i < lPos + len; i++)
  1391. bytes[i - lPos] = txt->getText()[i];
  1392. lPos += len;
  1393. }
  1394. // Reads the next line of the text
  1395. // return: The read line as text with line break
  1396. Text* TextReader::readLine()
  1397. {
  1398. if (isEnd()) return 0;
  1399. Text* ret = new Text("");
  1400. __int64 len = txt->getLength();
  1401. for (char c = 0; c != '\n' && lPos < len;)
  1402. {
  1403. read(&c, 1);
  1404. if (c) ret->append(&c, 1);
  1405. }
  1406. return ret;
  1407. }
  1408. // Checks whether the resource has been fully read
  1409. // return 1 if the resource has been fully read. 0 otherwise
  1410. bool TextReader::isEnd() const
  1411. {
  1412. return lPos >= txt->getLength();
  1413. }
  1414. // Returns the index of the byte from the text that would be read next
  1415. // return -1 if an error occurred. Otherwise the position of the read pointer
  1416. __int64 TextReader::getReadPosition() const
  1417. {
  1418. return lPos;
  1419. }
  1420. //! Returns the number of bytes to read
  1421. __int64 TextReader::getSize() const
  1422. {
  1423. return txt->getLength();
  1424. }
  1425. // char* operationen
  1426. int Framework::stringPositionOfChar(const char* string,
  1427. char c,
  1428. int num) // finds the position of the num-th c
  1429. // in string, -1 if not found
  1430. {
  1431. int gef = 0;
  1432. int p = 0;
  1433. for (char cc = *string; *string; ++string)
  1434. {
  1435. if (cc == c)
  1436. {
  1437. if (gef == num)
  1438. return p;
  1439. else
  1440. ++gef;
  1441. }
  1442. ++p;
  1443. }
  1444. return -1;
  1445. }
  1446. int Framework::stringPositionOfString(const char* string,
  1447. char* suche,
  1448. int sBegPos) // finds the position of 'suche' in 'string' starting at
  1449. // position 'sBegPos', -1 if not found
  1450. {
  1451. for (int i = 0; i < sBegPos; ++i)
  1452. {
  1453. if (!*string) return -1;
  1454. ++string;
  1455. }
  1456. int tl = textLength(suche); // length of the argument
  1457. int txl = textLength(string); // length of the text
  1458. if (tl <= 0 || tl > txl) // check for invalid argument
  1459. return -1;
  1460. for (int i = 0; i + tl <= txl; ++i) // search
  1461. {
  1462. bool b = 1;
  1463. for (int ii = 0; ii < tl; ++ii) // check
  1464. if (b) b = string[i + ii] == suche[ii];
  1465. if (b) return i + sBegPos;
  1466. }
  1467. return -1;
  1468. }
  1469. //---Other Functions---
  1470. void Framework::TextKopieren(
  1471. const char* txt) // copies the text to the clipboard
  1472. {
  1473. #ifdef WIN32
  1474. int laen = textLength(txt) + 1;
  1475. if (laen == 1) return;
  1476. HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, laen);
  1477. if (!hMem) return;
  1478. memcpy(GlobalLock(hMem), txt, laen);
  1479. GlobalUnlock(hMem);
  1480. OpenClipboard(0);
  1481. EmptyClipboard();
  1482. SetClipboardData(CF_TEXT, hMem);
  1483. CloseClipboard();
  1484. #endif
  1485. }
  1486. const char* Framework::TextInsert() // returns the text from the clipboard
  1487. {
  1488. #ifdef WIN32
  1489. if (!OpenClipboard(0)) return "";
  1490. HANDLE hClipData = GetClipboardData(CF_TEXT);
  1491. char* cBuffer = (char*)GlobalLock(hClipData);
  1492. GlobalUnlock(hClipData);
  1493. CloseClipboard();
  1494. return cBuffer;
  1495. #else
  1496. return 0;
  1497. #endif
  1498. }
  1499. char Framework::smallOrBig(char c, bool gr)
  1500. {
  1501. int ret = c;
  1502. if (gr)
  1503. {
  1504. if (c >= 'a' && c <= 'z')
  1505. ret -= 32;
  1506. else
  1507. {
  1508. switch (c)
  1509. {
  1510. case SpecialCharacters::CARET:
  1511. return SpecialCharacters::DEGREE_SIGN;
  1512. case '1':
  1513. return '!';
  1514. case '<':
  1515. return '>';
  1516. case '2':
  1517. return '\"';
  1518. case '3':
  1519. return SpecialCharacters::SECTION_SIGN;
  1520. case '4':
  1521. return '$';
  1522. case '5':
  1523. return '%';
  1524. case '6':
  1525. return '&';
  1526. case '7':
  1527. return '/';
  1528. case '8':
  1529. return '(';
  1530. case '9':
  1531. return ')';
  1532. case '0':
  1533. return '=';
  1534. case ',':
  1535. return ';';
  1536. case '.':
  1537. return ':';
  1538. case SpecialCharacters::SZ:
  1539. return '?';
  1540. case '-':
  1541. return '_';
  1542. case SpecialCharacters::ACUTE_ACCENT:
  1543. return '`';
  1544. case '+':
  1545. return '*';
  1546. case '#':
  1547. return '\'';
  1548. case SpecialCharacters::SMALL_UE:
  1549. return SpecialCharacters::BIG_UE;
  1550. case SpecialCharacters::SMALL_OE:
  1551. return SpecialCharacters::BIG_OE;
  1552. case SpecialCharacters::SMALL_AE:
  1553. return SpecialCharacters::BIG_AE;
  1554. }
  1555. }
  1556. }
  1557. else
  1558. {
  1559. if (c >= 'A' && c <= 'Z')
  1560. ret += 32;
  1561. else
  1562. {
  1563. switch (c)
  1564. {
  1565. case SpecialCharacters::DEGREE_SIGN:
  1566. return SpecialCharacters::CARET;
  1567. case '!':
  1568. return '1';
  1569. case '>':
  1570. return '<';
  1571. case '\"':
  1572. return '2';
  1573. case SpecialCharacters::SECTION_SIGN:
  1574. return '3';
  1575. case '$':
  1576. return '4';
  1577. case '%':
  1578. return '5';
  1579. case '&':
  1580. return '6';
  1581. case '/':
  1582. return '7';
  1583. case '(':
  1584. return '8';
  1585. case ')':
  1586. return '9';
  1587. case '=':
  1588. return '0';
  1589. case ';':
  1590. return ',';
  1591. case ':':
  1592. return '.';
  1593. case '?':
  1594. return SpecialCharacters::SZ;
  1595. case '_':
  1596. return '-';
  1597. case '`':
  1598. return SpecialCharacters::ACUTE_ACCENT;
  1599. case '*':
  1600. return '+';
  1601. case '\'':
  1602. return '#';
  1603. case SpecialCharacters::BIG_UE:
  1604. return SpecialCharacters::SMALL_UE;
  1605. case SpecialCharacters::BIG_OE:
  1606. return SpecialCharacters::SMALL_OE;
  1607. case SpecialCharacters::BIG_AE:
  1608. return SpecialCharacters::SMALL_AE;
  1609. }
  1610. }
  1611. }
  1612. return (char)ret;
  1613. }
  1614. bool Framework::isWritable(
  1615. unsigned char zeichen) // checks if zeichen is a printable character
  1616. {
  1617. if (zeichen > 32 && zeichen < 127) return 1;
  1618. if (zeichen == 128 || zeichen == 181 || zeichen == 178 || zeichen == 179)
  1619. return 1;
  1620. if (zeichen > 191 && zeichen < 198) return 1;
  1621. if (zeichen > 199 && zeichen < 208) return 1;
  1622. if (zeichen > 209 && zeichen < 215) return 1;
  1623. if (zeichen > 216 && zeichen < 221) return 1;
  1624. if (zeichen > 222 && zeichen < 230) return 1;
  1625. if (zeichen > 231 && zeichen < 240) return 1;
  1626. if (zeichen > 241 && zeichen < 247) return 1;
  1627. if (zeichen > 248 && zeichen < 253) return 1;
  1628. if (zeichen == ' ' || zeichen == '\t') return 1;
  1629. return 0;
  1630. }
  1631. unsigned int Framework::TextZuInt(
  1632. const char* c, int system) // converts c to int
  1633. {
  1634. if (system == 16) return (unsigned int)strtoul(c, 0, system);
  1635. return (unsigned int)strtol(c, 0, system);
  1636. }
  1637. unsigned int Framework::TextZuInt(const char* c, char** c_ende, int system)
  1638. {
  1639. if (system == 16) return (unsigned int)strtoul(c, c_ende, system);
  1640. return (unsigned int)strtol(c, c_ende, system);
  1641. }
  1642. unsigned __int64 Framework::TextZuInt64(const char* c, int system)
  1643. {
  1644. if (system == 16) return strtoull(c, 0, system);
  1645. return (unsigned __int64)strtoll(c, 0, system);
  1646. }
  1647. unsigned __int64 Framework::TextZuInt64(
  1648. const char* c, char** c_ende, int system)
  1649. {
  1650. if (system == 16) return strtoull(c, c_ende, system);
  1651. return (unsigned __int64)strtoll(c, c_ende, system);
  1652. }
  1653. double Framework::TextZuDouble(const char* c) // converts c to double
  1654. {
  1655. return strtod(c, 0);
  1656. }
  1657. float Framework::TextZuFloat(const char* c) // converts c to float
  1658. {
  1659. return strtof(c, 0);
  1660. }
  1661. double Framework::TextZuDouble(const char* c, char** c_ende)
  1662. {
  1663. return strtod(c, c_ende);
  1664. }
  1665. float Framework::TextZuFloat(const char* c, char** c_ende)
  1666. {
  1667. return strtof(c, c_ende);
  1668. }
  1669. int Framework::textLength(const char* txt) // returns the length of txt
  1670. {
  1671. if (!txt) return 0;
  1672. int ret = 0;
  1673. for (; txt[ret]; ++ret)
  1674. ;
  1675. return ret;
  1676. }