ftp.nice.ch/pub/next/database/plz/xplz.3.4.s.tar.gz#/xplz-3.4/strada.c

This is strada.c in view mode; [Download] [Up]

/* $Id: strada.c,v 3.1 1993/06/28 09:31:07 klute Exp klute $ */

/* 
 * Copyright 1993 Rainer Klute <klute@irb.informatik.uni-dortmund.de>
 *
 * Permission to use, copy, modify, distribute, and sell this software and
 * its documentation for any purpose is hereby granted without fee, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation. The author makes no representations about the suitability
 * of this software for any purpose. It is provided "as is" without express
 * or implied warranty.
 *
 */

#include <ctype.h>
#include <limits.h>
#include <malloc.h>
#include <memory.h>
#include <stdio.h>
#include <string.h>

#include "message.h"
#include "plzfile.h"
#include "strada.h"

#if defined (HANDLE_BROKEN_DATAFILES)
#define IbmToIso IbmAndBrokenToIso
#endif




static PlzFile strada = {(FILE *) 0, 0, 0, 0};




StradaSet *Strassenverzeichnis (char *alort)
{
    Range *foundEntries;
    StradaSet *result = (StradaSet *) malloc (sizeof (StradaSet));
    Strada *r;
    long pos;
    int i;

    if (result == (StradaSet *) 0)
    {
	OutOfMemory ("Strassenverzeichnis");
	return result;
    }

    OpenPlzFile (&strada, "strada");
    if (strada.f == (FILE *) 0)
	return (StradaSet *) 0;

    foundEntries = BinarySearchAll (strada.f, strada.recordLength, 0L,
				    strada.entries, 
				    ((Strada *) 0)->alort - 
				    ((Strada *) 0)->alort, 
				    sizeof (((Strada *) 0)->alort),
				    alort, -1,
				    userInterfaceMethods.StradaRecordRead,
				    &strada);
    Note ("\n");

    if (foundEntries == (Range *) 0)
	return (StradaSet *) 0;

    if (foundEntries->first == -1 && foundEntries->last == -1)
	result->entries = 0;
    else
	result->entries = foundEntries->last - foundEntries->first + 1;

    if (result->entries == 0)
    {
	free (foundEntries);
	result->list = (Strada *) 0;
	return result;
    }
    else
	result->list = (Strada *) malloc ((unsigned int) (result->entries * 
					sizeof (Strada) + 2));

    if (result->list == (Strada *) 0)
    {
	free (foundEntries);
	OutOfMemory ("Strassenverzeichnis");
	return (StradaSet *) 0;
    }

    pos = foundEntries->first;
    for (r = result->list, i = 0; i < result->entries; i++, r++)
    {
	fgetr (r, pos++, &strada);
    }
    free (foundEntries);
    return result;
}




StradaSet *StrassenAndOrtsteil (StradaSet *stradaSet, char *ortsteil)
{
    StradaSet *result = (StradaSet *) malloc (sizeof (StradaSet));
    Strada *r;
    char buffer[sizeof (((Strada *) 0)->ortsteil) + 1];
    char *help1;
    char *help2;
    int i;

    if (result == (StradaSet *) 0)
    {
	OutOfMemory ("AndOrtsteil");
	return result;
    }
    result->list = (Strada *) calloc (stradaSet->entries, sizeof (Strada));
    if (result->list == (Strada *) 0)
    {
	OutOfMemory ("SearchForArea");
	free (result);
	return (StradaSet *) 0;
    }

    r = result->list;
    for (i = 0; i < stradaSet->entries; i++)
    {
	strncpy (buffer, stradaSet->list[i].ortsteil, 
		 sizeof (stradaSet->list[i].ortsteil));
	buffer[sizeof (stradaSet->list[i].ortsteil)] = '\0';
	StripBlanks (buffer);
	help1 = IbmToIso (buffer);
	help2 = IsoToCapitals (help1);
	free (help1);
	help1 = IsoToCapitals (ortsteil);
	if (strcmp (help1, help2) == 0)
	    memcpy ((char *) r++, (char *) &(stradaSet->list[i]),
		    sizeof (Strada));
	free (help1);
	free (help2);
    }
    result->entries = r - result->list;
    return result;
}




StradaSet *StrassenAndPostanstalt (StradaSet *stradaSet, char *postanstalt)
{
    StradaSet *result = (StradaSet *) malloc (sizeof (StradaSet));
    Strada *r;
    int i;

    if (result == (StradaSet *) 0)
    {
	OutOfMemory ("StrassenAndPostanstalt");
	return result;
    }
    result->list = (Strada *) calloc (stradaSet->entries, sizeof (Strada));
    if (result->list == (Strada *) 0)
    {
	OutOfMemory ("StrassenAndPostanstalt");
	free (result);
	return (StradaSet *) 0;
    }

    r = result->list;
    for (i = 0; i < stradaSet->entries; i++)
    {
	if (strntoi (stradaSet->list[i].npanst, 
		     sizeof (stradaSet->list[i].npanst)) == atoi (postanstalt))
	    memcpy ((char *) r++, (char *) &(stradaSet->list[i]), 
		    sizeof (Strada));
    }
    result->entries = r - result->list;
    return result;
}




