summaryrefslogtreecommitdiffstats
path: root/src/isbnvalidator.h
blob: 56e324e10049becb6a6e5753f3c0abdd866fe8f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/***************************************************************************
    copyright            : (C) 2002-2006 by Robby Stephenson
    email                : [email protected]
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License as  *
 *   published by the Free Software Foundation;                            *
 *                                                                         *
 ***************************************************************************/

#ifndef ISBNVALIDATOR_H
#define ISBNVALIDATOR_H

#include <tqvalidator.h>

namespace Tellico {

/**
 * @author Robby Stephenson
 *
 * @see http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp
 * @see http://www.eblong.com/zarf/bookscan/
 * @see http://doc.trolltech.com/qq/qq01-seriously-weird-qregexp.html
 */
class ISBNValidator : public TQValidator {
public:
  ISBNValidator(TQObject* parent, const char* name=0);

  /**
   * Certain conditions are checked. Character, length and position
   * restrictions are checked. Certain cases where the user is deleting
   * characters are caught and compensated for. The string is then passed to
   * @ref fixup. Finally, the text is @ref Valid if it is a certain length and
   * @ref Intermediate if not.
   *
   * @param input The text to validate
   * @param pos The position of the cursor
   * @return The condition of the text
   */
  virtual TQValidator::State validate(TQString& input, int& pos) const;

  /**
   * The input string is examined. Hyphens are inserted appropriately,
   * and the checksum is calculated.
   *
   * For correct presentation, the 10 digits of an ISBN must
   * be divided, by hyphens, into four parts:
   * @li Part 1: The country or group of countries identifier
   * @li Part 2: The publisher identifier
   * @li Part 3: The title identifier
   * @li Part 4: The check digit
   * For details
   * @see http://www.isbn.org/standards/home/isbn/international/hyphenation-instructions.asp
   * For info on group codes
   * @see http://www.isbn.spk-berlin.de/html/prefix/allpref.htm
   * For info on French language publisher codes
   * @see http://www.afnil.org
   * <pre>
   *  Group Identifiers    First Hyphen After
   *  -----------------------------------------
   *  0........7              1st digit
   *  80.......94             2nd   "
   *  950......993            3rd   "
   *  9940.....9989           4th   "
   *  99900....99999          5th   "
   *
   *  Group                   Insert Hyphens
   *  Identifier "0"            After
   *  -----------------------------------------
   *  00.......19          1st  3rd  9th digit
   *  200......699          "   4th       "
   *  7000.....8499         "   5th       "
   *  85000....89999        "   6th       "
   *  900000...949999       "   7th       "
   *  9500000..9999999      "   8th       "
   *
   *
   *  Group                  Insert Hyphens
   *  Identifier "1"           After
   *  ----------------------------------------
   *  0........54999           illegal
   *  55000....86979      1st  6th  9th digit
   *  869800...998999      "   7th       "
   *  9990000..9999999     "   8th       "
   *
   *
   *  Group                   Insert Hyphens
   *  Identifier "2"            After
   *  -----------------------------------------
   *  00.......19          1st  3rd  9th digit
   *  200......349          "   4th       "
   *  34000....39999        "   6th       "
   *  400......699          "   4th       "
   *  7000.....8399         "   5th       "
   *  84000....89999        "   6th       "
   *  900000...949999       "   7th       "
   *  9500000..9999999      "   8th       "
   *
   *  The position of the hyphens are determined by the publisher
   *  prefix range established by each national agency in accordance
   *  with the industry needs. The knowledge of the prefix ranges for
   *  each country or group of countries is necessary to develop the
   *  hyphenation output program. For groups 3 through 99999, the hyphenation
   *  rules are currently unknown. So just leave out the hyphen between
   *  the publisher and title for now, but allow it if the user inserts it.
   * </pre>
   *
   * @param input The raw string, hyphens included
   */
  virtual void fixup(TQString& input) const;
  static void staticFixup(TQString& input);

  static TQString isbn10(TQString isbn13);
  static TQString isbn13(TQString isbn10);
  static TQString cleanValue(TQString isbn);

private:
  static struct isbn_band {
    unsigned long MaxValue;
    unsigned int First;
    unsigned int Mid;
    unsigned int Last;
  } bands[];

  TQValidator::State validate10(TQString& input, int& pos) const;
  TQValidator::State validate13(TQString& input, int& pos) const;

  static void fixup10(TQString& input);
  static void fixup13(TQString& input);

  /**
   * This function calculates and returns the ISBN checksum. The
   * algorithm is based on some code by Andrew Plotkin, available at
   * http://www.eblong.com/zarf/bookscan/
   *
   * @see http://www.eblong.com/zarf/bookscan/
   *
   * @param input The raw string, with no hyphens
   */
  static TQChar checkSum10(const TQString& input);
  static TQChar checkSum13(const TQString& input);
};

} // end namespace
#endif