/* must always start with a digit: */ if (!isdigit((unsignedchar) *aux1) || !isdigit((unsignedchar) *aux2)) goto invalidtable;
a = *aux1 - '0';
b = *aux2 - '0';
/* must always have the same format and length: */ while (*aux1 && *aux2)
{ if (!(isdigit((unsignedchar) *aux1) &&
isdigit((unsignedchar) *aux2)) &&
(*aux1 != *aux2 || *aux1 != '-')) goto invalidtable;
aux1++;
aux2++;
} if (*aux1 != *aux2) goto invalidtable;
/* found a new range */ if (a > y)
{ /* check current range in the index: */ for (j = x; j <= y; j++)
{ if (TABLE_index[j][0] != init) goto invalidindex; if (TABLE_index[j][1] != i - init) goto invalidindex;
}
init = i;
x = a;
}
/* Always get the new limit */
y = b; if (y < x) goto invalidtable;
i++;
}
/* just compress the string if no further hyphenation is required */ if (TABLE == NULL || TABLE_index == NULL)
{ while (*bufI)
{
*bufO++ = *bufI++;
ret++;
}
*bufO = '\0'; return (ret + 1);
}
ean >>= 1; /* verify it's in the EAN13 range */ if (ean > UINT64CONST(9999999999999)) goto eantoobig;
/* convert the number */
search = 0;
aux = buf + 13;
*aux = '\0'; /* terminate string; aux points to last digit */ do
{
digval = (unsigned) (ean % 10); /* get the decimal value */
ean /= 10; /* get next digit */
*--aux = (char) (digval + '0'); /* convert to ascii and store */
} while (ean && search++ < 12); while (search++ < 12)
*--aux = '0'; /* fill the remaining EAN13 with '0' */
/* find out the data type: */ if (strncmp("978", buf, 3) == 0)
{ /* ISBN */
type = ISBN;
} elseif (strncmp("977", buf, 3) == 0)
{ /* ISSN */
type = ISSN;
} elseif (strncmp("9790", buf, 4) == 0)
{ /* ISMN */
type = ISMN;
} elseif (strncmp("979", buf, 3) == 0)
{ /* ISBN-13 */
type = ISBN;
} elseif (*buf == '0')
{ /* UPC */
type = UPC;
} else
{
type = EAN13;
} if (accept != ANY && accept != EAN13 && accept != type) goto eanwrongtype;
*result = ret; returntrue;
eanwrongtype: if (!errorOK)
{ if (type != EAN13)
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("cannot cast EAN13(%s) to %s for number: \"%s\"",
isn_names[type], isn_names[accept], buf)));
} else
{
ereport(ERROR,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("cannot cast %s to %s for number: \"%s\"",
isn_names[type], isn_names[accept], buf)));
}
} returnfalse;
eantoobig: if (!errorOK)
{ char eanbuf[64];
/* *Formatthenumberseparatelytokeepthemachine-dependentformat *codeoutofthetranslatablemessagetext
*/
snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for %s type",
eanbuf, isn_names[type])));
} returnfalse;
}
/* *Thenumbershouldcomeinthisformat:978-0-000-00000-0ormaybean *ISBN-13number,979-...,whichdoesnothaveashortrepresentation.Do *theshortoutputversionifpossible.
*/ if (strncmp("978-", isn, 4) == 0)
{ /* Strip the first part and calculate the new check digit */
hyphenate(isn, isn + 4, NULL, NULL);
check = weight_checkdig(isn, 10);
aux = strchr(isn, '\0'); while (!isdigit((unsignedchar) *--aux)); if (check == 10)
*aux = 'X'; else
*aux = check + '0';
}
}
staticinlinevoid
ean2ISMN(char *isn)
{ /* the number should come in this format: 979-0-000-00000-0 */ /* Just strip the first part and change the first digit ('0') to 'M' */
hyphenate(isn, isn + 4, NULL, NULL);
isn[0] = 'M';
}
/* the number should come in this format: 977-0000-000-00-0 */ /* Strip the first part, crop, and calculate the new check digit */
hyphenate(isn, isn + 4, NULL, NULL);
check = weight_checkdig(isn, 8); if (check == 10)
isn[8] = 'X'; else
isn[8] = check + '0';
isn[9] = '\0';
}
staticinlinevoid
ean2UPC(char *isn)
{ /* the number should come in this format: 000-000000000-0 */ /* Strip the first part, crop, and dehyphenate */
dehyphenate(isn, isn + 1);
isn[12] = '\0';
}
char *aux; unsigned digval; unsigned search; char valid = '\0'; /* was the number initially written with a
* valid check digit? */
TABLE_index = ISBN_index;
if ((ean & 1) != 0)
valid = '!';
ean >>= 1; /* verify it's in the EAN13 range */ if (ean > UINT64CONST(9999999999999)) goto eantoobig;
/* convert the number */
search = 0;
aux = result + MAXEAN13LEN;
*aux = '\0'; /* terminate string; aux points to last digit */
*--aux = valid; /* append '!' for numbers with invalid but
* corrected check digit */ do
{
digval = (unsigned) (ean % 10); /* get the decimal value */
ean /= 10; /* get next digit */
*--aux = (char) (digval + '0'); /* convert to ascii and store */ if (search == 0)
*--aux = '-'; /* the check digit is always there */
} while (ean && search++ < 13); while (search++ < 13)
*--aux = '0'; /* fill the remaining EAN13 with '0' */
/* The string should be in this form: ???DDDDDDDDDDDD-D" */
search = hyphenate(result, result + 3, EAN13_range, EAN13_index);
/* verify it's a logically valid EAN13 */ if (search == 0)
{
search = hyphenate(result, result + 3, NULL, NULL); goto okay;
}
/* find out what type of hyphenation is needed: */ if (strncmp("978-", result, search) == 0)
{ /* ISBN -13 978-range */ /* The string should be in this form: 978-??000000000-0" */
type = ISBN;
TABLE = ISBN_range;
TABLE_index = ISBN_index;
} elseif (strncmp("977-", result, search) == 0)
{ /* ISSN */ /* The string should be in this form: 977-??000000000-0" */
type = ISSN;
TABLE = ISSN_range;
TABLE_index = ISSN_index;
} elseif (strncmp("979-0", result, search + 1) == 0)
{ /* ISMN */ /* The string should be in this form: 979-0?000000000-0" */
type = ISMN;
TABLE = ISMN_range;
TABLE_index = ISMN_index;
} elseif (strncmp("979-", result, search) == 0)
{ /* ISBN-13 979-range */ /* The string should be in this form: 979-??000000000-0" */
type = ISBN;
TABLE = ISBN_range_new;
TABLE_index = ISBN_index_new;
} elseif (*result == '0')
{ /* UPC */ /* The string should be in this form: 000-00000000000-0" */
type = UPC;
TABLE = UPC_range;
TABLE_index = UPC_index;
} else
{
type = EAN13;
TABLE = NULL;
TABLE_index = NULL;
}
/* verify it's a valid EAN13 */ if (search == 0)
{
search = hyphenate(result + digval, result + digval + 2, NULL, NULL); goto okay;
}
okay: /* convert to the old short type: */ if (shortType) switch (type)
{ case ISBN:
ean2ISBN(result); break; case ISMN:
ean2ISMN(result); break; case ISSN:
ean2ISSN(result); break; case UPC:
ean2UPC(result); break; default: break;
} returntrue;
eantoobig: if (!errorOK)
{ char eanbuf[64];
/* *Formatthenumberseparatelytokeepthemachine-dependentformat *codeoutofthetranslatablemessagetext
*/
snprintf(eanbuf, sizeof(eanbuf), EAN13_FORMAT, ean);
ereport(ERROR,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for %s type",
eanbuf, isn_names[type])));
} returnfalse;
}
eanbadcheck: if (g_weak)
{ /* weak input mode is activated: */ /* set the "invalid-check-digit-on-input" flag */
*result = str2ean(aux1);
*result |= 1; returntrue;
}
eanwrongtype:
ereturn(escontext, false,
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
errmsg("cannot cast %s to %s for number: \"%s\"",
isn_names[type], isn_names[accept], str)));
eantoobig:
ereturn(escontext, false,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("value \"%s\" is out of range for %s type",
str, isn_names[accept])));
}
if (!string2ean(str, fcinfo->context, &result, UPC))
PG_RETURN_NULL();
PG_RETURN_EAN13(result);
}
/* casting functions
*/
PG_FUNCTION_INFO_V1(isbn_cast_from_ean13);
Datum
isbn_cast_from_ean13(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
ean13 result;
(void) ean2isn(val, false, &result, ISBN);
PG_RETURN_EAN13(result);
}
PG_FUNCTION_INFO_V1(ismn_cast_from_ean13);
Datum
ismn_cast_from_ean13(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
ean13 result;
(void) ean2isn(val, false, &result, ISMN);
PG_RETURN_EAN13(result);
}
PG_FUNCTION_INFO_V1(issn_cast_from_ean13);
Datum
issn_cast_from_ean13(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
ean13 result;
(void) ean2isn(val, false, &result, ISSN);
PG_RETURN_EAN13(result);
}
PG_FUNCTION_INFO_V1(upc_cast_from_ean13);
Datum
upc_cast_from_ean13(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
ean13 result;
(void) ean2isn(val, false, &result, UPC);
PG_RETURN_EAN13(result);
}
/* is_valid - returns false if the "invalid-check-digit-on-input" is set
*/
PG_FUNCTION_INFO_V1(is_valid);
Datum
is_valid(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
PG_RETURN_BOOL((val & 1) == 0);
}
/* make_valid - unsets the "invalid-check-digit-on-input" flag
*/
PG_FUNCTION_INFO_V1(make_valid);
Datum
make_valid(PG_FUNCTION_ARGS)
{
ean13 val = PG_GETARG_EAN13(0);
val &= ~((ean13) 1);
PG_RETURN_EAN13(val);
}
/* this function temporarily sets weak input flag *(tolosethestrictnessofcheckdigitacceptance)
*/
PG_FUNCTION_INFO_V1(accept_weak_input);
Datum
accept_weak_input(PG_FUNCTION_ARGS)
{ bool newvalue = PG_GETARG_BOOL(0);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.