⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isbnvalidator.cpp

📁 bookcase,by shell script and c++ and perl
💻 CPP
字号:
/***************************************************************************                          isbnvalidator.cpp  -  description                             -------------------    begin                : Sun Oct 6 2002    copyright            : (C) 2002 by Robby Stephenson    email                : robby@periapsis.org ***************************************************************************//*************************************************************************** *                                                                         * *   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;                            * *                                                                         * ***************************************************************************/#include "isbnvalidator.h"#include <kdebug.h>ISBNValidator::ISBNValidator(QObject* parent_, const char* name_/*=0*/)    : QValidator(parent_, name_) {//  buildValidGroupLookup();}QValidator::State ISBNValidator::validate(QString& input_, int& pos_) const {  //kdDebug() << "ISBNValidator::validate() - " << input_ << endl;  // could use QRegExp("(\\d-?){9}[\\dXx]") but it causes problems.  // For example, if "X" is the checksum and the user attempts to delete a  // digit from the number, the validator would not allow it because the "X" would  // then be in an invalid position. So allow an X anywhere for a string with less  // than 10 digits  // an ISBN must be less than 13 characters  // only allow digits, hyphens, and "X" or "x"  // only allow maximum of three hyphens  // only allow up to a single "X" or "x"  // the "X" or "x" can only be the last character  // only allow up to 10 digits  QRegExp validChars(QString::fromLatin1("[\\d-Xx]{0,13}"));  if(!validChars.exactMatch(input_)      || input_.contains(QString::fromLatin1("-")) > 3      || input_.contains(QString::fromLatin1("X"), false) > 1      || (input_.find(QString::fromLatin1("X"), 0, false) != -1          && input_.find(QString::fromLatin1("X"), 0, false) < input_.length()-1)      || input_.contains(QRegExp(QString::fromLatin1("\\d"))) > 10) {    return QValidator::Invalid;  }  // remember if the cursor is at the end  bool atEnd = (pos_ == input_.length());  // fix the case where the user attempts to delete a character from a non-checksum  // position; the solution is to delete the checksum, but only if it's X  if(pos_ != input_.length()      && input_.contains(QRegExp(QString::fromLatin1("-[Xx]$")))) {    input_.truncate(input_.length()-2);  }  // fix the case where the user attempts to delete the checksum; the  // solution is to delete the last digit as well  if(pos_ == input_.length()      && input_.contains(QRegExp(QString::fromLatin1("\\d"))) == 9      && input_[pos_-1] == '-') {    input_.truncate(input_.length()-2);    pos_ -= 2;  }  // now fixup the hyphens and maybe add a checksum  fixup(input_);  if(atEnd) {    pos_ = input_.length();  }    QRegExp re(QString::fromLatin1("(\\d-?){9}[\\dX]"));  if(re.exactMatch(input_)) {    return QValidator::Acceptable;  } else {    return QValidator::Intermediate;  }}void ISBNValidator::fixup(QString& input_) const {  //replace "x" with "X"  input_.replace(QRegExp(QString::fromLatin1("x")), QString::fromLatin1("X"));  // remove dashes  input_.replace(QRegExp(QString::fromLatin1("-")), QString());  // only add the checksum if more than 8 digits are present  if(input_.length() > 8) {    checkSum(input_);  }  insertDashes(input_);}void ISBNValidator::checkSum(QString& input_) const {  int sum = 0;  int multiplier = 10;  input_ = input_.left(9);  for(int i = 0; i < 9; ++i) {    sum += input_[i].digitValue() * multiplier--;  }  sum %= 11;  sum = 11-sum;  if(sum == 10) {    input_.append(QString::fromLatin1("X"));  } else if(sum == 11) {    input_.append(QString::fromLatin1("0"));  } else {    input_.append(QString::number(sum));  }}void ISBNValidator::insertDashes(QString& input_) const{  int range = input_.leftJustify(9, '0', true).toInt();  uint whereFirstDash = 0;  uint whereMidDash = 0;  uint whereLastDash = 9;  // how to format an ISBN, after categorising it into a range of numbers.  // number is high+1 for the band.  int bands[] = {    // --------0  0-00-bbbbbb-x group 0    20000000,    // --------1  0-200-bbbbb-x    70000000,    // --------2  0-7000-bbbb-x    85000000,    // --------3  0-85000-bbb-x    90000000,    // --------4  0-90000-bb-x    95000000,    // --------5  0-950000-b-x    100000000,    // --------6  1-1000-bbbb-x  group 1    155000000,    // --------7  1-55000-bbb-x    186980000,    // --------8  1-869800-bb-x    199900000,    // --------9  1-1999000-b-x    200000000,    // -------10  2-rrrrrrrr-x groups 2 .. 7    800000000,    // -------11  80-rrrrrrr-x groups 80 .. 94    950000000,    // -------12  950-rrrrrr-x groups 950 .. 995    996000000,    // -------13  9960-rrrrr-x groups 9960 .. 9989    999000000,    // -------14   groups 99900 .. 99999    1000000000  };  int band = 0;  for(uint i = 0; i < sizeof(bands)/sizeof(int); ++i) {    if(range < bands[i]) {      band = i;      break;    }  }  switch(band) {    /* cases 0..5 handle the standard publisher pattern, for group 0 */    case 0:      /* publisher 00 .. 19 : 0-00-bbbbbb-x */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 2;      break;    case 1:      /* publisher 200 .. 699 : 0-200-bbbbb-x */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 3;      break;    case 2:      /* publisher 7000 .. 8499 : 0-7000-bbbb-x */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 4;      break;    case 3:      /* publisher 85000 .. 89999 : 0-85000-bbb-x  */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 5;      break;    case 4:      /* publisher 900000 .. 94999 : 0-90000-bb-x */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 6;      break;    case 5:      /* publisher 9500000 .. 9999999 : 0-950000-b-x */      whereFirstDash = 1;      whereMidDash = whereFirstDash + 7;      break;      /* cases 6..9 : 1-1000-bbbb-x handle nonstandard publisher pattern of group-1 */    case 6:      whereFirstDash = 1;      whereMidDash = 5;      break;    case 7: /*  1-55000-bbb-x  */      whereFirstDash = 1;      whereMidDash = 6;      break;    case 8:  /* 1-55000-bbb-x */      whereFirstDash = 1;      whereMidDash = 7;      break;    case 9: /* 1-1999000-b-x */      whereFirstDash = 1;      whereMidDash = 8;      break;    case 10: /* group codes 2 .. 7 : 2-rrrrrrrr-x */      /* leave out dash between publisher and title */      whereFirstDash = 1;      break;    case 11: /* group codes 80 .. 94:  80-rrrrrrr-x */      /* leave out dash between publisher and title  */      whereFirstDash = 2;      break;    case 12: /* group codes 950..995 : 950-rrrrrr-x */      /* leave out dash between publisher and title */      whereFirstDash = 3;      break;    case 13: /* group codes 9960 .. 9989 : 9960-rrrrr-x */      /* leave out dash between publisher and title */      whereFirstDash = 4;      break;    case 14: /* group codes 99900 .. 99999 : 99900-rrrr-x */      whereFirstDash = 5;      break;    }  if(input_.length() > whereFirstDash) {    input_.insert(whereFirstDash, QString::fromLatin1("-"));    // 0 means the middle dash is not to be inserted    if(whereMidDash > 0) {      ++whereMidDash;    }    ++whereLastDash;  }  if(whereMidDash > 0 && input_.length() > whereMidDash) {    //add 1 since one "-" has already been inserted    input_.insert(whereMidDash, QString::fromLatin1("-"));    ++whereLastDash;  }  // add a "-" before the checkdigit  if(input_.length() > whereLastDash) {    input_.insert(whereLastDash, QString::fromLatin1("-"));  }}// not needed yet#if 0void ISBNValidator::buildValidGroupLookup() {  validGroupLookup.resize(100000);  for(int i = 0; i < numGroups; ++i) {    int group = validGroups[i];    int width = QString::number(group).length();    switch(width) {      case 5:        validGroupLookup.setBit(group);        break;      case 4:        for(int j = group*10; j < group*10+9; ++j) {          validGroupLookup.setBit(j);        }        break;      case 3:        for(int j = group*100; j < group*100+99; ++j) {          validGroupLookup.setBit(j);        }        break;      case 2:        for(int j = group*1000; j < group*1000+999; ++j) {          validGroupLookup.setBit(j);        }        break;      case 1:        for(int j = group*10000; j < group*10000+9999; ++j) {          validGroupLookup.setBit(j);        }        break;      default:        kdDebug() << "ISBNValidator::buildValidGroupLookup() - invalid group length" << endl;        break;    }  }}/* List of legal groups as of 5 October 2002   Taken from http://www.isbn.spk-berlin.de/html/prefix/allpref.htm  */const long ISBNValidator::validGroups[] = {      0,      1,      2,      3,      4,      5,      7,      80,      81,      82,      83,      84,      85,      86,      87,      88,      89,      90,      91,      92,      93,      950,      951,      952,      953,      954,      955,      956,      957,      958,      959,      960,      961,      962,      963,      964,      965,      966,      967,      968,      969,      970,      971,      972,      973,      974,      975,      976,      977,      978,      979,      980,      981,      982,      983,      984,      985,      986,      987,      988,      989,      9948,      9949,      9950,      9951,      9952,      9953,      9954,      9955,      9956,      9957,      9958,      9959,      9960,      9961,      9962,      9963,      9964,      9965,      9966,      9967,      9968,      9970,      9971,      9972,      9973,      9974,      9975,      9976,      9977,      9978,      9979,      9980,      9982,      9983,      9984,      9985,      9986,      9987,      9988,      9989,      99901,      99903,      99904,      99905,      99906,      99908,      99909,      99910,      99911,      99912,      99913,      99914,      99915,      99916,      99917,      99918,      99919,      99920,      99921,      99922,      99923,      99924,      99925,      99926,      99927,      99928,      99929,      99930,      99931,      99932,      99933,      99934,      99935,      99936,      99937,      99938,      99939,      99940   };const int ISBNValidator::numGroups = sizeof(ISBNValidator::validGroups)/sizeof(long);#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -