Source file: /~heha/basteln/Haus/Telefon/CLIP-Anzeige/vorwahl.zip/MSVC/vorwahl.cpp

#include "vorwahl.h"
// C++-Implementierung
#ifdef __AVR__
# include <avr/pgmspace.h>
#else
# define PROGMEM
# define pgm_read_byte(x) *(x)
# define pgm_read_word(x) *(x)
#endif

#define elemof(x) (sizeof(x)/sizeof(*(x)))

namespace Vorwahl{

char len_intl(const char*n) {
 char z1=n[0]&15,z2=n[1]&15,z3=n[2]&15,z4=n[3]&15;
 switch (z1) {
  case 1: {	// USA und Inseln
   unsigned short npa=z2<<8|z3<<4|z4;
   PROGMEM static const unsigned short npas[]={
    0x242,0x246,0x264,0x268,	// 1242 Bahamas ...
    0x340,0x345,		// 1340	Amerikanische Jungferninseln ...
    0x441,0x473,		// 1441	Bermuda ...
    0x649,0x664,0x670,0x671,0x684,	// 1649	Turks- und Caicosinseln ...
    0x721,0x758,0x767,0x784,0x787,	// 1721	Sint Maarten ...
    0x808,0x809,0x829,0x868,0x869,	// 1809	Dominikanische Republik ...
    0x876,0x939};		// 1876	Jamaika ...
   for (const unsigned short*it=npas; it!=npas+elemof(npas); it++)
     if (pgm_read_word(it)==npa) return 4;
  }return 1;
  case 2: return z2==0 || z2==7 ? 2 : 3;	// Afrika
  case 3: return z2==5 || z2==7 || z2==8 ? 3 : 2;	// Europa I
  case 4: return z2==2 ? 3 : 2;	// Europa II
  case 5: return z2==0 || z2==9 ? 3 : 2;	// Lateinamerika
  case 6: return z2>=7 ? 3 : 2;	// Asien I
  case 7: if (z2>=8 && z3==4) return 3;	// GUS: Abchasien
  if (z2==6 || z2==7) return 3;	// GUS: Kasachstan
  return 1;
  case 8: return z2==5 || z2==8 ? 3 : 2;	// Asien II
  case 9: return z2>=6 && z2!=8 ? 3 : 2;	// Nahost
  default: return 0;		// Fehler: Kein Land fängt mit 0 an!
 }
}

// Das Schema vieler Ex-DDR-Vorwahlen ist, dass
// Nummern mit '0' an vierter Stelle stets 5, mit '1' an vierter Stelle stets 4,
// und mit sonstigen Ziffern 4 oder 5 Ziffern lang ist.
// Dadurch genügt ein Byte als Maske für die Ziffern '2' bis '9'
static char ost(char z4,unsigned char m) {
 if (z4==0) return 5;
 if (z4==1) return 4;
 return 4 + (m>>(z4-2) & 1);
}

// Nummern mit '1' oder '5' an dritter Stelle haben 3 Stellen.
// Alle anderen (8 möglichen Ziffern) siehe oben, daher Tabelle aus 8 Bytes
static char ost(char z3, char z4, const unsigned char m[8]) {
 if (z3==1 || z3==5) return 3;		// 3x1, 3x5
 if (z3>1) --z3; if (z3>4) --z3;	// 0,2,3,4,6,7,8,9 zur Bitadressierung
 return ost(z4,pgm_read_byte(m+z3));
}

char len_de(const char*n) {
 char z1=n[0]&15,z2=n[1]&15,z3=n[2]&15,z4=n[3]&15;
 switch (z1) {
  case 0: return 0;		// Fehler: Keine Ortsvorwahl beginnt mit 0
  case 1: return 3+(z2==5);	// Handynummern
  case 2: switch (z2) {
   case 0: return z3>=4 || z3<=6 ? 4 : 3;
   case 1:					//211 Düsseldorf, 214 Leverkusen
   case 3: if (z3==4) return 3; goto west;	//231 Dortmund, 234 Bochum
   case 2: if (z3==8) return 3; goto west;	//221 Köln, 228 Bonn
   default: goto west;	//241 Aachen, 251 Münster, 261 Koblenz, 271 Siegen, 281 Wesel, 291 Meschede
  }
  case 3: {
   if (z2<=2) return 2;	// 30, 32 Berlin
   if (z2==8 && z3==6) return 4;	// Ausnahme: 386x nur 4 Ziffern, auch für x==0
   PROGMEM static const unsigned char o[][8]={
	{0xC8,0x02,0x92,0x2A,0x2A,0x16,0x26,0x73},	// 331 Potsdam, 335 Frankfurt/O
	{0x00,0x95,0x55,0x95,0xAA,0x65,0x00,0x29},	// 341 Leipzig, 345 Halle	// 340, 348 gibt's nicht
	{0x0B,0x14,0x55,0x2A,0x80,0xA9,0xA5,0x2A},	// 351 Dresden, 355 Cottbus
	{0x65,0x08,0x22,0x59,0x89,0x56,0x24,0x15},	// 361 Erfurt, 365 Gera
	{0x00,0x80,0x55,0x13,0x00,0x08,0x00,0x00},	// 371 Chemnitz, 375 Zwickau	// 370, 378, 379 gibt's nicht
	{0x00,0x83,0xAB,0x59,0x00,0xCB,0x2D,0x5A},	// 381 Rostock, 385 Schwerin	// 380 gibt's nicht
	{0x5A,0x95,0xD5,0x49,0x00,0x2D,0x5B,0xAB}};	// 391 Magdeburg, 395 Neubrandenburg
   return ost(z3,z4,o[z2-3]);
  }
  case 4: if (z2==0) return 2; goto west;	// 40 Hamburg
  case 8: if (z2==0 && z3==0) return 3;		// 800
  case 6: if (z2==9) return 2; goto west;	// 69 Frankfurt, 89 München
  case 9: if (z2==0 && z3==6) return 3;		// 906 Donauwörth
  default: west:
  return 3 + (z3!=1);			// x11, x21 ... x91
 }
}

// Die Österreicher Vorwahllänge ist bis auf wenige Ausnahmen 4 Ziffern lang.
// Mobilfunknetze fallen mit Bundesland Salzburg zusammen und haben 3 Ziffern Vorwahl.
char len_at(const char*n) {
 char z1=n[0]&15,z2=n[1]&15,z3=n[2]&15;
 switch (z1) {
  case 1: return 1;	// Wien
  case 3: if (z2==1 && z3==6) return 3; break;	// Graz
  case 4: if (z2==6) return 3; break;	// Klagenfurt
  case 5: if (z2==1) return 3; break;	// Innsbruck
  case 6:
  if (z2>=6) return 3;		// Stadt Salzburg, Handynummern
  if (z2==5 && z3==0) return 3;	// Handy
  if (z2==4 && z3==4) return 3;	// Handy
  break;
  case 7: if (z2==3 && z3==2) return 3; break;	// Linz
 }
 return 4;
}

char len_it(const char*n) {	// ohne obligatorische '0'
 char z1=n[0]&15,z2=n[1]&15;
 switch (z1) {
  case 2:
  case 6: return 1;	// Mailand, Rom
  default: if (z2<=1 || z2==5 || z2==9) return 2; break;
 }
 return 3;
}

char len_cz(const char*n) {
 char z1=n[0]&15,z2=n[1]&15;
 switch (z1) {
  case 2: return 1;	// Prag
  case 3:
  case 4:
  case 5: return 2;	// sonstige Regionalnummern
  case 7: return 2+(z2<2);	// Handynummern
  default: return 3;	// sonstiges
 }
}

char len_sk(const char*n) {
 char z1=n[0]&15,z2=n[1]&15;
 switch (z1) {
  case 1: return 2;
  case 2:
  case 3:
  case 4:
  case 5: return 1;
  default: return 3;
 }
}

char len_pl(const char*n) {
 char z1=n[0]&15,z2=n[1]&15;
 return 2+(z1==1 && z2==1);	// generell 2-stellig
}

char len_hu(const char*n) {
 char z1=n[0]&15;
 return 1+(z1!=1);
}

char len_fr(const char*n) {	// Frankreich hat keine echten Regionalkodes
 char z1=n[0]&15,z2=n[1]&15;
 return 3+(z1==7 && z2==0);
}

char len_uk(const char*n) {
 char z1=n[0]&15,z2=n[1]&15,z3=n[2]&15;
 switch (z1) {
  case 2: return 2;		// London, Nordirland
  case 1: if (z2==1 || z3==1) return 3;
  PROGMEM static const unsigned short five[]={
    0x3873,			// einige kleinere Regionen haben 5-stellige Vorwahlen
    0x6973,0x6974,0x6975,
    0x7683,0x7684,0x7687,
    0x9467};
  char z4=n[3]&15,z5=n[4]&15;
  unsigned short zz=z2<<12|z3<<8|z4<<4|z5;
  for (const unsigned short*it=five; it!=five+elemof(five); it++) if (pgm_read_word(it)==zz) return 5;
  return 4;
 }
 return 3;			// IMHO unklar, Handynummern?
}

char len_us(const char*) {return 3;}	// entsprechend NANP

char len_ru(const char*) {return 3;}	// Interessant: Amerikaner sind Russen mit Westgeld!
}
Detected encoding: ANSI (CP1252)4
Wrong umlauts? - Assume file is ANSI (CP1252) encoded