class ref name: postal_address
category-group: address
layer: 8
header file: z_postaladdr.h

synopsis.
The postal address object, or postal_address_o , is a very powerful object for managing postal addresses. It gives an application the capability to parse text into an address; store and retrieve such addresses to a database; and write them out as strings. In the most mechanical terms, it is essentially a specialty text processor. However, given that there are millions, if not billions of addresses on this planet, this class object can be very handy.

description.
The postal address object is a straightforward subclass of the orthodox_o class. As such, it has many of the characteristics of sibling classes, such as email_address_o, business_o, or person_o class objects. It can be owned by other objects. A postal address, in the Z Directory and like in real life, can be owned by a person or business - these are the typically idioms. It has a database schema and can be saved to a database via store_save() or retrieved via store_fetch() (both orthodox_o member functions).

The complete database schema is defined by the following [multi-part] string:

postal_address
(
    is_equipment YES
    is_code      NO
    columns
    [

From this, you can see that 2 external columns are referenced by each row: country.code and landmark_code.full_code. Thus, the Z Directory topo dataset must be loaded into the database prior to using postal_address_o to store rows into a table.

Using the following address as an example:

United Nations Headquarters
760 United Nations Plaza, 39th floor
New York, NY 10017
The following table sheds some summary information about these database columns:
column name notes
country 2-character ISO code; maps to country.code
region "NY"
city The city ("New York")
street_number 760
street_name "United Nations Plaza": the street component, such as "5th Avenue" or "Market Street"
direction (n.a.) this would be a directional prefix or suffix, eg "NW" in "2020 Pennsylvania Ave NW", or "South" in "76 South Park Avenue"
direc_loc (n.a.)
street_type ("Plaza") eg, street, alley, avenue, lane, etc.
floor ("39") the building's floor number, if specified
building_name The United Nations Secretariat building
building_number sometimes there is a separate building number, which is subsidiary to the address.
room the room (or suite) number, if specified
room_code this is a code for the type of room or suite in the address (if present). The different types include apartment, room, box, suite, and others.
post_code the postal code. in America, this is the zip code
zip4 "zip+4" - specific to America
pre_street eg, "United Nations Headquarters".
post_street this is a line following the "street line" (not common)
free_text the full address, as a multi-line string
type this is a reference to the code found in the table-column landmark_code.full_code
zoning_code ?

strict mode.

For certain operations, such as when setting the country or the "type" (codes found in database table landmark_code.full_code , representing the type of place the address is, eg, warehouse; parking lot [S.PKLT]; airport [S.AIRP]; abandoned prison [S.PRNQ]; etc) - you may want to verify if the input value is correct. This involves a database lookup and hence is relatively expensive. If "strict mode" is off, no validation check is done. An errant value would have to be caught later either manually by the application or automatically by the database engine when the object is saved or updated to a database. If "strict mode" is on, the check is done when the value is set. This applies for set_country() and set_type().

member functions (primary)

postal_address_o()
SIGNATURE: postal_address_o ()
SYNOPSIS: instantiaate a simple postal_address_o instance. The object at construction time has no actual address.
 

postal_address_o(postal_address_o)
SIGNATURE: postal_address_o (const postal_address_o &rhs)
SYNOPSIS: instantiaate a simple postal_address_o instance. It is an exact copy of the input variable, 'rhs'.
 

operator = (postal_address_o)
SIGNATURE: const postal_address_o &operator = (const postal_address_o &rhs)
SYNOPSIS:
copies the postal_address_o instance 'rhs' into the current object. Any prior contents is over-written by whatever is in 'rhs'.
 

postal_address_o(<args>)
SIGNATURE: postal_address_o (const string_o &s)
SYNOPSIS:
creates a new computer object. The address is initialized to the value found in 's', if 's' represents a valid address.
 

clone()
SIGNATURE: postal_address_o *clone () const
SYNOPSIS:
makes a new instance of a postal address object, via "new". This instance is an exact copy of the current object. It must be explicitly freed by the application in order to properly deallocate the memory consumed in creating the object.
RETURNS: a pointer to a newly made email_address_o instance.
TRAITS: this is an inline, virtual function
 

bad_reference()
SIGNATURE: postal_address_o &bad_reference ()
SYNOPSIS:
returns a reference "handle" to the "bad postal address object" instance. This is used mainly for containers, where an object must be returned, whether or not there is one that satisfies the operation (such as a search for a particular object in a list). The address of this object is the way the application knows that the "bad object" was returned.
TRAITS: this is a static function
 

operator = (postal_address_o)
SIGNATURE: orthodox_o &operator = (const rec_dbag_o &rhs)
SYNOPSIS:
copies the address provided by 'rhs' into the current object. This operator function is similar in all respects to the "= (string_o &)" assignment operation.
RETURNS: reference to the current object (ie, "*this"), upcast to an orthodox object.
TRAITS: this is a virtual function
 

operator = (postal_address_o)
SIGNATURE: postal_address_o &operator = (const string_o &rhs)
SYNOPSIS: parses the address in 'rhs' and sets up the address based on the contents of the input parameter
PARAMETERS

  • rhs: a string containing a valid address. If the string is not a valid address, the operation will abort and the object will not be affected.
  • RETURNS: reference to the current object (ie, "*this")
    TRAITS: this is a virtual function
     

    operator ==()
    SIGNATURE: int operator == (const postal_address_o &rhs) const
    SYNOPSIS:
    equality operator: this compares two addresses to see if they are the same. To be considered the same, a group of fields comprising an address must match. If any item is different, the test fails and this function returns 0. The default items that are used in this test are:

    • country_code
    • city
    • street_number
    • street_name
    • room
    • post_code

    RETURNS:
    1: the objects are "equal"
    0: the objects are different
    TRAITS: this is an inline, virtual function
     

    operator !=()
    SIGNATURE: int operator != (const postal_address_o &rhs) const
    SYNOPSIS:
    This function compares two postal address objects for inequality via the "!=" operator. It is used like so:

    postal_address_o x, y;
    x = "307 West Hastings Street\nVancouver, BC\nCanada V6B 1H6";
    y = "5880 Hwy 67 South\nFlorence, CO 81226";
    if (x != y)
       std::cout << "the x & y addresses are not the same.\n";
    

    RETURNS:
    1: the objects are different
    0: the objects are "equal"
    TRAITS: this is an inline, virtual function
     

    type()
    SIGNATURE: const string_o &type () const
    SYNOPSIS:
    this returns a string that contains a code found in the database column landmark_code.full_code. The resultant code, up to 8 characters long, represents the type of object at the current address. This can be any of the 657 things found constituting man-made and natural places on Earth, from abandoned mines, athletic fields, and ATMs to wells, wildlife reserves, and zoos.
    TRAITS: this is an inline function
     

    country()
    SIGNATURE: const string_o &country () const
    SYNOPSIS: This returns the name of the country that the current object's postal address is in (if it is set).
    TRAITS: this is an inline function
     

    country_code()
    SIGNATURE: const string_o &country_code () const
    SYNOPSIS: This returns the 2-character country code that the current object's postal address is in (if it is set).
    TRAITS: this is an inline function
     

    free_text()
    SIGNATURE: const string_o &free_text () const
    SYNOPSIS: this returns the full multi-line string that constitutes the current object's postal address (if set).
    TRAITS: this is an inline function
     

    is_set()
    SIGNATURE: boolean is_set () const
    SYNOPSIS: tells if the current object has been set to a valid address or not.
    RETURNS:
    TRUE: the object has been set to a valid address
    FALSE: the object is not set to an address
    TRAITS: this is an inline function
     

    last_error()
    SIGNATURE: int last_error () const
    SYNOPSIS: [WIP]
    TRAITS: this is an inline function
     

    default_country()
    SIGNATURE: string_o default_country ()
    SYNOPSIS:
    returns the default country (if set). This is the country that is used when the address given to a specific postal address instance is unknown or cannot be determined.
    TRAITS: this is a static function
     

    set_strictmode()
    SIGNATURE: int set_strictmode (boolean ison = TRUE)
    SYNOPSIS:
    if TRUE, this will enforce doing a database lookup to make sure that a parameter is a valid address component when the application is attempting to set a value using the component. Strict mode applies to these:

    • post ("zip") codes [within a set() call]
    • countries [set_country()]
    • address types [set_type()]

    TRAITS: this is an inline function
     

    set_loosemode()
    SIGNATURE: int set_loosemode ()
    SYNOPSIS:
    this is the converse of set_strictmode(). if the object is set to "loose mode", no checking of post-zip codes, countries, or address types. This call is exacty equivalent to set_strictmode(FALSE).
    TRAITS: this is an inline function
     

    set_type()
    SIGNATURE: int set_type (const string_o &s)
    SYNOPSIS:
    this sets the address type to the value in string object 's'. that contains an address type code. If the object is in "strict mode", the value will be looked up during this function call and if not found, the operation will fail.
    PARAMETERS

  • s: a string containing a valid type code. This code must be a value found in the database column landmark_code.full_code.
  •  

    set_freetext()
    SIGNATURE: int set_freetext (const string_o &s)
    SYNOPSIS: [WIP]
    TRAITS: this is a virtual function
     

    set_country()
    SIGNATURE: int set_country (const string_o &cc)
    SYNOPSIS:
    sets the country for the current object. Usually, this would be done prior to giving the object an address.
    If the object is in strict mode, the country name (or code) will be looked up in the local database. If no matching country is found, the operation will fail and -1 is returned.
    PARAMETERS

  • cc: a string containing either the name of a country or a country's 2-letter ISO code.
  • RETURNS:
    0: country successfully set
    -1: error occurred; object's country not set
    TRAITS: this is a virtual function
     

    set_volume()
    SIGNATURE: int set_volume (const int)
    SYNOPSIS: sets the object's personal "volume control" level. This is used for error reporting purposes.
    TRAITS: this is an inline function
     

    setup_by_country()
    SIGNATURE: int setup_by_country (const string_o &, int *)
    SYNOPSIS: [WIP]
     

    setup_by_countryID()
    SIGNATURE: int setup_by_countryID (const string_o &, int *)
    SYNOPSIS: [WIP]
     

    set_default_country()
    SIGNATURE: int set_default_country (const string_o)
    SYNOPSIS: [WIP]
    TRAITS: this is a static function
     

    set()
    SIGNATURE: int set (const string_o &s, int *pi = NULL)
    SYNOPSIS:
    Sets the address to the contents of 's', which must contain a valid address in order for this function call to succeed.
    If the object is in strict mode, the postal (USA: "zip") code will be looked up in the local database. If no matching code is found, the operation will fail and -1 is returned. Also, if the string contains a country (which should be on the last line), the country name will be looked up.
    PARAMETERS

    • s: a string containing a valid address. If the string is not a valid address, the operation will abort
    • pi: [output] error indicator variable.
    TRAITS: this is a virtual function
     

    reset()
    SIGNATURE: int reset ()
    SYNOPSIS: wipes out all internal [databag] fields. the object returns to the at-construction state.
     

    reset_fields()
    SIGNATURE: int reset_fields (const boolean all = TRUE)
    SYNOPSIS:
    wipes out all internal [databag] fields. this does the bulk of the work for the call to reset().
    Under certain conditions you may want to preserve country information. For that, set 'all ' to FALSE. This is the case in set(), where a call to setup_by_country() is followed by parse_address().
    PARAMETERS

  • all: if TRUE, these fields are also wiped: country, country_code, and type. If FALSE, they are unchanged.
  • RETURNS: 0
     

    print()
    SIGNATURE: string_o print (int *pi = NULL) const
    SYNOPSIS: prints the full address (if set) to a string, which is the return variable from this function call.
    RETURNS: [string] object containing the text form of the object's address
    TRAITS: this is a virtual function
     

     

    sql_fetchquery()
    SIGNATURE: string_o sql_fetchquery (int * = NULL) const
    SYNOPSIS: [WIP]
     

    note.
    Prior to 2013 there was a subclass, the American_postal_address_o class. This specialty class existed with the intent of specializing the parsing of an address on a per-country basis. This approach has been abandoned in order to reduce complexity. However, currently the postal address class supports processing only American addresses.

    examples.
    This hastily-assembled example demonstrates how easy it is to use this object.

    #include "z_txtstring.h"
    #include "z_postaladdr.h"
    
    void main()
    {
        int x, ie0;
        const char *s = "200 NW 5th Street, Suite 901\nOklahoma City, OK 73102-3202\";
        textstring_o ts, wc;
        postal_address_o::set_default_country("America");
        postal_address_o w_addr, r_addr;    // Write address; Read address
        w_addr = s;                         // load string to postal addr
        if (!w_addr.is_set())
            { std::cerr << "postal address set failed.\n"; return; }
        ie0 = w_addr.store_add();           // written out to the DB
        ts = w_addr.get("id");              // save the DB ID for later
        x = s.as_number();
        z_int_to_str (w_addr.externID(), ts);
        wc = string_o("id = ") + ts;
    
        ie0 = r_addr.store_fetch(wc);
        if (ie0)
            { std::cerr << "error reading object from the database\n"; return; }
    
        std::cout << "\nTHE ADDRESS:\n" << r_addr.print() << "\n\n";
    
        if (r_addr.city() != "Oklahoma City")
            std::cerr << "error 'city' value invalid.\n";
    
        if (r_addr.post_code() != "73102")
            std::cerr << "error zip code value invalid.\n";
    }
    

    limitations.
    As of 2013, the only supported address formats are American addresses. The goal is to eventually handle postal address formats of all nations. There have been long-standing plans to expand postal address parsing to encompass all the known addresses on Earth. The rate at which other country's address formats are included are limited only by Vettrasoft manpower (as of this writing, this is a severe restriction).

    history.

    Sat 12/21/1996: American_postal_address_o::set_street() created [-GeG]
    Mon 03/23/1998: bug fix; changed param (do_zip_plus4) default to true
    Sat 10/10/1998 de-inlined APA_o::set_state(); complex: region <-> state
    Sun 10/11/1998: changed 2- -> 3-char fields state, direction, room_code
    Mon 10/19/1998: did fix in American_postal_address_o::print()
    Wed 05/22/2002: QA driver, parse_address(), reset_fields() added [--AG]
    Fri 05/24/2002: postal_address_o::address_to_morphem() added [--AG]
    ??? 07/02/2002: "" removed from foreign keys
    Tue 08/20/2002: added to 'common_street_names'; clean-up [--GeG]
    Sat 09/07/2002: took out t_start, t_end (they are in "orthodox")
    Wed 09/18/2002: fixing some DB table columns. "state" merged -> "region"
    ??? 10/01/2002: setup_by_countryID() bug fix, CountryBag_List [--AG]
    Wed 05/22/2013: if parse turns out American, 'z_APA_Do_Parse' flag set
    Mon 06/17/2013: created c-tor(string_o &) [--GeG]
    Mon 07/08/2013: setup_by_country() where clause changed; "like" to "=".
    Tue 07/16/2013: cleanup: zip_code -> post_code; took out bStrictMode, ..