debrecords.cc 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: debrecords.cc,v 1.10 2001/03/13 06:51:46 jgg Exp $
  4. /* ######################################################################
  5. Debian Package Records - Parser for debian package records
  6. ##################################################################### */
  7. /*}}}*/
  8. // Include Files /*{{{*/
  9. #include <config.h>
  10. #include <apt-pkg/debrecords.h>
  11. #include <apt-pkg/strutl.h>
  12. #include <apt-pkg/aptconfiguration.h>
  13. #include <apt-pkg/fileutl.h>
  14. #include <apt-pkg/cacheiterators.h>
  15. #include <apt-pkg/pkgcache.h>
  16. #include <apt-pkg/tagfile.h>
  17. #include <string.h>
  18. #include <algorithm>
  19. #include <string>
  20. #include <vector>
  21. #include <langinfo.h>
  22. /*}}}*/
  23. using std::string;
  24. // RecordParser::debRecordParser - Constructor /*{{{*/
  25. // ---------------------------------------------------------------------
  26. /* */
  27. debRecordParser::debRecordParser(string FileName,pkgCache &Cache) :
  28. File(FileName,FileFd::ReadOnly, FileFd::Extension),
  29. Tags(&File, std::max(Cache.Head().MaxVerFileSize,
  30. Cache.Head().MaxDescFileSize) + 200)
  31. {
  32. }
  33. /*}}}*/
  34. // RecordParser::Jump - Jump to a specific record /*{{{*/
  35. // ---------------------------------------------------------------------
  36. /* */
  37. bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver)
  38. {
  39. return Tags.Jump(Section,Ver->Offset);
  40. }
  41. bool debRecordParser::Jump(pkgCache::DescFileIterator const &Desc)
  42. {
  43. return Tags.Jump(Section,Desc->Offset);
  44. }
  45. /*}}}*/
  46. // RecordParser::FileName - Return the archive filename on the site /*{{{*/
  47. // ---------------------------------------------------------------------
  48. /* */
  49. string debRecordParser::FileName()
  50. {
  51. return Section.FindS("Filename");
  52. }
  53. /*}}}*/
  54. // RecordParser::Name - Return the package name /*{{{*/
  55. // ---------------------------------------------------------------------
  56. /* */
  57. string debRecordParser::Name()
  58. {
  59. return Section.FindS("Package");
  60. }
  61. /*}}}*/
  62. // RecordParser::Homepage - Return the package homepage /*{{{*/
  63. // ---------------------------------------------------------------------
  64. /* */
  65. string debRecordParser::Homepage()
  66. {
  67. return Section.FindS("Homepage");
  68. }
  69. /*}}}*/
  70. // RecordParser::Hashes - return the available archive hashes /*{{{*/
  71. HashStringList debRecordParser::Hashes() const
  72. {
  73. HashStringList hashes;
  74. for (char const * const * type = HashString::SupportedHashes(); *type != NULL; ++type)
  75. {
  76. std::string const hash = Section.FindS(*type);
  77. if (hash.empty() == false)
  78. hashes.push_back(HashString(*type, hash));
  79. }
  80. return hashes;
  81. }
  82. /*}}}*/
  83. // RecordParser::Maintainer - Return the maintainer email /*{{{*/
  84. // ---------------------------------------------------------------------
  85. /* */
  86. string debRecordParser::Maintainer()
  87. {
  88. return Section.FindS("Maintainer");
  89. }
  90. /*}}}*/
  91. // RecordParser::RecordField - Return the value of an arbitrary field /*{{*/
  92. // ---------------------------------------------------------------------
  93. /* */
  94. string debRecordParser::RecordField(const char *fieldName)
  95. {
  96. return Section.FindS(fieldName);
  97. }
  98. /*}}}*/
  99. // RecordParser::ShortDesc - Return a 1 line description /*{{{*/
  100. // ---------------------------------------------------------------------
  101. /* */
  102. string debRecordParser::ShortDesc(std::string const &lang)
  103. {
  104. string const Res = LongDesc(lang);
  105. if (Res.empty() == true)
  106. return "";
  107. string::size_type const Pos = Res.find('\n');
  108. if (Pos == string::npos)
  109. return Res;
  110. return string(Res,0,Pos);
  111. }
  112. /*}}}*/
  113. // RecordParser::LongDesc - Return a longer description /*{{{*/
  114. // ---------------------------------------------------------------------
  115. /* */
  116. string debRecordParser::LongDesc(std::string const &lang)
  117. {
  118. string orig;
  119. if (lang.empty() == true)
  120. {
  121. std::vector<string> const lang = APT::Configuration::getLanguages();
  122. for (std::vector<string>::const_iterator l = lang.begin();
  123. l != lang.end(); ++l)
  124. {
  125. std::string const tagname = "Description-" + *l;
  126. orig = Section.FindS(tagname.c_str());
  127. if (orig.empty() == false)
  128. break;
  129. else if (*l == "en")
  130. {
  131. orig = Section.FindS("Description");
  132. if (orig.empty() == false)
  133. break;
  134. }
  135. }
  136. if (orig.empty() == true)
  137. orig = Section.FindS("Description");
  138. }
  139. else
  140. {
  141. std::string const tagname = "Description-" + lang;
  142. orig = Section.FindS(tagname.c_str());
  143. if (orig.empty() == true && lang == "en")
  144. orig = Section.FindS("Description");
  145. }
  146. char const * const codeset = nl_langinfo(CODESET);
  147. if (strcmp(codeset,"UTF-8") != 0) {
  148. string dest;
  149. UTF8ToCodeset(codeset, orig, &dest);
  150. return dest;
  151. }
  152. return orig;
  153. }
  154. /*}}}*/
  155. static const char *SourceVerSeparators = " ()";
  156. // RecordParser::SourcePkg - Return the source package name if any /*{{{*/
  157. // ---------------------------------------------------------------------
  158. /* */
  159. string debRecordParser::SourcePkg()
  160. {
  161. string Res = Section.FindS("Source");
  162. string::size_type Pos = Res.find_first_of(SourceVerSeparators);
  163. if (Pos == string::npos)
  164. return Res;
  165. return string(Res,0,Pos);
  166. }
  167. /*}}}*/
  168. // RecordParser::SourceVer - Return the source version number if present /*{{{*/
  169. // ---------------------------------------------------------------------
  170. /* */
  171. string debRecordParser::SourceVer()
  172. {
  173. string Pkg = Section.FindS("Source");
  174. string::size_type Pos = Pkg.find_first_of(SourceVerSeparators);
  175. if (Pos == string::npos)
  176. return "";
  177. string::size_type VerStart = Pkg.find_first_not_of(SourceVerSeparators, Pos);
  178. if(VerStart == string::npos)
  179. return "";
  180. string::size_type VerEnd = Pkg.find_first_of(SourceVerSeparators, VerStart);
  181. if(VerEnd == string::npos)
  182. // Corresponds to the case of, e.g., "foo (1.2" without a closing
  183. // paren. Be liberal and guess what it means.
  184. return string(Pkg, VerStart);
  185. else
  186. return string(Pkg, VerStart, VerEnd - VerStart);
  187. }
  188. /*}}}*/
  189. // RecordParser::GetRec - Return the whole record /*{{{*/
  190. // ---------------------------------------------------------------------
  191. /* */
  192. void debRecordParser::GetRec(const char *&Start,const char *&Stop)
  193. {
  194. Section.GetSection(Start,Stop);
  195. }
  196. /*}}}*/
  197. debRecordParser::~debRecordParser() {};