]> git.tdb.fi Git - r2c2.git/blob - source/libr2c2/articlenumber.cpp
dd19eb5710e1ab0b7d1d719ef0969b1545cdd08f
[r2c2.git] / source / libr2c2 / articlenumber.cpp
1 #include <msp/strings/utils.h>
2 #include "articlenumber.h"
3
4 using namespace std;
5 using namespace Msp;
6
7 namespace R2C2 {
8
9 ArticleNumber::ArticleNumber(unsigned n)
10 {
11         Part part;
12         part.number = n;
13         part.letter = 0;
14         parts.push_back(part);
15 }
16
17 ArticleNumber::ArticleNumber(const string &s)
18 {
19         vector<string> sparts = split(s, '-');
20         for(vector<string>::iterator i=sparts.begin(); i!=sparts.end(); ++i)
21         {
22                 if(i->empty())
23                         throw invalid_argument("ArticleNumber::ArticleNumber");
24
25                 unsigned nondigit = i->size();
26                 for(unsigned j=0; j<i->size(); ++j)
27                         if(!isdigit((*i)[j]))
28                         {
29                                 nondigit = j;
30                                 break;
31                         }
32
33                 if(!nondigit || nondigit<i->size()-1)
34                         throw invalid_argument("ArticleNumber::ArticleNumber");
35
36                 Part part;
37                 part.number = lexical_cast<unsigned>(i->substr(0, nondigit));
38                 part.letter = nondigit<i->size() ? (*i)[nondigit] : 0;
39                 parts.push_back(part);
40         }
41 }
42
43 string ArticleNumber::str() const
44 {
45         string result;
46         for(vector<Part>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
47         {
48                 if(!result.empty())
49                         result += '-';
50
51                 result += lexical_cast<string>(i->number);
52                 if(i->letter)
53                         result += i->letter;
54         }
55
56         return result;
57 }
58
59 bool ArticleNumber::operator<(const ArticleNumber &other) const
60 {
61         return parts<other.parts;
62 }
63
64
65 bool ArticleNumber::Part::operator<(const Part &other) const
66 {
67         if(number!=other.number)
68                 return number<other.number;
69         return letter<other.letter;
70 }
71
72
73 void operator>>(const LexicalConverter &conv, ArticleNumber &art_nr)
74 {
75         art_nr = ArticleNumber(conv.get());
76 }
77
78 void operator<<(LexicalConverter &conv, const ArticleNumber &art_nr)
79 {
80         conv.result(art_nr.str());
81 }
82
83 } // namespace R2C2