isbn.c
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:3k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. /*
  2.  * PostgreSQL type definitions for ISBNs.
  3.  *
  4.  * $Id: isbn.c,v 1.2 1999/05/25 16:05:40 momjian Exp $
  5.  */
  6. #include <stdio.h>
  7. #include <postgres.h>
  8. #include <utils/palloc.h>
  9. /*
  10.  * This is the internal storage format for ISBNs.
  11.  * NB: This is an intentional type pun with builtin type `char16'.
  12.  */
  13. typedef struct isbn
  14. {
  15. char num[13];
  16. char pad[3];
  17. } isbn;
  18. /*
  19.  * Various forward declarations:
  20.  */
  21. isbn    *isbn_in(char *str);
  22. char    *isbn_out(isbn * addr);
  23. bool isbn_lt(isbn * a1, isbn * a2);
  24. bool isbn_le(isbn * a1, isbn * a2);
  25. bool isbn_eq(isbn * a1, isbn * a2);
  26. bool isbn_ge(isbn * a1, isbn * a2);
  27. bool isbn_gt(isbn * a1, isbn * a2);
  28. bool isbn_ne(isbn * a1, isbn * a2);
  29. int4 isbn_cmp(isbn * a1, isbn * a2);
  30. int4 isbn_sum(char *str);
  31. /*
  32.  * ISBN reader.
  33.  */
  34. isbn *
  35. isbn_in(char *str)
  36. {
  37. isbn    *result;
  38. char    *cp;
  39. int count;
  40. if (strlen(str) != 13)
  41. {
  42. elog(ERROR, "isbn_in: invalid ISBN "%s"", str);
  43. return (NULL);
  44. }
  45. if (isbn_sum(str) != 0)
  46. {
  47. elog(ERROR, "isbn_in: purported ISBN "%s" failed checksum",
  48.  str);
  49. return (NULL);
  50. }
  51. result = (isbn *) palloc(sizeof(isbn));
  52. strncpy(result->num, str, 13);
  53. memset(result->pad, ' ', 3);
  54. return (result);
  55. }
  56. /*
  57.  * The ISBN checksum is defined as follows:
  58.  *
  59.  * Number the digits from 1 to 9 (call this N).
  60.  * Compute the sum, S, of N * D_N.
  61.  * The check digit, C, is the value which satisfies the equation
  62.  * S + 10*C === 0 (mod 11)
  63.  * The value 10 for C is written as `X'.
  64.  *
  65.  * For our purposes, we want the complete sum including the check
  66.  * digit; if this is zero, then the checksum passed.  We also check
  67.  * the syntactic validity if the provided string, and return 12
  68.  * if any errors are found.
  69.  */
  70. int4
  71. isbn_sum(char *str)
  72. {
  73. int4 sum = 0,
  74. dashes = 0,
  75. val;
  76. int i;
  77. for (i = 0; str[i] && i < 13; i++)
  78. {
  79. switch (str[i])
  80. {
  81. case '-':
  82. if (++dashes > 3)
  83. return 12;
  84. continue;
  85. case '0':
  86. case '1':
  87. case '2':
  88. case '3':
  89. case '4':
  90. case '5':
  91. case '6':
  92. case '7':
  93. case '8':
  94. case '9':
  95. val = str[i] - '0';
  96. break;
  97. case 'X':
  98. case 'x':
  99. val = 10;
  100. break;
  101. default:
  102. return 12;
  103. }
  104. sum += val * (i + 1 - dashes);
  105. }
  106. return (sum % 11);
  107. }
  108. /*
  109.  * ISBN output function.
  110.  */
  111. char *
  112. isbn_out(isbn * num)
  113. {
  114. char    *result;
  115. if (num == NULL)
  116. return (NULL);
  117. result = (char *) palloc(14);
  118. result[0] = '';
  119. strncat(result, num->num, 13);
  120. return (result);
  121. }
  122. /*
  123.  * Boolean tests for magnitude.
  124.  */
  125. bool
  126. isbn_lt(isbn * a1, isbn * a2)
  127. {
  128. return (strncmp(a1->num, a2->num, 13) < 0);
  129. };
  130. bool
  131. isbn_le(isbn * a1, isbn * a2)
  132. {
  133. return (strncmp(a1->num, a2->num, 13) <= 0);
  134. };
  135. bool
  136. isbn_eq(isbn * a1, isbn * a2)
  137. {
  138. return (strncmp(a1->num, a2->num, 13) == 0);
  139. };
  140. bool
  141. isbn_ge(isbn * a1, isbn * a2)
  142. {
  143. return (strncmp(a1->num, a2->num, 13) >= 0);
  144. };
  145. bool
  146. isbn_gt(isbn * a1, isbn * a2)
  147. {
  148. return (strncmp(a1->num, a2->num, 13) > 0);
  149. };
  150. bool
  151. isbn_ne(isbn * a1, isbn * a2)
  152. {
  153. return (strncmp(a1->num, a2->num, 13) != 0);
  154. };
  155. /*
  156.  * Comparison function for sorting:
  157.  */
  158. int4
  159. isbn_cmp(isbn * a1, isbn * a2)
  160. {
  161. return (strncmp(a1->num, a2->num, 13));
  162. }
  163. /*
  164.  * eof
  165.  */