MetalinkParserStateImpl.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2009 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "MetalinkParserStateImpl.h"
  36. #include "MetalinkParserStateMachine.h"
  37. #include "RecoverableException.h"
  38. #include "Util.h"
  39. namespace aria2 {
  40. namespace {
  41. const std::string FILE("file");
  42. const std::string FILES("files");
  43. const std::string HASH("hash");
  44. const std::string LANGUAGE("language");
  45. const std::string LENGTH("length");
  46. const std::string LOCATION("location");
  47. const std::string MAXCONNECTIONS("maxconnections");
  48. const std::string METALINK("metalink");
  49. // Can't use name VERSION because it is used as a macro.
  50. const std::string METALINK_VERSION("version");
  51. const std::string METAURL("metaurl");
  52. const std::string NAME("name");
  53. const std::string OS("os");
  54. const std::string PIECE("piece");
  55. const std::string PIECES("pieces");
  56. const std::string PREFERENCE("preference");
  57. const std::string RESOURCES("resources");
  58. const std::string SIGNATURE("signature");
  59. const std::string SIZE("size");
  60. const std::string TYPE("type");
  61. const std::string URL("url");
  62. const std::string VERIFICATION("verification");
  63. }
  64. void InitialMetalinkParserState::beginElement
  65. (MetalinkParserStateMachine* stm,
  66. const std::string& name,
  67. const std::map<std::string, std::string>& attrs)
  68. {
  69. if(name == METALINK) {
  70. stm->setMetalinkState();
  71. } else {
  72. stm->setSkipTagState();
  73. }
  74. }
  75. void MetalinkMetalinkParserState::beginElement
  76. (MetalinkParserStateMachine* stm,
  77. const std::string& name,
  78. const std::map<std::string, std::string>& attrs)
  79. {
  80. if(name == FILES) {
  81. stm->setFilesState();
  82. } else {
  83. stm->setSkipTagState();
  84. }
  85. }
  86. void FilesMetalinkParserState::beginElement
  87. (MetalinkParserStateMachine* stm,
  88. const std::string& name,
  89. const std::map<std::string, std::string>& attrs)
  90. {
  91. if(name == FILE) {
  92. stm->setFileState();
  93. std::map<std::string, std::string>::const_iterator itr = attrs.find(NAME);
  94. if(itr != attrs.end()) {
  95. stm->newEntryTransaction();
  96. stm->setFileNameOfEntry((*itr).second);
  97. }
  98. } else {
  99. stm->setSkipTagState();
  100. }
  101. }
  102. void FileMetalinkParserState::beginElement
  103. (MetalinkParserStateMachine* stm,
  104. const std::string& name,
  105. const std::map<std::string, std::string>& attrs)
  106. {
  107. if(name == SIZE) {
  108. stm->setSizeState();
  109. } else if(name == METALINK_VERSION) {
  110. stm->setVersionState();
  111. } else if(name == LANGUAGE) {
  112. stm->setLanguageState();
  113. } else if(name == OS) {
  114. stm->setOSState();
  115. } else if(name == VERIFICATION) {
  116. stm->setVerificationState();
  117. } else if(name == RESOURCES) {
  118. stm->setResourcesState();
  119. int maxConnections;
  120. {
  121. std::map<std::string, std::string>::const_iterator itr =
  122. attrs.find(MAXCONNECTIONS);
  123. if(itr == attrs.end()) {
  124. maxConnections = -1;
  125. } else {
  126. try {
  127. maxConnections = util::parseInt((*itr).second);
  128. } catch(RecoverableException& e) {
  129. maxConnections = -1;
  130. }
  131. }
  132. }
  133. stm->setMaxConnectionsOfEntry(maxConnections);
  134. } else {
  135. stm->setSkipTagState();
  136. }
  137. }
  138. void FileMetalinkParserState::endElement
  139. (MetalinkParserStateMachine* stm,
  140. const std::string& name,
  141. const std::string& characters)
  142. {
  143. stm->commitEntryTransaction();
  144. }
  145. void SizeMetalinkParserState::beginElement
  146. (MetalinkParserStateMachine* stm,
  147. const std::string& name,
  148. const std::map<std::string, std::string>& attrs)
  149. {
  150. stm->setSkipTagState();
  151. }
  152. void SizeMetalinkParserState::endElement
  153. (MetalinkParserStateMachine* stm,
  154. const std::string& name,
  155. const std::string& characters)
  156. {
  157. try {
  158. stm->setFileLengthOfEntry(util::parseLLInt(characters));
  159. } catch(RecoverableException& e) {
  160. // current metalink specification doesn't require size element.
  161. }
  162. }
  163. void VersionMetalinkParserState::beginElement
  164. (MetalinkParserStateMachine* stm,
  165. const std::string& name,
  166. const std::map<std::string, std::string>& attrs)
  167. {
  168. stm->setSkipTagState();
  169. }
  170. void VersionMetalinkParserState::endElement
  171. (MetalinkParserStateMachine* stm,
  172. const std::string& name,
  173. const std::string& characters)
  174. {
  175. stm->setVersionOfEntry(characters);
  176. }
  177. void LanguageMetalinkParserState::beginElement
  178. (MetalinkParserStateMachine* stm,
  179. const std::string& name,
  180. const std::map<std::string, std::string>& attrs)
  181. {
  182. stm->setSkipTagState();
  183. }
  184. void LanguageMetalinkParserState::endElement
  185. (MetalinkParserStateMachine* stm,
  186. const std::string& name,
  187. const std::string& characters)
  188. {
  189. stm->setLanguageOfEntry(characters);
  190. }
  191. void OSMetalinkParserState::beginElement
  192. (MetalinkParserStateMachine* stm,
  193. const std::string& name,
  194. const std::map<std::string, std::string>& attrs)
  195. {
  196. stm->setSkipTagState();
  197. }
  198. void OSMetalinkParserState::endElement
  199. (MetalinkParserStateMachine* stm,
  200. const std::string& name,
  201. const std::string& characters)
  202. {
  203. stm->setOSOfEntry(characters);
  204. }
  205. void VerificationMetalinkParserState::beginElement
  206. (MetalinkParserStateMachine* stm,
  207. const std::string& name,
  208. const std::map<std::string, std::string>& attrs)
  209. {
  210. #ifdef ENABLE_MESSAGE_DIGEST
  211. if(name == HASH) {
  212. stm->setHashState();
  213. std::map<std::string, std::string>::const_iterator itr = attrs.find(TYPE);
  214. if(itr == attrs.end()) {
  215. return;
  216. } else {
  217. std::string type = (*itr).second;
  218. stm->newChecksumTransaction();
  219. stm->setTypeOfChecksum(type);
  220. }
  221. } else if(name == PIECES) {
  222. stm->setPiecesState();
  223. try {
  224. size_t length;
  225. {
  226. std::map<std::string, std::string>::const_iterator itr =
  227. attrs.find(LENGTH);
  228. if(itr == attrs.end()) {
  229. return;
  230. } else {
  231. length = util::parseInt((*itr).second);
  232. }
  233. }
  234. std::string type;
  235. {
  236. std::map<std::string, std::string>::const_iterator itr =
  237. attrs.find(TYPE);
  238. if(itr == attrs.end()) {
  239. return;
  240. } else {
  241. type = (*itr).second;
  242. }
  243. }
  244. stm->newChunkChecksumTransaction();
  245. stm->setLengthOfChunkChecksum(length);
  246. stm->setTypeOfChunkChecksum(type);
  247. } catch(RecoverableException& e) {
  248. stm->cancelChunkChecksumTransaction();
  249. }
  250. } else
  251. #endif // ENABLE_MESSAGE_DIGEST
  252. if(name == SIGNATURE) {
  253. stm->setSignatureState();
  254. std::map<std::string, std::string>::const_iterator itr = attrs.find(TYPE);
  255. if(itr == attrs.end()) {
  256. return;
  257. } else {
  258. stm->newSignatureTransaction();
  259. stm->setTypeOfSignature((*itr).second);
  260. std::map<std::string, std::string>::const_iterator itr = attrs.find(FILE);
  261. if(itr != attrs.end()) {
  262. stm->setFileOfSignature((*itr).second);
  263. }
  264. }
  265. } else {
  266. stm->setSkipTagState();
  267. }
  268. }
  269. void HashMetalinkParserState::beginElement
  270. (MetalinkParserStateMachine* stm,
  271. const std::string& name,
  272. const std::map<std::string, std::string>& attrs)
  273. {
  274. stm->setSkipTagState();
  275. }
  276. void HashMetalinkParserState::endElement
  277. (MetalinkParserStateMachine* stm,
  278. const std::string& name,
  279. const std::string& characters)
  280. {
  281. stm->setHashOfChecksum(characters);
  282. stm->commitChecksumTransaction();
  283. }
  284. void PiecesMetalinkParserState::beginElement
  285. (MetalinkParserStateMachine* stm,
  286. const std::string& name,
  287. const std::map<std::string, std::string>& attrs)
  288. {
  289. if(name == HASH) {
  290. stm->setPieceHashState();
  291. std::map<std::string, std::string>::const_iterator itr = attrs.find(PIECE);
  292. if(itr == attrs.end()) {
  293. stm->cancelChunkChecksumTransaction();
  294. } else {
  295. try {
  296. stm->createNewHashOfChunkChecksum(util::parseInt((*itr).second));
  297. } catch(RecoverableException& e) {
  298. stm->cancelChunkChecksumTransaction();
  299. }
  300. }
  301. } else {
  302. stm->setSkipTagState();
  303. }
  304. }
  305. void PiecesMetalinkParserState::endElement
  306. (MetalinkParserStateMachine* stm,
  307. const std::string& name,
  308. const std::string& characters)
  309. {
  310. stm->commitChunkChecksumTransaction();
  311. }
  312. void PieceHashMetalinkParserState::beginElement
  313. (MetalinkParserStateMachine* stm,
  314. const std::string& name,
  315. const std::map<std::string, std::string>& attrs)
  316. {
  317. stm->setSkipTagState();
  318. }
  319. void PieceHashMetalinkParserState::endElement
  320. (MetalinkParserStateMachine* stm,
  321. const std::string& name,
  322. const std::string& characters)
  323. {
  324. stm->setMessageDigestOfChunkChecksum(characters);
  325. stm->addHashOfChunkChecksum();
  326. }
  327. void SignatureMetalinkParserState::beginElement
  328. (MetalinkParserStateMachine* stm,
  329. const std::string& name,
  330. const std::map<std::string, std::string>& attrs)
  331. {
  332. stm->setSkipTagState();
  333. }
  334. void SignatureMetalinkParserState::endElement
  335. (MetalinkParserStateMachine* stm,
  336. const std::string& name,
  337. const std::string& characters)
  338. {
  339. stm->setBodyOfSignature(characters);
  340. stm->commitSignatureTransaction();
  341. }
  342. void ResourcesMetalinkParserState::beginElement
  343. (MetalinkParserStateMachine* stm,
  344. const std::string& name,
  345. const std::map<std::string, std::string>& attrs)
  346. {
  347. if(name == URL) {
  348. stm->setURLState();
  349. std::string type;
  350. {
  351. std::map<std::string, std::string>::const_iterator itr = attrs.find(TYPE);
  352. if(itr == attrs.end()) {
  353. return;
  354. } else {
  355. type = (*itr).second;
  356. }
  357. }
  358. std::string location;
  359. {
  360. std::map<std::string, std::string>::const_iterator itr =
  361. attrs.find(LOCATION);
  362. if(itr != attrs.end()) {
  363. location = util::toUpper((*itr).second);
  364. }
  365. }
  366. int preference;
  367. {
  368. std::map<std::string, std::string>::const_iterator itr =
  369. attrs.find(PREFERENCE);
  370. if(itr == attrs.end()) {
  371. preference = 0;
  372. } else {
  373. try {
  374. preference = util::parseInt((*itr).second);
  375. } catch(RecoverableException& e) {
  376. preference = 0;
  377. }
  378. }
  379. }
  380. int maxConnections;
  381. {
  382. std::map<std::string, std::string>::const_iterator itr =
  383. attrs.find(MAXCONNECTIONS);
  384. if(itr == attrs.end()) {
  385. maxConnections = -1;
  386. } else {
  387. try {
  388. maxConnections = util::parseInt((*itr).second);
  389. } catch(RecoverableException& e) {
  390. maxConnections = -1;
  391. }
  392. }
  393. }
  394. stm->newResourceTransaction();
  395. stm->setTypeOfResource(type);
  396. stm->setLocationOfResource(location);
  397. stm->setPreferenceOfResource(preference);
  398. stm->setMaxConnectionsOfResource(maxConnections);
  399. } else {
  400. stm->setSkipTagState();
  401. }
  402. }
  403. void URLMetalinkParserState::beginElement
  404. (MetalinkParserStateMachine* stm,
  405. const std::string& name,
  406. const std::map<std::string, std::string>& attrs)
  407. {
  408. stm->setSkipTagState();
  409. }
  410. void URLMetalinkParserState::endElement
  411. (MetalinkParserStateMachine* stm,
  412. const std::string& name,
  413. const std::string& characters)
  414. {
  415. stm->setURLOfResource(characters);
  416. stm->commitResourceTransaction();
  417. }
  418. void SkipTagMetalinkParserState::beginElement
  419. (MetalinkParserStateMachine* stm,
  420. const std::string& name,
  421. const std::map<std::string, std::string>& attrs)
  422. {
  423. stm->setSkipTagState();
  424. }
  425. } // namespace aria2