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