logo

libbulletml

Library of Bullet Markup Language (forked from https://shinh.skr.jp/libbulletml/index_en.html )git clone https://anongit.hacktivis.me/git/libbulletml.git/

ygg.cpp (60446B)


  1. /******************************************************************************
  2. 世界樹 -yggdrasil-
  3. 世界樹モジュールソースファイル
  4. Coded by Wraith in July 14, 2002.
  5. ******************************************************************************/
  6. // Tab幅を4文字に設定して表示させてください。
  7. ///////////////////////////////////////////////////////////////////////////////
  8. //
  9. // ■ ygg.cpp
  10. // http://tricklib.com/cxx/ex/yggdrasil/ygg.cpp
  11. //
  12. // □ 関連ファイル
  13. // 本モジュールのヘッダファイル
  14. // http://tricklib.com/cxx/ex/yggdrasil/ygg.h
  15. // 本モジュールのチュートリアルソースファイル
  16. // http://tricklib.com/cxx/ex/yggdrasil/ygg_test.cpp
  17. // 全ファイルパック
  18. // http://tricklib.com/cxx/ex/yggdrasil/ygg.lzh
  19. // http://tricklib.com/cxx/ex/yggdrasil/ygg.zip
  20. //
  21. // □ リファレンス・サポートページ
  22. // http://tricklib.com/cxx/ex/yggdrasil/
  23. //
  24. // □ ライセンス情報
  25. // http://tricklib.com/license.htm
  26. //
  27. #include "ygg.h"
  28. #include <iterator>
  29. #include <map>
  30. #ifdef __USING_STRINGSTREAM___
  31. # include <sstream>
  32. #else
  33. # include <cstdio>
  34. #endif
  35. /******************************************************************************
  36. □■□■ TrickPalace □■□■
  37. ■□■□ http://www.trickpalace.net/ ■□■□
  38. ******************************************************************************/
  39. #define ARRAY_SIZE(X) (sizeof(X)/sizeof(X[0]))
  40. #define ARRAY_END(X) (X +ARRAY_SIZE(X))
  41. #define AD_LIBTIUM(XXX) if (!(XXX)) ; else (*(XXX))
  42. #define PROMOTION(XXX) XXX = XXX
  43. #define init_stack \
  44. char init_stack_dummy[1]; \
  45. init_stack_dummy[0] = 0;
  46. #if defined(_MSC_VER)
  47. # define tricklib_alloca _alloca
  48. #else
  49. # define tricklib_alloca alloca
  50. #endif
  51. #define get_stack(type, volume) ((type*)tricklib_alloca(volume*sizeof(type)))
  52. //#define AD_LIB(XXX) if (!(XXX)) ; else
  53. //#define AD_LIBTIUM_WHILE(XXX) while(XXX) (XXX)
  54. //#define AD_LIB_WHILE_PROMOTION(XXX) while(XXX) XXX = XXX
  55. /******************************************************************************
  56. □■□■ cppll ML □■□■
  57. ■□■□ http://www.trickpalace.net/cppll/ ■□■□
  58. ******************************************************************************/
  59. namespace yggdrasil {
  60. namespace ygg_utility {
  61. ygg_string ygg_utility::make_indent(int indent) {
  62. if (0 <= indent) {
  63. return make_indent(indent -1) + ygg_term::indent; // return
  64. } else {
  65. return ygg_term::empty; // return
  66. }
  67. }
  68. ygg_string ygg_utility::encode_xml(const ygg_string &X) {
  69. ygg_string X_text = X;
  70. ygg_string_replace(X_text, "&", "&amp;");
  71. ygg_string_replace(X_text, "<", "&lt;");
  72. ygg_string_replace(X_text, ">", "&gt;");
  73. ygg_string_replace(X_text, "=", "&#61;");
  74. // ygg_string_replace(X_text, "\t", "&#9;");
  75. return X_text; // return
  76. }
  77. ygg_string ygg_utility::encode_attribute(const ygg_string &X) {
  78. ygg_string X_text = X;
  79. ygg_string_replace(X_text, "&", "&amp;");
  80. ygg_string_replace(X_text, "<", "&lt;");
  81. ygg_string_replace(X_text, ">", "&gt;");
  82. ygg_string_replace(X_text, "\"", "&quot;");
  83. ygg_string_replace(X_text, "\'", "&apos;"); // &#39;
  84. ygg_string_replace(X_text, "=", "&#61;");
  85. ygg_string_replace(X_text, "\t", "&#9;");
  86. return X_text; // return
  87. }
  88. ygg_string ygg_utility::encode_sox(const ygg_string &X) {
  89. ygg_string X_text = X;
  90. ygg_string_replace(X_text, "&", "&amp;");
  91. ygg_string_replace(X_text, "<", "&lt;");
  92. ygg_string_replace(X_text, ">", "&gt;");
  93. ygg_string_replace(X_text, "=", "&#61;");
  94. ygg_string_replace(X_text, "\t", "&#9;");
  95. return X_text; // return
  96. }
  97. ygg_string ygg_utility::encode_sox(int indent, const ygg_string &X) {
  98. return ygg_utility::encode_sox(make_indent(indent), X); // return
  99. }
  100. ygg_string ygg_utility::encode_sox(const ygg_string &indent, const ygg_string &X) {
  101. ygg_string X_text;
  102. ygg_string buffer = X;
  103. ygg_string::size_type p;
  104. const int return_code_length = ygg_term::return_code.length();
  105. while(ygg_string::npos != (p = buffer.find(ygg_term::return_code))) {
  106. X_text += indent +encode_sox(buffer.substr(0, p)) +ygg_term::return_code;
  107. buffer = buffer.substr(p +return_code_length);
  108. }
  109. X_text += indent +encode_sox(buffer);
  110. return X_text; // return
  111. // return indent +encode_sox(X);
  112. }
  113. #if defined(__BORLANDC__)
  114. # pragma warn -8026
  115. # pragma warn -8027
  116. #endif
  117. ygg_string decode_xml(const ygg_string &X) {
  118. //#define __SIMPLE_XML_CODING__
  119. #ifdef __SIMPLE_XML_CODING__
  120. ygg_string X_text = X;
  121. ygg_string_replace(X_text, "&lt;", "<"),
  122. ygg_string_replace(X_text, "&gt;", ">"),
  123. ygg_string_replace(X_text, "&quot;", "\""),
  124. ygg_string_replace(X_text, "&apos;", "\'"),
  125. ygg_string_replace(X_text, "&#39;", "\'"),
  126. ygg_string_replace(X_text, "&#61;", "="),
  127. ygg_string_replace(X_text, "&#9;", "\t"),
  128. ygg_string_replace(X_text, "&amp;", "&");
  129. return X_text; // return
  130. #else
  131. class decodex {
  132. public:
  133. ygg_string replace;
  134. decodex(const ygg_string source) {
  135. if (0 == source.find("&#")) {
  136. unsigned int code;
  137. if (0 == source.find("&#x")) {
  138. code = strtol(source.substr(3).c_str(), NULL, 16);
  139. } else {
  140. code = strtol(source.substr(2).c_str(), NULL, 10);
  141. }
  142. #ifdef __USING_UTF8__
  143. char utf8[8] = {0}; // ←指定されてない要素もゼロで初期化される。
  144. if (code < 0x80) {
  145. utf8[0] = (unsigned char)code;
  146. } else if (code < 0x800) {
  147. utf8[0] = 0xC0 | (code >> 6);
  148. utf8[1] = 0x80 | 0x3F & code;
  149. } else {
  150. // } else if (code < 0x10000) {
  151. utf8[0] = 0xE0 | (code >> 12);
  152. utf8[1] = 0x80 | 0x3F & (code >> 6);
  153. utf8[2] = 0x80 | 0x3F & code;
  154. // } else if (code < 0x200000) {
  155. // utf8[0] = 0xF0 | (code >> 18);
  156. // utf8[1] = 0x80 | 0x3F & (code >> 12);
  157. // utf8[2] = 0x80 | 0x3F & (code >> 6);
  158. // utf8[3] = 0x80 | 0x3F & code;
  159. // } else if (code < 0x400000) {
  160. // utf8[0] = 0xF8 | (code >> 24);
  161. // utf8[1] = 0x80 | 0x3F & (code >> 18);
  162. // utf8[2] = 0x80 | 0x3F & (code >> 12);
  163. // utf8[3] = 0x80 | 0x3F & (code >> 6);
  164. // utf8[4] = 0x80 | 0x3F & code;
  165. // } else {
  166. // utf8[0] = 0xFC | (code >> 30);
  167. // utf8[1] = 0x80 | 0x3F & (code >> 24);
  168. // utf8[2] = 0x80 | 0x3F & (code >> 18);
  169. // utf8[3] = 0x80 | 0x3F & (code >> 12);
  170. // utf8[4] = 0x80 | 0x3F & (code >> 6);
  171. // utf8[5] = 0x80 | 0x3F & code;
  172. }
  173. replace = utf8;
  174. #else // __USING_UTF8__
  175. replace = "";
  176. # ifdef __ACCEPT_NULLCODE__
  177. do {
  178. replace += (char)(code % 0x100);
  179. code /= 0x100;
  180. } while(code);
  181. # else // __ACCEPT_NULLCODE__
  182. while(code) {
  183. replace += (char)(code % 0x100);
  184. code /= 0x100;
  185. }
  186. # endif // __ACCEPT_NULLCODE__
  187. #endif // __USING_UTF8__
  188. } else {
  189. assert(false);
  190. replace = source;
  191. }
  192. assert(0 < source.find(";"));
  193. }
  194. operator const char * () {
  195. return replace.c_str(); // return
  196. }
  197. };
  198. ygg_string X_text = X;
  199. ygg_string X_search_begin = "&";
  200. ygg_string X_search_end = ";";
  201. ygg_string X_replace;
  202. ygg_string::size_type inc;
  203. ygg_string::size_type p_end;
  204. for(ygg_string::size_type p = 0;
  205. ygg_string::npos != (p = X_text.find(X_search_begin, p));
  206. p += inc) {
  207. if (ygg_string::npos == (p_end = X_text.find(X_search_end, p))) {
  208. break; // break
  209. }
  210. p == X_text.find("&lt;", p) && (X_replace = "<", true) ||
  211. p == X_text.find("&gt;", p) && (X_replace = ">", true) ||
  212. p == X_text.find("&quot;", p) && (X_replace = "\"", true) ||
  213. p == X_text.find("&apos;", p) && (X_replace = "\'", true) ||
  214. p == X_text.find("&amp;", p) && (X_replace = "&", true) ||
  215. p == X_text.find("&#", p) && (X_replace =
  216. decodex(X_text.substr(p, p_end)), true) ||
  217. (X_replace = X_text.substr(p, p_end +1), true); // ←ここ、バグってない?
  218. X_text.replace(p, (p_end -p) +1, X_replace);
  219. inc = X_replace.length();
  220. }
  221. return X_text; // break
  222. #endif
  223. }
  224. #if defined(__BORLANDC__)
  225. # pragma warn .8026
  226. # pragma warn .8027
  227. #endif
  228. ygg_string ygg_utility::decode_attribute(const ygg_string &X) {
  229. return ygg_utility::decode_xml(X); // return
  230. }
  231. ygg_string ygg_utility::decode_sox(int , const ygg_string &X) {
  232. // indent;
  233. return decode_xml(X); // return
  234. }
  235. ygg_node & ygg_utility::format_tree(ygg_node &node, unsigned int max_row_length) {
  236. ygg_string type;
  237. bool is_text_node = ygg_node_type::root == node.get_type();
  238. bool is_simple_element = true;
  239. ygg_node list = ygg_list::create();
  240. for(ygg_iterator i = node[ygg_term::node].begin(); i.is_not_end(); ++i) {
  241. type = i->get_type();
  242. if (ygg_node_type::attribute != type) {
  243. is_simple_element = false;
  244. if (ygg_node_type::text == type) {
  245. is_text_node = true;
  246. } else {
  247. if (!is_text_node) {
  248. list.adopt_node(ygg_text::create().set_value(" "));
  249. }
  250. if (ygg_node_type::element == type && max_row_length < i->get_xml().length()) {
  251. format_tree(*i);
  252. }
  253. is_text_node = false;
  254. }
  255. }
  256. list.adopt_node(*i);
  257. }
  258. if (!is_simple_element && !is_text_node) {
  259. list.adopt_node(ygg_text::create().set_value(" "));
  260. }
  261. node[ygg_term::node].vanish();
  262. node.adopt_node(list);
  263. return node;
  264. }
  265. ygg_string ygg_utility::xml_trim(const ygg_string &X) {
  266. ygg_string X_text = X;
  267. for(ygg_string::size_type p = 0, p_end;
  268. ygg_string::npos != (p = X_text.find_first_of(ygg_term::white_space, p));
  269. p += 1) {
  270. p_end = X_text.find_first_not_of(ygg_term::white_space, p);
  271. X_text.replace(p, (ygg_string::npos != p_end) ? p_end -p: ygg_string::npos, " ");
  272. }
  273. return X_text;
  274. }
  275. ygg_string ygg_utility::both_trim(const ygg_string &X) {
  276. ygg_string X_text = X;
  277. ygg_string::size_type start_pos = X_text.find_first_not_of(ygg_term::white_space);
  278. if (ygg_string::npos == start_pos) {
  279. return "";
  280. }
  281. X_text = X_text.substr(start_pos);
  282. ygg_string::size_type end_pos = X_text.find_last_not_of(ygg_term::white_space);
  283. if (ygg_string::npos != end_pos && end_pos +1 < X_text.length()) {
  284. X_text = X_text.substr(0, end_pos +1);
  285. }
  286. return X_text;
  287. }
  288. ygg_error_code ygg_utility::check_name(const ygg_string &X) {
  289. using namespace ygg_term;
  290. using namespace ygg_error_term;
  291. // 一文字目のチェック
  292. if (ygg_string::npos != ygg_invalid_name_chars_a.find(X.substr(0, 1))) {
  293. return ygg_invalid_name_a;
  294. }
  295. // 二文字目以降のチェック
  296. #if defined(__USING_UNKNOWN__)
  297. if (base_encoding::sjis == get_base_encoding()) {
  298. #endif
  299. #if defined(__USING_UNKNOWN__) || defined(__USING_SJIS__)
  300. for(ygg_string::const_iterator i = X.begin(); i != X.end(); ++i) {
  301. if (0x81 <= (unsigned char)*i && (unsigned char)*i <= 0xFC) {
  302. // 2バイトコードの1バイト目...
  303. ++i;
  304. if (i == X.end() || 0x40 <= (unsigned char)*i && (unsigned char)*i <= 0xFC) {
  305. // 2バイトコードの2バイト目が無い、もしくは2バイト目のコードが取り得る範囲外の値...
  306. return ygg_broken_char;
  307. }
  308. } else {
  309. if (ygg_string::npos != ygg_invalid_name_chars_b.find(*i)) {
  310. return ygg_invalid_name_b;
  311. }
  312. }
  313. }
  314. #endif
  315. #if defined(__USING_UNKNOWN__)
  316. } else {
  317. #endif
  318. #if defined(__USING_UNKNOWN__) || !defined(__USING_SJIS__)
  319. if (ygg_string::npos != ygg_invalid_name_chars_b.find_first_of(X.substr(1))) {
  320. return ygg_invalid_name_b;
  321. }
  322. #endif
  323. #if defined(__USING_UNKNOWN__)
  324. }
  325. #endif
  326. return no_error;
  327. }
  328. // 文字列置換 [ 〆 ]
  329. ygg_string & ygg_utility::ygg_string_replace(
  330. ygg_string &body,
  331. const ygg_string &X_search, const ygg_string &X_replace) {
  332. for(ygg_string::size_type p = ygg_string::npos, search_length = X_search.length();
  333. ygg_string::npos != (p = body.rfind(X_search, p));
  334. p -= search_length) {
  335. body.replace(p, search_length, X_replace);
  336. }
  337. return body; // return
  338. }
  339. ygg_string ygg_utility::create_line(ygg_node X_list, const ygg_string &separator) {
  340. ygg_string line_string;
  341. for(int i = 0; X_list[i].is_valid(); ++i) {
  342. line_string += separator + X_list[i].get_value().get_string();
  343. }
  344. if (separator.length() <= line_string.length()) {
  345. return line_string.substr(separator.length()); // return
  346. } else {
  347. return line_string; // return
  348. }
  349. }
  350. } // namespace ygg_utility
  351. ygg_value & ygg_value::set_int(int X) {
  352. #ifdef __USING_STRINGSTREAM___
  353. std::ostringstream strstr;
  354. strstr << X;
  355. value = strstr.str();
  356. #else
  357. using namespace std;
  358. char buffer[32];
  359. sprintf(buffer, "%d",X);
  360. value = buffer;
  361. #endif
  362. return *this; // return
  363. }
  364. ygg_value & ygg_value::set_double(double X) {
  365. #ifdef __USING_STRINGSTREAM___
  366. std::ostringstream strstr;
  367. strstr << X;
  368. value = strstr.str();
  369. #else
  370. using namespace std;
  371. char buffer[32];
  372. sprintf(buffer, "%f",X);
  373. value = buffer;
  374. #endif
  375. return *this; // return
  376. }
  377. /******************************************************************************
  378. □■□■ cuppa □■□■
  379. ■□■□ http://www.unittest.org/ ■□■□
  380. ******************************************************************************/
  381. using namespace ygg_utility;
  382. //
  383. // ■yggノードホルダ
  384. //
  385. ygg_node & ygg_node::self_exile() {
  386. for(ygg_iterator i = begin(); i.is_not_end(); ++i) {
  387. ygg_node parent = i->get_parent();
  388. assert(ygg_node_type::empty != parent.get_type());
  389. if (ygg_node_type::empty != parent.get_type()) {
  390. parent.exile_node(*i);
  391. }
  392. }
  393. return *this;
  394. }
  395. ygg_node & ygg_node::vanish() {
  396. if (body.is_not_null()) {
  397. // 空ノードではない...
  398. for(ygg_iterator i = begin(); i.is_not_end(); ++i) {
  399. if (i->is_live()) {
  400. // ゴーストではない...
  401. ygg_node parent = i->get_parent();
  402. if (ygg_node_type::empty != parent.get_type()) {
  403. // 親ノードが存在する...
  404. // 親ノードから絶縁する
  405. parent.exile_node(*i);
  406. }
  407. }
  408. }
  409. // ハンドルを手放す(必ずしもこのタイミングでノードが消えてくれるとは限らない)
  410. this->operator=(NULL);
  411. }
  412. return *this; // return
  413. }
  414. ygg_string ygg_node::get_path() const {
  415. if (body.is_null()) {
  416. // 空ノード...
  417. return "/null()"; // return
  418. }
  419. ygg_string path;
  420. ygg_string this_path_name = get_path_name();
  421. ygg_string index;
  422. ygg_node parent = body->get_parent();
  423. if (ygg_node_type::empty != parent.get_type()) {
  424. // 親ノードが存在する...
  425. // 親ノードまでのパスを取得
  426. path = parent.get_path();
  427. if (ygg_term::path_root != path){
  428. path += ygg_term::path_dir;
  429. }
  430. // インデックスの処理
  431. ygg_node X_list = parent[this_path_name];
  432. int size = X_list.get_size();
  433. assert(0 < size);
  434. if (1 < size) {
  435. for(int i = 0; i < size; ++i) {
  436. if (this->body == X_list[i].body) {
  437. char number[2];
  438. number[0] = '0' +i, number[1] = '\x0';
  439. index = ygg_term::path_parenthesis_begin
  440. +number
  441. +ygg_term::path_parenthesis_end;
  442. break; // break
  443. }
  444. assert(i < size -1);
  445. }
  446. assert(0 < index.length());
  447. }
  448. } else {
  449. // 親ノードが存在しない...
  450. path = ygg_term::path_root;
  451. }
  452. path += this_path_name +index;
  453. return path; // return
  454. }
  455. ygg_node & ygg_node::purge() {
  456. // 除霊
  457. if (!is_live()) {
  458. return vanish(); // return
  459. }
  460. // ノード種別の取得
  461. ygg_string type = get_type();
  462. if (type == ygg_node_type::empty ||
  463. type == ygg_node_type::comment ||
  464. type == ygg_node_type::attribute) {
  465. // 既に空 もしくは コメントノード・属性ノード(弄りようがないので放置)
  466. return *this; // return
  467. }
  468. if (ygg_node_type::text == type) {
  469. // テキストノード...
  470. if (ygg_term::empty != get_value().get_string()) {
  471. return *this; // return
  472. } else {
  473. // 内容が空の場合はバニッシュ
  474. return vanish(); // return
  475. }
  476. }
  477. if (type == ygg_node_type::root ||
  478. type == ygg_node_type::element) {
  479. // 要素ノード...
  480. ygg_node pre_node;
  481. ygg_node children = operator[](ygg_term::node);
  482. for(int i = 0; children[i].is_valid(); children[i++].purge()) {
  483. if (ygg_node_type::text == pre_node.get_type() &&
  484. ygg_node_type::text == children[i].get_type()) {
  485. pre_node.set_value(pre_node.get_value().get_string() +children[i].get_value().get_string());
  486. children[i].set_value(ygg_term::empty);
  487. }
  488. pre_node = children[i];
  489. }
  490. return *this; // return
  491. }
  492. if (ygg_node_type::list == type) {
  493. // ノードリスト...
  494. ygg_node children = operator[](ygg_term::node);
  495. for(int i = 0; children[i].is_valid(); children[i++].purge());
  496. switch(get_size()) {
  497. case 0:
  498. return vanish(); // return
  499. case 1:
  500. return *this = operator[](0); // return
  501. }
  502. return *this; // return
  503. }
  504. assert(false);
  505. return *this; // return
  506. }
  507. ygg_node ygg_node::enum_node(const ygg_string &path_where) {
  508. ygg_node node_list = ygg_list::create();
  509. if (match_path(path_where)) {
  510. node_list.adopt_node(*this);
  511. }
  512. ygg_node children = (*this)[ygg_term::node];
  513. for(int i = 0; children[i].is_valid(); ++i) {
  514. node_list.adopt_node(children[i].enum_node(path_where));
  515. }
  516. return node_list.purge(); // return
  517. }
  518. //
  519. // ■yggノードクラス
  520. //
  521. ygg_node ygg_node_body::operator[](const ygg_string &path) {
  522. if ("." == path) {
  523. return this; // return
  524. } else {
  525. return NULL; // return
  526. }
  527. }
  528. ygg_node ygg_node_body::operator[](const unsigned index) {
  529. if (0 == index) {
  530. return this; // return
  531. } else {
  532. return NULL; // return
  533. }
  534. }
  535. const int ygg_node_body::get_size() const {
  536. return 1;
  537. }
  538. ygg_iterator ygg_node_body::begin() {
  539. assert(false);
  540. return *(ygg_iterator*)(void*)NULL; // return
  541. }
  542. ygg_iterator ygg_node_body::end() {
  543. assert(false);
  544. return *(ygg_iterator*)(void*)NULL; // return
  545. }
  546. ygg_reverse_iterator ygg_node_body::rbegin() {
  547. assert(false);
  548. return *(ygg_reverse_iterator*)(void*)NULL; // return
  549. }
  550. ygg_reverse_iterator ygg_node_body::rend() {
  551. assert(false);
  552. return *(ygg_reverse_iterator*)(void*)NULL; // return
  553. }
  554. ygg_const_iterator ygg_node_body::begin() const {
  555. assert(false);
  556. return *(ygg_const_iterator*)(void*)NULL; // return
  557. }
  558. ygg_const_iterator ygg_node_body::end() const {
  559. assert(false);
  560. return *(ygg_const_iterator*)(void*)NULL; // return
  561. }
  562. ygg_const_reverse_iterator ygg_node_body::rbegin() const {
  563. assert(false);
  564. return *(ygg_const_reverse_iterator*)(void*)NULL; // return
  565. }
  566. ygg_const_reverse_iterator ygg_node_body::rend() const {
  567. assert(false);
  568. return *(ygg_const_reverse_iterator*)(void*)NULL; // return
  569. }
  570. bool ygg_node_body::match_path(const ygg_string &) const {
  571. return false; // return
  572. }
  573. void ygg_node_body::set_name(const ygg_string &) {
  574. assert(false);
  575. }
  576. void ygg_node_body::set_value(const ygg_string &) {
  577. assert(false);
  578. }
  579. void ygg_node_body::adopt_node(ygg_node) {
  580. assert(false);
  581. }
  582. void ygg_node_body::exile_node(ygg_node) {
  583. assert(false);
  584. }
  585. #ifdef _DEBUG
  586. bool ygg_node_body::assert_other(const ygg_node &) const {
  587. return true; // return
  588. }
  589. #endif
  590. //
  591. // ■yggゴーストクラス
  592. //
  593. ygg_node ygg_ghost::get_life() const {
  594. ygg_node life = parent->operator[](path);
  595. if (life.is_live()) {
  596. return life; // return
  597. } else {
  598. return NULL; // return
  599. }
  600. }
  601. ygg_node ygg_ghost::realize() const {
  602. ygg_node life = get_life();
  603. if (life.is_live()) {
  604. return life; // return
  605. }
  606. ygg_string::size_type p;
  607. ygg_string parent_path = path;
  608. while (0 < parent_path.length() && ygg_term::path_dir == parent_path.substr(p = parent_path.length() -1, 1)) {
  609. PROMOTION(parent_path).substr(0, p);
  610. }
  611. ygg_string::size_type px = 0;
  612. ygg_string::size_type this_p = 0;
  613. ygg_string this_path = parent_path;
  614. ygg_string xi[] = {
  615. ygg_term::path_dir,
  616. ygg_term::attribute_prefix,
  617. ygg_term::path_parenthesis_begin,
  618. ygg_term::path_parenthesis_end};
  619. for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) {
  620. while(ygg_string::npos != (p = parent_path.find(*i, this_p))) {
  621. px = p;
  622. this_p = px +1;
  623. this_path = parent_path.substr(this_p);
  624. }
  625. }
  626. if (ygg_term::empty == this_path) {
  627. assert(false); // return
  628. return parent;
  629. }
  630. if (ygg_term::attribute_prefix == parent_path.substr(px, 1)) {
  631. life = ygg_attribute::create().set_name(this_path);
  632. } else if (ygg_term::comment_node == this_path) {
  633. life = ygg_comment::create();
  634. } else {
  635. life = ygg_element::create().set_name(this_path);
  636. }
  637. parent_path = parent_path.substr(0, px);
  638. while (0 < parent_path.length() && ygg_term::path_dir == parent_path.substr(p = parent_path.length() -1, 1)) {
  639. PROMOTION(parent_path).substr(0, p);
  640. }
  641. (*parent)[parent_path].adopt_node(life);// parent->operator[](parent_path).adopt_node(life);
  642. return life; // return
  643. }
  644. bool ygg_ghost::is_live() const {
  645. return false; // return
  646. }
  647. ygg_string ygg_ghost::get_type() const {
  648. return get_life().get_type(); // return
  649. }
  650. ygg_string ygg_ghost::get_name() const {
  651. return get_life().get_name(); // return
  652. }
  653. ygg_string ygg_ghost::get_value() const {
  654. return get_life().get_value().get_string(); // return
  655. }
  656. ygg_string ygg_ghost::get_text() const {
  657. return get_life().get_text(); // return
  658. }
  659. ygg_string ygg_ghost::get_xml(const ygg_string &indent) const {
  660. return get_life().get_xml(indent); // return
  661. }
  662. ygg_string ygg_ghost::get_xml_attribute() const {
  663. return get_life().get_xml_attribute(); // return
  664. }
  665. ygg_string ygg_ghost::get_sox(const ygg_string &indent) const {
  666. return get_life().get_sox(indent); // return
  667. }
  668. ygg_node ygg_ghost::operator[](const ygg_string &X_path) {
  669. ygg_string child_path = path;
  670. if (ygg_term::path_dir != path.substr(path.length() -1)) {
  671. child_path += ygg_term::path_dir;
  672. }
  673. child_path += X_path;
  674. return ygg_ghost::create(parent, child_path); // return
  675. }
  676. ygg_node ygg_ghost::operator[](const unsigned index) {
  677. return get_life().operator[](index); // return
  678. }
  679. const int ygg_ghost::get_size() const {
  680. return get_life().get_size(); // return
  681. }
  682. bool ygg_ghost::match_path(const ygg_string &path) const {
  683. return get_life().match_path(path); // return
  684. }
  685. void ygg_ghost::set_name(const ygg_string &X) {
  686. realize().set_name(X);
  687. }
  688. void ygg_ghost::set_value(const ygg_string &X) {
  689. realize().set_value(X);
  690. }
  691. void ygg_ghost::adopt_node(ygg_node X) {
  692. realize().adopt_node(X);
  693. }
  694. void ygg_ghost::exile_node(ygg_node X) {
  695. get_life().exile_node(X);
  696. }
  697. ygg_node ygg_ghost::clone() const {
  698. return create(NULL, path); // return
  699. }
  700. #ifdef _DEBUG
  701. bool ygg_ghost::assert_other(const ygg_node &X) const {
  702. return get_life().assert_other(X); // return
  703. }
  704. #endif
  705. //
  706. // ■yggコメントクラス
  707. //
  708. bool ygg_comment::is_live() const {
  709. return true; // return
  710. }
  711. ygg_string ygg_comment::get_type() const {
  712. return ygg_node_type::comment; // return
  713. }
  714. ygg_string ygg_comment::get_name() const {
  715. return ygg_term::comment_node; // return
  716. }
  717. ygg_string ygg_comment::get_value() const {
  718. return value; // return
  719. }
  720. ygg_string ygg_comment::get_text() const {
  721. return ygg_term::empty; // return
  722. }
  723. ygg_string ygg_comment::get_xml(const ygg_string &) const {
  724. ygg_string X_text = value;
  725. ygg_utility::ygg_string_replace(X_text, "-->", "--&gt;");
  726. return ygg_term::comment_lead +X_text +ygg_term::comment_trail; // return
  727. }
  728. ygg_string ygg_comment::get_xml_attribute() const {
  729. return ygg_term::empty; // return
  730. }
  731. ygg_string ygg_comment::get_sox(const ygg_string & indent) const {
  732. ygg_string X_text;
  733. ygg_string buffer = value;
  734. ygg_string::size_type p;
  735. int return_code_length = ygg_term::return_code.length();
  736. if (ygg_string::npos != (p = buffer.find(ygg_term::return_code))) {
  737. X_text += indent +buffer.substr(0, p) +ygg_term::comment_trail +ygg_term::return_code;
  738. buffer = buffer.substr(p +return_code_length);
  739. while(ygg_string::npos != (p = buffer.find(ygg_term::return_code))) {
  740. X_text += indent +buffer.substr(0, p) +ygg_term::return_code;
  741. buffer = buffer.substr(p +return_code_length);
  742. }
  743. X_text += indent +buffer +ygg_term::return_code;
  744. } else {
  745. X_text = indent +buffer +ygg_term::comment_trail +ygg_term::return_code;
  746. }
  747. return X_text; // return
  748. // return indent +value +ygg_term::comment_trail +ygg_term::return_code;
  749. }
  750. bool ygg_comment::match_path(const ygg_string &path) const {
  751. return
  752. path == ygg_term::node ||
  753. path == ygg_term::comment_node; // return
  754. }
  755. void ygg_comment::set_value(const ygg_string &X) {
  756. value = X;
  757. }
  758. ygg_node ygg_comment::clone() const {
  759. return create().set_value(value); // return
  760. }
  761. //
  762. // ■yggテキストクラス
  763. //
  764. bool ygg_text::is_live() const {
  765. return true; // return
  766. }
  767. ygg_string ygg_text::get_type() const {
  768. return ygg_node_type::text; // return
  769. }
  770. ygg_string ygg_text::get_name() const {
  771. return ygg_term::text_node; // return
  772. }
  773. ygg_string ygg_text::get_value() const {
  774. return value; // return
  775. }
  776. ygg_string ygg_text::get_text() const {
  777. return value; // return
  778. }
  779. ygg_string ygg_text::get_xml(const ygg_string &) const {
  780. return encode_xml(xml_trim(value)); // return
  781. }
  782. ygg_string ygg_text::get_xml_attribute() const {
  783. return ygg_term::empty; // return
  784. }
  785. ygg_string ygg_text::get_sox(const ygg_string & indent) const {
  786. return encode_sox(indent, value) +ygg_term::return_code; // return
  787. }
  788. bool ygg_text::match_path(const ygg_string &path) const {
  789. return
  790. path == ygg_term::node ||
  791. path == ygg_term::text_node; // return
  792. }
  793. void ygg_text::set_value(const ygg_string &X) {
  794. value = X;
  795. }
  796. ygg_node ygg_text::clone() const {
  797. return create().set_value(value); // return
  798. }
  799. //
  800. // ■ygg属性クラス
  801. //
  802. bool ygg_attribute::is_live() const {
  803. return true; // return
  804. }
  805. ygg_string ygg_attribute::get_type() const {
  806. return ygg_node_type::attribute; // return
  807. }
  808. ygg_string ygg_attribute::get_name() const {
  809. assert(name == encode_xml(name));
  810. assert(name == encode_attribute(name));
  811. return name; // return
  812. }
  813. ygg_string ygg_attribute::get_value() const {
  814. return value; // return
  815. }
  816. ygg_string ygg_attribute::get_text() const {
  817. return ygg_term::empty; // return
  818. }
  819. ygg_string ygg_attribute::get_xml(const ygg_string &) const {
  820. assert(name == encode_xml(name));
  821. assert(name == encode_attribute(name));
  822. return ygg_term::empty; // return
  823. }
  824. ygg_string ygg_attribute::get_xml_attribute() const {
  825. assert(name == encode_xml(name));
  826. assert(name == encode_attribute(name));
  827. return " " +name +"=\"" +encode_attribute(value) +"\""; // return
  828. }
  829. ygg_string ygg_attribute::get_sox(const ygg_string & indent) const {
  830. return indent +name
  831. + "=" +encode_attribute(value) +ygg_term::return_code; // return
  832. }
  833. bool ygg_attribute::match_path(const ygg_string &path) const {
  834. return
  835. path == ygg_term::node ||
  836. path == ygg_term::attribute_node ||
  837. path == ygg_term::attribute_prefix +ygg_term::wildcard ||
  838. path == ygg_term::attribute_prefix +name; // return
  839. }
  840. void ygg_attribute::set_name(const ygg_string &X) {
  841. name = X;
  842. }
  843. void ygg_attribute::set_value(const ygg_string &X) {
  844. value = X;
  845. }
  846. ygg_node ygg_attribute::clone() const {
  847. return create().set_name(name).set_value(value); // return
  848. }
  849. //
  850. // ■yggプロトリストクラス
  851. //
  852. bool ygg_proto_list::is_live() const {
  853. return true; // return
  854. }
  855. ygg_string ygg_proto_list::get_value() const {
  856. return get_text(); // return
  857. }
  858. // [ 〆 ]
  859. ygg_string ygg_proto_list::get_text() const {
  860. ygg_string X_text;
  861. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  862. X_text += i->get_text();
  863. }
  864. return X_text; // return
  865. }
  866. // [ 〆 ]
  867. ygg_string ygg_proto_list::get_xml(const ygg_string & indent) const {
  868. ygg_string X_text, X_part, X_core;
  869. bool gap = false;
  870. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  871. X_part = i->get_xml(indent);
  872. if (0 < X_part.length()) {
  873. X_core = both_trim(X_part);
  874. if (0 < X_core.length()) {
  875. if (!gap && 0 < X_part.find_first_not_of(ygg_term::white_space)) {
  876. X_core = ygg_term::return_code +indent +X_core;
  877. }
  878. ygg_string::size_type end_pos = X_part.find_last_not_of(ygg_term::white_space);
  879. if (ygg_string::npos != end_pos && end_pos +1 < X_part.length()) {
  880. gap = true;
  881. X_core += ygg_term::return_code +indent;
  882. } else {
  883. gap = false;
  884. }
  885. } else {
  886. if (!gap) {
  887. gap = true;
  888. X_core += ygg_term::return_code +indent;
  889. }
  890. }
  891. X_text += X_core;
  892. }
  893. }
  894. return X_text; // return
  895. }
  896. // [ 〆 ]
  897. ygg_string ygg_proto_list::get_xml_attribute() const {
  898. ygg_string X_text;
  899. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  900. X_text += i->get_xml_attribute();
  901. }
  902. return X_text; // return
  903. }
  904. // [ 〆 ]
  905. ygg_string ygg_proto_list::get_sox(const ygg_string & indent) const {
  906. ygg_string X_text;
  907. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  908. X_text += i->get_sox(indent);
  909. }
  910. return X_text; // return
  911. }
  912. void ygg_proto_list::adopt_node(ygg_node X) {
  913. adopt_child(X);
  914. }
  915. void ygg_proto_list::exile_node(ygg_node X) {
  916. exile_child(X);
  917. }
  918. // リストへのノード追加 [ 〆 ]
  919. ygg_proto_list * ygg_proto_list::adopt_child(ygg_node X_node) {
  920. for(int i = 0; X_node[i].is_valid(); ++i) {
  921. #ifdef _DEBUG
  922. assert_other(X_node);
  923. #endif
  924. body.insert(body.end(), X_node[i]);
  925. }
  926. return this; // return
  927. }
  928. // リストからノード追加削除 [ 〆 ]
  929. ygg_proto_list * ygg_proto_list::exile_child(ygg_node X_node) {
  930. for(int i = 0; X_node[i].is_valid(); ++i) {
  931. body.remove(X_node[i]);
  932. }
  933. return this; // return
  934. }
  935. #ifdef _DEBUG
  936. bool ygg_proto_list::assert_other(const ygg_node &X) const {
  937. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  938. if (!i->assert_other(X)) {
  939. return false; // return
  940. }
  941. }
  942. return (const ygg_node_body*)this != (const ygg_node_body*)X.body; // return
  943. }
  944. #endif
  945. //
  946. // ■yggリストクラス
  947. //
  948. ygg_string ygg_list::get_type() const {
  949. return ygg_node_type::list; // return
  950. }
  951. ygg_string ygg_list::get_name() const {
  952. // return ygg_term::list_node;
  953. return ygg_term::empty; // return
  954. }
  955. // [ 〆 ]
  956. ygg_node ygg_list::operator[](const ygg_string &path) {
  957. if (ygg_term::path_last_index == path) {
  958. return *body.rbegin();
  959. }
  960. ygg_node X_list = ygg_list::create();
  961. for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) {
  962. X_list.adopt_node(i->operator[](path));
  963. }
  964. switch(X_list.get_size()) {
  965. case 0:
  966. return NULL; // return
  967. case 1:
  968. return X_list[0]; // return
  969. default:
  970. return X_list; // return
  971. }
  972. }
  973. // [ 〆 ]
  974. ygg_node ygg_list::operator[](const unsigned index) {
  975. if (index < body.size()) {
  976. ygg_list_type::iterator i = body.begin();
  977. std::advance(i, index);
  978. return *i; // return
  979. } else {
  980. return NULL; // return
  981. }
  982. }
  983. const int ygg_list::get_size() const {
  984. return body.size(); // return
  985. }
  986. ygg_iterator ygg_list::begin() {
  987. return ygg_iterator(this, body.begin()); // return
  988. }
  989. ygg_iterator ygg_list::end() {
  990. return ygg_iterator(this, body.end()); // return
  991. }
  992. ygg_reverse_iterator ygg_list::rbegin() {
  993. return ygg_reverse_iterator(get_shell(), body.rbegin()); // return
  994. }
  995. ygg_reverse_iterator ygg_list::rend() {
  996. return ygg_reverse_iterator(get_shell(), body.rend()); // return
  997. }
  998. ygg_const_iterator ygg_list::begin() const {
  999. return ygg_const_iterator(get_shell(), body.begin()); // return
  1000. }
  1001. ygg_const_iterator ygg_list::end() const {
  1002. return ygg_const_iterator(get_shell(), body.end()); // return
  1003. }
  1004. ygg_const_reverse_iterator ygg_list::rbegin() const {
  1005. return ygg_const_reverse_iterator(get_shell(), body.rbegin()); // return
  1006. }
  1007. ygg_const_reverse_iterator ygg_list::rend() const {
  1008. return ygg_const_reverse_iterator(get_shell(), body.rend()); // return
  1009. }
  1010. bool ygg_list::match_path(const ygg_string &path) const {
  1011. assert(false);
  1012. //assert(("ygg_list::match_path が呼ばれるようなことはないはず。どっかにバグにがあると思われる。", false));
  1013. return
  1014. path == ygg_term::node ||
  1015. path == ygg_term::list_node; // return
  1016. }
  1017. ygg_node ygg_list::clone() const {
  1018. ygg_node X_clone = create();
  1019. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  1020. X_clone.adopt_node(i->clone());
  1021. }
  1022. return X_clone; // return
  1023. }
  1024. //
  1025. // ■ygg基底クラス
  1026. //
  1027. ygg_string ygg_root::get_type() const {
  1028. return ygg_node_type::root; // return
  1029. }
  1030. ygg_string ygg_root::get_name() const {
  1031. return ygg_term::empty; // return
  1032. }
  1033. // [ 〆 ]
  1034. ygg_node ygg_root::operator[](const ygg_string &path) {
  1035. assert(1 == ygg_term::path_dir.length());
  1036. assert(1 == ygg_term::attribute_prefix.length());
  1037. assert(1 == ygg_term::path_parenthesis_begin.length());
  1038. assert(1 == ygg_term::path_parenthesis_end.length());
  1039. if (ygg_term::empty == path || ygg_term::path_this == path) {
  1040. return this; // return
  1041. }
  1042. if (ygg_term::node == path) {
  1043. ygg_node X_list = ygg_list::create();
  1044. for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) {
  1045. X_list.adopt_node(*i);
  1046. }
  1047. return X_list; // return
  1048. }
  1049. if (0 == path.find(ygg_term::path_wherever)) {
  1050. return operator[](ygg_term::path_root).enum_node(path.substr(ygg_term::path_wherever.length()));
  1051. // return
  1052. }
  1053. if (0 == path.find(ygg_term::path_parent)) {
  1054. ygg_node &X_parent = get_parent();
  1055. if (ygg_node(NULL) != X_parent) {
  1056. return X_parent.operator[](path.substr(1)); // return
  1057. } else {
  1058. return NULL; // return
  1059. }
  1060. }
  1061. if (0 == path.find(ygg_term::path_this)) {
  1062. if (0 == path.find(ygg_term::path_this__wherever)) {
  1063. return get_shell().enum_node(path.substr(ygg_term::path_this__wherever.length()));
  1064. // return
  1065. } else if (0 == path.find(ygg_term::path_this_element)) {
  1066. return operator[](path.substr(ygg_term::path_this_element.length()));
  1067. // return
  1068. } else {
  1069. return operator[](path.substr(ygg_term::path_this.length()));
  1070. // return
  1071. }
  1072. }
  1073. if (0 == path.find(ygg_term::path_dir)) {
  1074. ygg_node &X_parent = get_parent();
  1075. if (ygg_node(NULL) != X_parent) {
  1076. return X_parent.operator[](path);
  1077. // return
  1078. } else {
  1079. return operator[](path.substr(ygg_term::path_dir.length()));
  1080. // return
  1081. }
  1082. }
  1083. ygg_string current_path = path;
  1084. ygg_string next_term = ygg_term::empty;
  1085. if (0 != current_path.find(ygg_term::attribute_prefix)) {
  1086. ygg_string::size_type p;
  1087. ygg_string xi[] = {
  1088. ygg_term::path_dir,
  1089. ygg_term::attribute_prefix,
  1090. ygg_term::path_parenthesis_begin,
  1091. ygg_term::path_parenthesis_end};
  1092. for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) {
  1093. if (ygg_string::npos != (p = current_path.find(*i))) {
  1094. next_term = *i;
  1095. current_path = current_path.substr(0, p);
  1096. }
  1097. }
  1098. }
  1099. ygg_node X_list = ygg_list::create();
  1100. for(ygg_list_type::iterator i = body.begin(); i != body.end(); ++i) {
  1101. if (i->match_path(current_path)) {
  1102. X_list.adopt_node(*i);
  1103. }
  1104. }
  1105. if (ygg_term::path_parenthesis_begin == next_term) {
  1106. assert(ygg_string::npos != path.find(next_term));
  1107. ygg_string index_string = path.substr(path.find(next_term) +1);
  1108. if (0 == index_string.find(ygg_term::path_last_index)) {
  1109. X_list = *X_list.rbegin();
  1110. } else {
  1111. int index = atoi(index_string.c_str());
  1112. X_list = X_list[index];
  1113. }
  1114. assert(ygg_string::npos != path.find(ygg_term::path_parenthesis_end));
  1115. current_path = path.substr(path.find(ygg_term::path_parenthesis_end) +1);
  1116. next_term = ygg_term::empty;
  1117. ygg_string::size_type p;
  1118. ygg_string xi[] = {
  1119. ygg_term::path_dir,
  1120. ygg_term::attribute_prefix};
  1121. for(ygg_string *i = xi; i < ARRAY_END(xi); ++i) {
  1122. if (ygg_string::npos != (p = current_path.find(*i))) {
  1123. next_term = *i;
  1124. current_path = current_path.substr(0, p);
  1125. }
  1126. }
  1127. }
  1128. if (ygg_term::empty != next_term) {
  1129. ygg_string next_path = path;
  1130. if (ygg_term::path_dir != next_term) {
  1131. next_path = next_path.substr(next_path.find(next_term));
  1132. } else {
  1133. next_path = next_path.substr(next_path.find(next_term) +1);
  1134. }
  1135. ygg_node X_list_temp = ygg_list::create();
  1136. for(int i = 0; X_list[i].is_valid(); ++i) {
  1137. X_list_temp.adopt_node(X_list[i][next_path]);
  1138. }
  1139. X_list = X_list_temp;
  1140. }
  1141. switch(X_list.get_size()) {
  1142. case 0:
  1143. return ygg_ghost::create(this, path); // return
  1144. case 1:
  1145. return X_list[0]; // return
  1146. default:
  1147. return X_list; // return
  1148. }
  1149. }
  1150. void ygg_root::adopt_node(ygg_node X_node) {
  1151. for(ygg_iterator i = X_node.begin(); i.is_not_end(); ++i) {
  1152. i->regist_parent(this);
  1153. }
  1154. // for(int i = 0; X_node[i].is_valid(); ++i) {
  1155. // X_node[i].regist_parent(this);
  1156. // }
  1157. }
  1158. void ygg_root::exile_node(ygg_node X_node) {
  1159. for(ygg_iterator i = X_node.begin(); i.is_not_end(); ++i) {
  1160. i->unregist_parent(this);
  1161. }
  1162. // for(int i = 0; X_node[i].is_valid(); ++i) {
  1163. // X_node[i].unregist_parent(this);
  1164. // }
  1165. }
  1166. bool ygg_root::match_path(const ygg_string &path) const {
  1167. return
  1168. path == ygg_term::node ||
  1169. path == ygg_term::element_node ||
  1170. path == ygg_term::wildcard; // return
  1171. }
  1172. ygg_node ygg_root::clone() const {
  1173. ygg_node X_clone = create();
  1174. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  1175. X_clone.adopt_node(i->clone());
  1176. }
  1177. return X_clone; // return
  1178. }
  1179. //
  1180. // ■ygg要素クラス
  1181. //
  1182. ygg_string ygg_element::get_type() const {
  1183. return ygg_node_type::element; // return
  1184. }
  1185. ygg_string ygg_element::get_name() const {
  1186. assert(name == encode_xml(name));
  1187. assert(name == encode_attribute(name));
  1188. return name; // return
  1189. }
  1190. ygg_string ygg_element::get_xml(const ygg_string & indent) const {
  1191. const ygg_string inner_indent = indent +ygg_term::indent;
  1192. ygg_string X_text = ygg_proto_list::get_xml(inner_indent);
  1193. ygg_string X_attribute = ygg_proto_list::get_xml_attribute();
  1194. if (0 == name.find("?")) {
  1195. X_text = "<" +name +X_attribute +" ?>";
  1196. } else if (ygg_term::empty == X_text) {
  1197. X_text = "<" +name +X_attribute +" />";
  1198. } else {
  1199. ygg_string X_core = both_trim(X_text);
  1200. if (0 < X_text.find_first_not_of(ygg_term::white_space)) {
  1201. X_core = ygg_term::return_code +inner_indent +X_core;
  1202. }
  1203. ygg_string::size_type end_pos = X_text.find_last_not_of(ygg_term::white_space);
  1204. if (ygg_string::npos != end_pos && end_pos +1 < X_text.length()) {
  1205. X_core += ygg_term::return_code +indent;
  1206. }
  1207. X_text = "<" +name +X_attribute +">" +X_core +"</" + name + ">";
  1208. }
  1209. return X_text; // return
  1210. }
  1211. ygg_string ygg_element::get_xml_attribute() const {
  1212. return ygg_term::empty; // return
  1213. }
  1214. ygg_string ygg_element::get_sox(const ygg_string & indent) const {
  1215. const ygg_string child_indent = indent +ygg_term::indent;
  1216. const ygg_list_type &X_list = body;
  1217. ygg_string X_attribute;
  1218. ygg_string X_text;
  1219. for(ygg_list_type::const_iterator i = X_list.begin(); i != X_list.end(); ++i) {
  1220. if (ygg_node_type::attribute == i->get_type()) {
  1221. X_attribute += i->get_sox(child_indent);
  1222. } else {
  1223. X_text += i->get_sox(child_indent);
  1224. }
  1225. }
  1226. X_text = indent +name +">" +ygg_term::return_code
  1227. +X_attribute
  1228. +X_text;
  1229. return X_text; // return
  1230. }
  1231. bool ygg_element::match_path(const ygg_string &path) const {
  1232. #ifdef __REJECT_PROCESSING_INSTRUCTION__
  1233. return
  1234. path == ygg_term::node ||
  1235. path == ygg_term::element_node ||
  1236. path == ygg_term::wildcard ||
  1237. path == name; // return
  1238. #else
  1239. return
  1240. path == ygg_term::node ||
  1241. (ygg_string::npos != name.find("!") ?
  1242. path == ygg_term::element_node ||
  1243. path == ygg_term::wildcard:
  1244. path == ygg_term::processing_instruction_node) ||
  1245. path == name; // return
  1246. #endif
  1247. }
  1248. void ygg_element::set_name(const ygg_string &X) {
  1249. name = X;
  1250. }
  1251. void ygg_element::set_value(const ygg_string &X) {
  1252. ygg_list_type::iterator i = body.begin();
  1253. while(i != body.end()) {
  1254. if (ygg_node_type::attribute != i->get_type()) {
  1255. i++->vanish();
  1256. } else {
  1257. ++i;
  1258. }
  1259. }
  1260. adopt_node(ygg_text::create().set_value(X));
  1261. }
  1262. ygg_node ygg_element::clone() const {
  1263. ygg_node X_clone = create().set_name(name);
  1264. for(ygg_list_type::const_iterator i = body.begin(); i != body.end(); ++i) {
  1265. X_clone.adopt_node(i->clone());
  1266. }
  1267. return X_clone; // return
  1268. }
  1269. /******************************************************************************
  1270. □■□■ Trick Library 'dagger' □■□■
  1271. ■□■□ http://tricklib.com/cxx/dagger/ ■□■□
  1272. ******************************************************************************/
  1273. //
  1274. // ■ygg_position
  1275. //
  1276. ygg_position & ygg_position::operator+=(const ygg_string &X) {
  1277. ygg_string X_text = X;
  1278. ygg_string::size_type p;
  1279. const ygg_string::size_type return_code_length = ygg_term::return_code.length();
  1280. while(ygg_string::npos != (p = X_text.find(ygg_term::return_code))) {
  1281. next_line();
  1282. PROMOTION(X_text).substr(p +return_code_length);
  1283. }
  1284. row += X_text.length();
  1285. return *this;
  1286. }
  1287. //
  1288. // ■SAXハンドラー基本クラス
  1289. //
  1290. void sax_handler::on_error(ygg_error*) {}
  1291. void sax_handler::start_document(ygg_node) {}
  1292. void sax_handler::end_document(ygg_node&) {}
  1293. void sax_handler::start_element(ygg_node) {}
  1294. void sax_handler::end_element(ygg_node) {}
  1295. void sax_handler::catch_text(ygg_node) {}
  1296. void sax_handler::catch_comment(ygg_node) {}
  1297. //
  1298. // □yggパーザクラス
  1299. //
  1300. ygg_parser * ygg_parser::set_sax_handler(sax_handler *X_sax) {
  1301. sax = X_sax;
  1302. AD_LIBTIUM(sax).set_parser(this);
  1303. return this; // return
  1304. }
  1305. const ygg_error_code ygg_parser::check_name(const ygg_string &type, const ygg_string &X) {
  1306. using namespace ygg_error_term;
  1307. ygg_error_code name_error = ygg_utility::check_name(X);
  1308. const int error_code = name_error.get_code();
  1309. const int sequence_case = name_error.get_sequence_case();
  1310. if (error_code == ygg_broken_char.get_code()) {
  1311. // 不正な文字コード...
  1312. raise_error(name_error, "不正な文字コードがあります。");
  1313. } else if (error_code == ygg_invalid_name.get_code()) {
  1314. // 不適切な名前...
  1315. if (sequence_case == ygg_invalid_name_a.get_sequence_case()) {
  1316. raise_error(name_error, "不適切な" +type +"(" +X +")です。(次の文字は" +type +"の一文字目には使用できません '" +ygg_term::ygg_invalid_name_chars_a +"')");
  1317. } else if (sequence_case == ygg_invalid_name_b.get_sequence_case()) {
  1318. raise_error(name_error, "不適切な" +type +"(" +X +")です。(次の文字は" +type +"として使用できません '" +ygg_term::ygg_invalid_name_chars_b +"')");
  1319. } else {
  1320. raise_error(name_error, "不適切な" +type +"(" +X +")です。");
  1321. }
  1322. } else if (error_code != no_error.get_code()) {
  1323. // その他のエラー...
  1324. raise_error(name_error);
  1325. }
  1326. // sax->on_error 内でエラーがクリアされた場合には強行する
  1327. return parse_error;
  1328. }
  1329. //
  1330. // ■SOXパーザクラス
  1331. //
  1332. sox_parser & sox_parser::init_root() {
  1333. root = ygg_root::create();
  1334. hot_element = root;
  1335. last_node = root;
  1336. indent_node_list = ygg_list::create();
  1337. indent_node_list.adopt_node(root);
  1338. anchor_indent = -1;
  1339. anchor_position.clear();
  1340. hot_position.clear();
  1341. parse_error.clear();
  1342. AD_LIBTIUM(sax).start_document(root);
  1343. return *this; // return
  1344. }
  1345. sox_parser & sox_parser::parse_line(const ygg_string &X_line) {
  1346. // いったん未処理バッファに残ってるやつを処理する
  1347. flush();
  1348. // その後は丸投げ
  1349. parse(X_line);
  1350. // 現在行のカウント
  1351. anchor_position.next_line();
  1352. return *this; // return
  1353. }
  1354. sox_parser & sox_parser::parse_string(const ygg_string &X_text) {
  1355. // とりあえず未処理バッファに追加
  1356. unparsed_buffer += X_text;
  1357. // 行単位で解析処理に投げる
  1358. int return_code_length = ygg_term::return_code.length();
  1359. ygg_string::size_type p;
  1360. while(ygg_string::npos != (p = unparsed_buffer.find(ygg_term::return_code))) {
  1361. parse(unparsed_buffer.substr(0, p));
  1362. if (parse_error.is_error()) {
  1363. break; // break
  1364. }
  1365. // 現在行のカウント
  1366. anchor_position.next_line();
  1367. unparsed_buffer = unparsed_buffer.substr(p +return_code_length);
  1368. }
  1369. return *this; // return
  1370. }
  1371. sox_parser & sox_parser::flush() {
  1372. // 未処理バッファに残ってるやつがあれば処理する
  1373. if (ygg_term::empty != unparsed_buffer) {
  1374. parse(unparsed_buffer);
  1375. unparsed_buffer = ygg_term::empty;
  1376. }
  1377. return *this; // return
  1378. }
  1379. sox_parser & sox_parser::end_stream() {
  1380. flush();
  1381. if (sax) {
  1382. catch_event(last_node);
  1383. if (ygg_node_type::element == hot_element.get_type()) {
  1384. for(ygg_node node = hot_element;
  1385. node.is_valid() && node != root;
  1386. PROMOTION(node).get_parent()) {
  1387. sax->end_element(node);
  1388. }
  1389. }
  1390. sax->end_document(root);
  1391. }
  1392. return *this; // return
  1393. }
  1394. void sox_parser::parse(const ygg_string &X_text) {
  1395. ygg_string X_parse = X_text;
  1396. ygg_string::size_type p;
  1397. ygg_string name;
  1398. ygg_string value;
  1399. // 既にエラーが発生していたら追い返す
  1400. if (parse_error.is_error()) {
  1401. return; // return
  1402. }
  1403. // 改行コードがまだ残っていれば取り除く
  1404. const char *xi[] = {"\x0a", "\x0d"};
  1405. for(const char **i = xi; i < ARRAY_END(xi); ++i) {
  1406. if (ygg_string::npos != (p = X_parse.find(*i))) {
  1407. PROMOTION(X_parse).substr(0, p);
  1408. }
  1409. }
  1410. // インデントを数える
  1411. int indent_count = 0;
  1412. int indent_length = ygg_term::indent.length();
  1413. while(ygg_term::indent == X_parse.substr(0, indent_length)) {
  1414. PROMOTION(X_parse).substr(indent_length);
  1415. ++indent_count;
  1416. anchor_position.row += indent_length;
  1417. }
  1418. if (0 == X_parse.length()) {
  1419. // 空行だべ...
  1420. return; // return
  1421. }
  1422. //
  1423. // アンカーインデントの差分を元に処理を行う
  1424. //
  1425. while(indent_count <= anchor_indent) {
  1426. // 親エレメントへ降りる
  1427. --anchor_indent;
  1428. assert(root != hot_element);
  1429. assert(ygg_node_type::empty != hot_element.get_type());
  1430. assert(1 < indent_node_list.get_size());
  1431. indent_node_list.exile_node(indent_node_list[indent_node_list.get_size() -1]);
  1432. assert(0 < indent_node_list.get_size());
  1433. ygg_node indent_node = indent_node_list[indent_node_list.get_size() -1];
  1434. if (sax) {
  1435. catch_event(last_node);
  1436. if (ygg_node_type::element == hot_element.get_type()) {
  1437. for(ygg_node node = hot_element;
  1438. node.is_valid() && node != indent_node;
  1439. PROMOTION(node).get_parent()) {
  1440. sax->end_element(node);
  1441. }
  1442. }
  1443. }
  1444. hot_element = indent_node;
  1445. // last_node = hot_element;
  1446. last_node = NULL;
  1447. // hot_element = hot_element.get_parent();
  1448. assert(ygg_node_type::empty != hot_element.get_type());
  1449. }
  1450. //
  1451. // ノードの検出
  1452. //
  1453. if (ygg_node_type::comment == last_node.get_type()) {
  1454. // コメントの続き...
  1455. last_node.set_value(
  1456. last_node.get_value().get_string() +ygg_term::return_code
  1457. +make_indent(indent_count -(anchor_indent +1))
  1458. +X_parse);
  1459. return; // return
  1460. }
  1461. // ここで深すぎるインデントのエラー検出
  1462. if (anchor_indent +1 < indent_count) {
  1463. raise_error(ygg_error_term::sox_deep_indent, "インデントが深すぎます。");
  1464. return; // return
  1465. }
  1466. if (ygg_string::npos != (p = X_parse.rfind(ygg_term::comment_trail))) {
  1467. // コメント
  1468. catch_event(last_node);
  1469. value = X_parse.substr(0, p);
  1470. last_node = ygg_comment::create().set_value(value);
  1471. hot_element.adopt_node(last_node);
  1472. hot_element = last_node;
  1473. indent_node_list.adopt_node(last_node);
  1474. assert(anchor_indent +1 == indent_count);
  1475. anchor_indent = indent_count;
  1476. X_parse = X_parse.substr(p +ygg_term::comment_trail.length());
  1477. while(ygg_term::indent == X_parse.substr(0, indent_length)) {
  1478. PROMOTION(X_parse).substr(indent_length);
  1479. }
  1480. if (0 < X_parse.length()) {
  1481. last_node.set_value(
  1482. value +ygg_term::return_code
  1483. +ygg_term::indent +X_parse);
  1484. }
  1485. return; // return
  1486. }
  1487. while(ygg_string::npos != (p = X_parse.find(ygg_term::element_trail))) {
  1488. // エレメント
  1489. catch_event(last_node);
  1490. name = X_parse.substr(0, p);
  1491. if (ygg_parser::check_element_name(name).is_error()) {
  1492. return;
  1493. }
  1494. last_node = ygg_element::create().set_name(name);
  1495. hot_element.adopt_node(last_node);
  1496. hot_element = last_node;
  1497. if (anchor_indent < indent_count) {
  1498. assert(anchor_indent +1 == indent_count);
  1499. anchor_indent = indent_count;
  1500. indent_node_list.adopt_node(last_node);
  1501. }
  1502. X_parse = X_parse.substr(p +ygg_term::element_trail.length());
  1503. while(ygg_term::indent == X_parse.substr(0, indent_length)) {
  1504. PROMOTION(X_parse).substr(indent_length);
  1505. }
  1506. }
  1507. if (0 == X_parse.length()) {
  1508. return; // return
  1509. }
  1510. if (ygg_string::npos != (p = X_parse.find(ygg_term::equal))) {
  1511. // アトリビュート
  1512. name = X_parse.substr(0, p);
  1513. if (ygg_parser::check_attribute_name(name).is_error()) {
  1514. return;
  1515. } else if (hot_element["@"+name].is_valid()) {
  1516. raise_error(ygg_error_term::duplication_attribute, name +"属性が重複しています。");
  1517. // sax->on_error 内でエラーがクリアされた場合は強行する...
  1518. if (parse_error.is_error()) {
  1519. return;
  1520. }
  1521. }
  1522. value = decode_attribute(X_parse.substr(p +ygg_term::equal.length()));
  1523. // last_node = ygg_attribute::create().set_name(name).set_value(value);
  1524. // hot_element.adopt_node(last_node);
  1525. hot_element.adopt_node(ygg_attribute::create().set_name(name).set_value(value));
  1526. } else {
  1527. // テキスト
  1528. if (ygg_node_type::text != last_node.get_type()) {
  1529. // 新規
  1530. catch_event(last_node);
  1531. value = decode_xml(X_parse);
  1532. last_node = ygg_text::create().set_value(value);
  1533. hot_element.adopt_node(last_node);
  1534. } else {
  1535. // 続き...
  1536. last_node.set_value(
  1537. last_node.get_value().get_string() +ygg_term::return_code
  1538. +make_indent(indent_count -(anchor_indent +2))
  1539. +X_parse);
  1540. }
  1541. }
  1542. }
  1543. void sox_parser::catch_event(ygg_node node) {
  1544. if (sax) {
  1545. ygg_string type = node.get_type();
  1546. if (ygg_node_type::text == type) {
  1547. sax->catch_text(node);
  1548. } else if (ygg_node_type::comment == type) {
  1549. sax->catch_comment(node);
  1550. } else if (ygg_node_type::element == type) {
  1551. sax->start_element(node);
  1552. }
  1553. }
  1554. }
  1555. //
  1556. // ■XMLパーザクラス
  1557. //
  1558. xml_parser & xml_parser::init_root() {
  1559. root = ygg_root::create();
  1560. hot_element = root;
  1561. last_node = root;
  1562. anchor_position.clear();
  1563. hot_position.clear();
  1564. parse_error.clear();
  1565. AD_LIBTIUM(sax).start_document(root);
  1566. return *this; // return
  1567. }
  1568. xml_parser & xml_parser::parse_line(const ygg_string &X_line) {
  1569. if (ygg_string::npos != X_line.find(ygg_term::return_code)) {
  1570. parse_string(X_line);
  1571. } else {
  1572. parse_string(X_line +ygg_term::return_code);
  1573. }
  1574. return *this; // return
  1575. }
  1576. xml_parser & xml_parser::parse_string(const ygg_string &X_text) {
  1577. // とりあえず未処理バッファに追加
  1578. unparsed_buffer += X_text;
  1579. // 既にエラーが発生していたら追い返す
  1580. if (parse_error.is_error()) {
  1581. return *this; // return
  1582. }
  1583. ygg_string::size_type p, p_end;
  1584. ygg_string value;
  1585. while (ygg_string::npos != (p = unparsed_buffer.find(ygg_term::element_lead))) {
  1586. if (0 != p) {
  1587. // 先にテキストを処理...
  1588. ygg_string source_text = unparsed_buffer.substr(0, p);
  1589. value = decode_xml(ygg_utility::xml_trim(source_text));
  1590. if (ygg_node_type::text == last_node.get_type()) {
  1591. // 続きのテキスト...
  1592. last_node.set_value(last_node.get_value().get_string() +value);
  1593. } else {
  1594. // 新規のテキスト...
  1595. anchor_position = hot_position;
  1596. last_node = ygg_text::create().set_value(value);
  1597. hot_element.adopt_node(last_node);
  1598. }
  1599. // 続きがある可能性があるのでこの段階ではイベントを発生させない。
  1600. // AD_LIBTIUM(sax).catch_text(last_node);
  1601. hot_position += source_text;
  1602. PROMOTION(unparsed_buffer).substr(p), p = 0;
  1603. }
  1604. if (p == unparsed_buffer.find(ygg_term::comment_lead)) {
  1605. // コメント...
  1606. p_end = unparsed_buffer.find(ygg_term::comment_trail, p);
  1607. if (ygg_string::npos != p_end) {
  1608. // コメントの"閉じ"を発見...
  1609. // 直前のノードがテキストノードならテキストイベントを発生。
  1610. if (ygg_node_type::text == last_node.get_type()) {
  1611. AD_LIBTIUM(sax).catch_text(last_node);
  1612. }
  1613. value = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::comment_lead.length());
  1614. last_node = ygg_comment::create().set_value(value);
  1615. hot_element.adopt_node(last_node);
  1616. AD_LIBTIUM(sax).catch_comment(last_node);
  1617. hot_position += unparsed_buffer.substr(0, p_end +ygg_term::comment_trail.length());
  1618. PROMOTION(unparsed_buffer).substr(p_end +ygg_term::comment_trail.length());
  1619. } else {
  1620. break; // break
  1621. }
  1622. } else if (p == unparsed_buffer.find(ygg_term::cdata_lead)) {
  1623. // CDATAテキスト...
  1624. p_end = unparsed_buffer.find(ygg_term::cdata_trail, p);
  1625. if (ygg_string::npos != p_end) {
  1626. // CDATAの"閉じ"を発見...
  1627. value = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::cdata_lead.length());
  1628. if (ygg_node_type::text == last_node.get_type()) {
  1629. last_node.set_value(last_node.get_value().get_string() +value);
  1630. } else {
  1631. last_node = ygg_text::create().set_value(value);
  1632. hot_element.adopt_node(last_node);
  1633. }
  1634. // 続きがある可能性があるのでこの段階ではイベントを発生させない。
  1635. // AD_LIBTIUM(sax).catch_text(last_node);
  1636. hot_position += unparsed_buffer.substr(0, p_end +ygg_term::cdata_trail.length());
  1637. PROMOTION(unparsed_buffer).substr(p_end +ygg_term::cdata_trail.length());
  1638. } else {
  1639. break; // break
  1640. }
  1641. } else {
  1642. // エレメント...
  1643. p_end = unparsed_buffer.find(ygg_term::element_trail, p);
  1644. if (ygg_string::npos != p_end) {
  1645. // エレメントの"閉じ"を発見...
  1646. // 直前のノードがテキストノードならテキストイベントを発生。
  1647. if (ygg_node_type::text == last_node.get_type()) {
  1648. AD_LIBTIUM(sax).catch_text(last_node);
  1649. }
  1650. // タグ内のテキスト
  1651. ygg_string element_string = unparsed_buffer.substr(0, p_end).substr(p +ygg_term::element_lead.length());
  1652. //
  1653. anchor_position = hot_position;
  1654. hot_position += unparsed_buffer.substr(0, p_end +ygg_term::element_trail.length());
  1655. PROMOTION(unparsed_buffer).substr(p_end +ygg_term::element_trail.length());
  1656. // "/" のチェック
  1657. ygg_string::size_type p_lead_sign = 0;
  1658. ygg_string::size_type p_trail_sign = element_string.length() -ygg_term::element_sign.length();
  1659. bool lead_sign = p_lead_sign == element_string.find(ygg_term::element_sign, p_lead_sign);
  1660. bool trail_sign = p_trail_sign == element_string.find(ygg_term::element_sign, p_trail_sign);
  1661. if (trail_sign) PROMOTION(element_string).substr(0, p_trail_sign);
  1662. if (lead_sign) PROMOTION(element_string).substr(ygg_term::element_sign.length());
  1663. # ifdef __REJECT_PROCESSING_INSTRUCTION__
  1664. # else
  1665. bool is_pi_node = false;
  1666. # endif
  1667. if (!lead_sign && !trail_sign &&
  1668. p_lead_sign == element_string.find("?", p_lead_sign) &&
  1669. p_trail_sign == element_string.find("?", p_trail_sign)) {
  1670. // <?〜?> ...
  1671. # ifdef __REJECT_PROCESSING_INSTRUCTION__
  1672. // 読み飛ばし
  1673. continue; // continue
  1674. # else
  1675. // 特殊なエレメントとして処理
  1676. PROMOTION(element_string).substr(0, p_trail_sign);
  1677. trail_sign = true;
  1678. is_pi_node = true;
  1679. # endif
  1680. }
  1681. // 要素名の取得
  1682. ygg_string::size_type p_name_end = element_string.find_first_of(ygg_term::white_space);
  1683. ygg_string element_name = element_string.substr(0, p_name_end);
  1684. if (ygg_string::npos != p_name_end) {
  1685. PROMOTION(element_string).substr(p_name_end);
  1686. } else {
  1687. PROMOTION(element_string) = ygg_term::empty;
  1688. }
  1689. // 先頭に"/"が無ければ
  1690. if (!lead_sign) {
  1691. # ifdef __REJECT_PROCESSING_INSTRUCTION__
  1692. if (ygg_parser::check_element_name(element_name).is_error()) {
  1693. # else
  1694. if (ygg_parser::check_element_name((is_pi_node) ? element_name.substr(1): element_name).is_error()) {
  1695. # endif
  1696. return *this; // return
  1697. }
  1698. last_node = ygg_element::create().set_name(element_name);
  1699. hot_element.adopt_node(last_node);
  1700. hot_element = last_node;
  1701. // 属性の取得...
  1702. while(true) {
  1703. ygg_string::size_type p_anchor = element_string.find_first_not_of(ygg_term::white_space);
  1704. if (ygg_string::npos == p_anchor) {
  1705. break; // break
  1706. }
  1707. PROMOTION(element_string).substr(p_anchor);
  1708. ygg_string::size_type p_name_end = element_string.find_first_of("=" +ygg_term::white_space);
  1709. ygg_string attribute_name = element_string.substr(0, p_name_end);
  1710. if (ygg_parser::check_attribute_name(attribute_name).is_error()) {
  1711. return *this; // return
  1712. } else if (hot_element["@"+attribute_name].is_valid()) {
  1713. raise_error(ygg_error_term::duplication_attribute, attribute_name +"属性が重複しています。");
  1714. // sax->on_error 内でエラーがクリアされた場合は強行する...
  1715. if (parse_error.is_error()) {
  1716. return *this; // return
  1717. }
  1718. }
  1719. ygg_string hedge_symbol;
  1720. ygg_string::size_type p_value;
  1721. ygg_string::size_type p_value_a = element_string.find("\"", p_name_end);
  1722. ygg_string::size_type p_value_b = element_string.find("\'", p_name_end);
  1723. if (ygg_string::npos == p_value_b ||
  1724. (ygg_string::npos != p_value_a && p_value_a <= p_value_b)) {
  1725. hedge_symbol = "\"";
  1726. p_value = p_value_a;
  1727. } else {
  1728. hedge_symbol = "\'";
  1729. p_value = p_value_b;
  1730. }
  1731. ygg_string::size_type p_value_end = element_string.find(hedge_symbol, p_value +1);
  1732. value = element_string.substr(0, p_value_end).substr(p_value +1);
  1733. hot_element.adopt_node(ygg_attribute::create().set_name(attribute_name).set_value(value));
  1734. PROMOTION(element_string).substr(p_value_end +1);
  1735. }
  1736. // エレメント開始イベントを発生。
  1737. AD_LIBTIUM(sax).start_element(hot_element);
  1738. }
  1739. // 先頭もしくは末尾に"/"が有れば
  1740. if (lead_sign || trail_sign) {
  1741. if (element_name != hot_element.get_name()) {
  1742. if (root != hot_element) {
  1743. raise_error(ygg_error_term::unmatch_tags_a, "開始タグ<" +hot_element.get_name() +">と終了タグ</" +element_name +">がマッチしていません。");
  1744. } else {
  1745. raise_error(ygg_error_term::unmatch_tags_b, "いきなり終了タグ<" +element_name +">から始まっています。");
  1746. }
  1747. if (parse_error.is_error()) {
  1748. return *this; // return
  1749. }
  1750. }
  1751. // end_element 内で vanish されると親が分からなくなるのでここで取得。
  1752. ygg_node parent = hot_element.get_parent();
  1753. // エレメント終了イベントを発生。
  1754. AD_LIBTIUM(sax).end_element(hot_element);
  1755. hot_element = parent;
  1756. last_node = NULL;
  1757. }
  1758. } else {
  1759. break; // break
  1760. }
  1761. }
  1762. }
  1763. return *this; // return
  1764. }
  1765. xml_parser & xml_parser::flush() {
  1766. // xml版では何もしない。
  1767. return *this; // return
  1768. }
  1769. xml_parser & xml_parser::end_stream() {
  1770. flush();
  1771. if (sax) {
  1772. if (ygg_node_type::text == last_node.get_type()) {
  1773. sax->catch_text(last_node);
  1774. }
  1775. sax->end_document(root);
  1776. }
  1777. return *this; // return
  1778. }
  1779. } // namespace yggdrasil
  1780. /******************************************************************************
  1781. □■□■ Wraith the Trickster □■□■
  1782. ■□■□ 〜I'll go with heaven's advantage and fool's wisdom.〜 ■□■□
  1783. ******************************************************************************/