StradaSet *SearchForArea (StradaSet *stradaSet, char *zustellamt, 
			  char *ortsteil)
{
    StradaSet *result = (StradaSet *) malloc (sizeof (StradaSet));
    Strada *r;
    char *help1, *help2;
    int i;
    Boolean matchZustellamt;
    Boolean matchOrtsteil;

    if (result == (StradaSet *) 0)
    {
	OutOfMemory ("SearchForArea");
	return result;
    }
    result->list = (Strada *) calloc (stradaSet->entries, sizeof (Strada));
    if (result->list == (Strada *) 0)
    {
	OutOfMemory ("SearchForArea");
	free (result);
	return (StradaSet *) 0;
    }

    r = result->list;
    for (i = 0; i < stradaSet->entries; i++)
    {
	matchZustellamt = matchOrtsteil = False;

	if (*zustellamt)
	{
	    if (strntoi (stradaSet->list[i].npanst, 
	    sizeof (stradaSet->list[i].npanst)) == atoi (zustellamt))
		matchZustellamt = True;
	}
	else
	    matchZustellamt = True;

	if (*ortsteil)
	{
	    char buffer[100];
	    strncpy (buffer, stradaSet->list[i].ortsteil, 
		     sizeof (stradaSet->list[i].ortsteil));
	    buffer[sizeof (stradaSet->list[i].ortsteil)] = '\0';
	    StripBlanks (buffer);
	    help1 = IbmToIso (buffer);
	    help2 = IsoToCapitals (help1);
	    free (help1);
	    help1 = IsoToCapitals (ortsteil);
	    if (strcmp (help1, help2) == 0)
		matchOrtsteil = True;
	    free (help1);
	    free (help2);
	}
	else
	    matchOrtsteil = True;

	if (matchZustellamt && matchOrtsteil)
	    memcpy ((char *) r++, (char *) &(stradaSet->list[i]), 
		    sizeof (Strada));
    }
    result->entries = r - result->list;
    return result;
}





StradaSet *SucheStrasse (char *alort, char *street)
{
    static Shortcut abk[] =
    {
	{"Str.",     "Strasse"},
	{"str.",     "strasse"},
	{"STR.",     "STRASSE"},
	{"V.",       "Von"},
	{"v.",       "von"},
	{"St.",      "Sankt"},
	{"st.",      "sankt"},
	{"ST.",      "SANKT"},
	{"dr.",      "doktor"},
	{"Dr.",      "Doktor"},
	{"DR.",      "DOKTOR"},
	{(char *) 0, (char *) 0},
    };

    Range *foundEntries;
    Range help;
    StradaSet *result = (StradaSet *) malloc (sizeof (StradaSet));
    Strada *r;
    char *help1, *help2;
    long pos;
    int i;

    if (result == (StradaSet *) 0)
    {
	OutOfMemory ("SucheStrasse");
	return result;
    }

    OpenPlzFile (&strada, "strada");
    if (strada.f == (FILE *) 0)
	return (StradaSet *) 0;

    foundEntries = BinarySearchAll (strada.f, strada.recordLength, 0L,
				    strada.entries, 
				    ((Strada *) 0)->alort - 
				    ((Strada *) 0)->alort, 
				    sizeof (((Strada *) 0)->alort),
				    alort, -1,
				    userInterfaceMethods.StradaRecordRead, 
				    &strada);
    Note ("\n");

    help2 = AbkuerzungenExpandieren (street, abk);
    help1 = IsoToCapitals (help2);
    free (help2);
    help2 = CStringToFixed (help1, sizeof (((Strada *) 0)->snamesort));
    free (help1);
    help.first = foundEntries->first;
    help.last = foundEntries->last;
    free (foundEntries);
    foundEntries = BinarySearchAll (strada.f, strada.recordLength, 
				    help.first, help.last,
				    ((Strada *) 0)->snamesort - 
				    ((Strada *) 0)->alort, 
				    sizeof (((Strada *) 0)->snamesort),
				    help2, -1,
				    userInterfaceMethods.StradaRecordRead,
				    &strada);
    free (help2);
    if (foundEntries == (Range *) 0)
	return (StradaSet *) 0;

    if (foundEntries->first == -1 && foundEntries->last == -1)
	result->entries = 0;
    else
	result->entries = foundEntries->last - foundEntries->first + 1;

    if (result->entries == 0)
    {
	free (foundEntries);
	result->list = (Strada *) 0;
	return result;
    }
    else
	result->list = (Strada *) malloc ((unsigned int) (result->entries * 
					sizeof (Strada) + 2));

    if (result->list == (Strada *) 0)
    {
	free (foundEntries);
	OutOfMemory ("SucheStrasse");
	return (StradaSet *) 0;
    }

    pos = foundEntries->first;
    for (r = result->list, i = 0; i < result->entries; i++, r++)
    {
	fgetr (r, pos++, &strada);
    }
    free (foundEntries);
    return result;
}




static void StrToUpper (char *s)
{
    while (*s)
    {
	if (islower (*s))
	    *s = toupper (*s);
	s++;
    }
}




static Boolean Between (int from, char *fromZusatz, int number, char *zusatz,
			int to, char *toZusatz)
{
    if (from > number)
	return False;
    if (from == number)
    {
	while (*fromZusatz == ' ')
	    fromZusatz++;
	StrToUpper (fromZusatz);
	while (*zusatz == ' ')
	    zusatz++;
	StrToUpper (zusatz);
	if (strcmp (fromZusatz, zusatz) > 0)
	    return False;
    }
    if (number > to)
	return False;
    if (number == to)
    {
	while (*toZusatz == ' ')
	    toZusatz++;
	StrToUpper (toZusatz);
	while (*zusatz == ' ')
	    zusatz++;
	StrToUpper (zusatz);
	if (strcmp (zusatz, toZusatz) > 0)
	    return False;
    }
    return True;
}




char *SearchForHouseNumber (StradaSet *stradaSet, char *houseNumber)
{
    int i, j;
    Strada *s;
    static char plz[6];
    int number;
    int from;
    int to;
    char fromZusatz[sizeof (s->hnr2von) + 1];
    char toZusatz[sizeof (s->hnr2bis) + 1];
    Boolean even;
    Boolean found = False;
    char zusatz[sizeof (s->hnr2von) + 1];

    number = strntoi (houseNumber, 4);
    for (; isdigit (*houseNumber); houseNumber++)
	;
    strcpy (zusatz, houseNumber);
 
    even = (number >> 1) << 1 == number;

    *plz = '\0';
    for (s = stradaSet->list, i = 0; i < stradaSet->entries && !found;
         i++, s++)
    {
	if (s->hnr1von[sizeof (s->hnr1von) - 1] == ' ')
	    from = INT_MIN;
	else
	    from = strntoi (s->hnr1von, sizeof (s->hnr1von));
	strncpy (fromZusatz, s->hnr2von, sizeof (s->hnr2von));
	fromZusatz[sizeof (s->hnr2von)] = '\0';

	if (s->hnr1bis[sizeof (s->hnr1bis) - 1] == ' ')
	    to = INT_MAX;
	else
	    to = strntoi (s->hnr1bis, sizeof (s->hnr1bis));
	if (strncmp (s->hnr2bis, "Ende", sizeof (s->hnr2bis)) == 0)
	    for (j = 0; j < sizeof (s->hnr2bis); j++)
		toZusatz[j] = 0xff;
	else
	{
	    strncpy (toZusatz, s->hnr2bis, sizeof (s->hnr2bis));
	    toZusatz[sizeof (s->hnr2bis)] = '\0';
	}

	switch (s->hnrkenn[0])
	{
	    case '0':
	    {
		if (Between (from, fromZusatz, number, zusatz, to, toZusatz))
		    found = True;
		break;
	    }
	    case '1':
	    {
		if (even
		&& Between (from, fromZusatz, number, zusatz, to, toZusatz))
		    found = True;
		break;
	    }
	    case '2':
	    {
		if (!even 
		&& Between (from, fromZusatz, number, zusatz, to, toZusatz))
		    found = True;
		break;
	    }
	}
    }
    if (!found)
	return "";
    else
    {
	s--;
	strncpy (plz, s->plz_z, sizeof (s->plz_z));
	plz[sizeof (s->plz_z)] = '\0';
	return plz;
    }
}	




Boolean UniqueStreet (StradaSet *stradaSet)
{
    Strada *s;
    int i;
    int number;
    char sname[sizeof (s->sname)];

    s = stradaSet->list;
    strncpy (sname, s->sname, sizeof (s->sname));
    number = strntoi (s->strlfdnr, sizeof (s->strlfdnr));
    for (i = 1, s++; i < stradaSet->entries; i++, s++)
	if (strntoi (s->strlfdnr, sizeof (s->strlfdnr)) != number
	|| strncmp (sname, s->sname, sizeof (s->sname)) != 0)
	    return False;
    return True;
}



Boolean IsStrassePlzEindeutig (StradaSet *stradaSet)
{
    return UniqueStreet (stradaSet) && *(stradaSet->list->nplz_z) == '1'; 
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.