/* * $Id$ */ /* * Harbour Project source code: * Hash table type and functions * * Copyright 2009 April White * www - http://harbour-project.org * * Based on the content of hashfunc.c and hashes.c * Copyright 2007 Przemyslaw Czerpak * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this software; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). * * As a special exception, the Harbour Project gives permission for * additional uses of the text contained in its release of Harbour. * * The exception is that, if you link the Harbour libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Harbour library code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public License. * * This exception applies only to the code released by the Harbour * Project under the name Harbour. If you copy code from other * Harbour Project or Free Software Foundation releases into a copy of * Harbour, as the General Public License permits, the exception does * not apply to the code that you add in this way. To avoid misleading * anyone as to the status of such modified files, you must delete * this exception notice from them. * * If you write modifications of your own for Harbour, it is your choice * whether to permit this exception to apply to your modifications. * If you do not wish that, delete this exception notice. * */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HASH() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns a hash table * $SYNTAX$ * HB_HASH( [ , ], [ , ], ... ) -> hsTable * $ARGUMENTS$ * entry key; * can be of type: number, date, datetime, string, pointer * * entry value; can be of type: block, string, numeric, date/datetime, logical, nil, pointer, array, hash table * $RETURNS$ * A hash table built from the initial key/value pairs * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HHASKEY() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Determines whether a hash table has an entry with a give key * $SYNTAX$ * HB_HHASKEY( , ) -> lExists * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a key value to be queried for; * can be of type: number, date, datetime, string, pointer * $RETURNS$ * A logical value indicating whether the key exists within the hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HPOS() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Locates the index of a key within a hash table * $SYNTAX$ * HB_HPOS( , ) -> nPosition * $ARGUMENTS$ * a hash table, created by HB_HASH() * * key for which its position is to be determined; * can be of type: number, date, datetime, string, pointer * $RETURNS$ * A integer number being the index position of the key within the hash table. * * TODO: what is the return value if the key does not exist? zero (0)? RTE? * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HGET() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns a hash value * $SYNTAX$ * HB_HGET( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * key to be retrieve from the hash table; * can be of type: number, date, datetime, string, pointer * $RETURNS$ * Either the value within the hash table for the given key. * * An array access error occurs of the key is not found * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HGETDEF() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns a hash value, or a default value if the key is not present * $SYNTAX$ * HB_HGETDEF( , , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * key to be retrieve from the hash table; * can be of type: number, date, datetime, string, pointer * * a default value to be returned if the * hash table does not contain the key * $RETURNS$ * Either the value within the hash table for the given key, * or the default value. * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSET() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets a hash value * $SYNTAX$ * HB_HSET( , , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * the key of the entry to be set; * can be of type: number, date, datetime, string, pointer * * the entry value * $RETURNS$ * The hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HDEL() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Removes a key/value pair from a hash table * $SYNTAX$ * HB_HDEL( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * key to be removed from the hash table; * can be of type: number, date, datetime, string, pointer * $RETURNS$ * The hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HKEYAT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Gets a hash table key at a given position * $SYNTAX$ * HB_HKEYAT( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * the position of an entry within the hash table that will * be returned * $RETURNS$ * The key at the given position of the hash table; * the type will be one: number, date, datetime, string, pointer * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HVALUEAT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Gets/sets a hash value at a given position * $SYNTAX$ * HB_HVALUEAT( , , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * the position of an entry within the hash table that will * be returned * * a new value to be assigned to the hash table at the given * position * $RETURNS$ * The existing value, or the new value if it is given * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HPAIRAT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns a two-dimensional array of a hash table entry key/value pair * $SYNTAX$ * HB_HPAIRAT( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * the position of an entry within the hash table that will * be returned * $RETURNS$ * A two-dimensional array of the key/value pair entry of the hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HDELAT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Removes an entry from a hash table based on its index position * $SYNTAX$ * HB_HDELAT( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * the position of an entry within the hash table that will * be deleted * $RETURNS$ * The hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HKEYS() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns an array of the keys of a hash table * $SYNTAX$ * HB_HKEYS( ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * $RETURNS$ * An array of all the hash table keys * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HVALUES() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns an array of the values of a hash table * $SYNTAX$ * HB_HVALUES( ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * $RETURNS$ * An array of all the hash values * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HFILL() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Fills a hash table with a value * $SYNTAX$ * HB_HFILL( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * fill value; can be of type: block, string, numeric, date/datetime, logical, nil, pointer, array, hash table * $RETURNS$ * The hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HCLONE() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Creates a copy of a hash table * $SYNTAX$ * HB_HCLONE( ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * $RETURNS$ * A cloned copy of the hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HCOPY() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Adds entries from the source hash table to the destination hash table * $SYNTAX$ * HB_HCOPY( , , [], [] ) -> * $ARGUMENTS$ * a destination hash table, created by HB_HASH() * * a source hash table, created by HB_HASH() * * starting index, defaults to 1 if omitted * * counter, defaults to (length) - is omitted * $RETURNS$ * The destination hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HMERGE() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Merges a source hash table into a destination hash table * $SYNTAX$ * HB_HMERGE( , , | ) -> * $ARGUMENTS$ * a destination hash table, created by HB_HASH() * * a source hash table, created by HB_HASH() * * a code block that will be evaluated for each entry within the * source hash table; the code block will be passed the entry key, value and * position; if the code block returns a true value, the entry will be added to * the destination hash table * * the position of an entry within the source hash table that will * be appended to the destination hash table * * TODO: the source code passes either a number or HB_HASH_UNION; research this * $RETURNS$ * The destination hash table with the contents of the source hash table merged * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HEVAL() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Evaluate a code block across the contents of a hash table * $SYNTAX$ * HB_HEVAL( , , [], [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * code block to be evaluated * * starting index, defaults to 1 if omitted * * counter, defaults to (length) - is omitted * $RETURNS$ * The hash table * $DESCRIPTION$ * The code block is evaluated for every hash table entry starting at * for items. * * The code block is passed the entry key, value, and numeric position * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSCAN() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Scans a hash table * $SYNTAX$ * HB_HSCAN( , , [], [, [] ) -> nPosition * $ARGUMENTS$ * a hash table, created by HB_HASH() * * to be located within the hash table * * starting index, defaults to 1 if omitted * * counter, defaults to (length) - is omitted * * logical valuye indicating whether the comparision * is to be be exact or not * $RETURNS$ * The position of the located value within the hash table, or zero (0) if not found. * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSORT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Reorganizes the internal list of the hash table to be sorted * $SYNTAX$ * HB_HSORT( ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * $RETURNS$ * The hash table sorted * * TODO: is the original table altered? * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HCASEMATCH() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'case match' flag for the hash table * $SYNTAX$ * HB_HCASEMATCH( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'case match' flag of the hash table * $RETURNS$ * The previous value of the 'case match' flag * $DESCRIPTION$ * This function is equivalent to HB_HSETCASEMATCH() but it returns * the old flag value rather than the hash table * $EXAMPLES$ * LOCAL hsTable, lFlag * hsTable := { "one" => 1, "two" => 2 } * // turn 'case match' on for a new hash table, storing ol flag * lFlag := hb_HCaseMatch( hsTable, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HSETCASEMATCH() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HBINARY() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'binary' flag for the hash table * $SYNTAX$ * HB_HBINARY( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'binary' flag of the hash table * $RETURNS$ * The previous value of the 'binary' flag * $DESCRIPTION$ * This function is equivalent to HB_HBINARY() but it returns * the old flag value rather than the hash table * $EXAMPLES$ * LOCAL hsTable, lFlag * hsTable := { "one" => 1, "two" => 2 } * // turn 'binary' on for a new hash table, storing ol flag * lFlag := hb_HBinary( hsTable, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HSETBINARY() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HAUTOADD() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'auto add' flag for the hash table * $SYNTAX$ * HB_HAUTOADD( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'auto add' flag of the hash table * $RETURNS$ * The previous value of the 'auto add' flag * $DESCRIPTION$ * This function is equivalent to HB_HAUTOADD() but it returns * the old flag value rather than the hash table * $EXAMPLES$ * LOCAL hsTable, lFlag * hsTable := { "one" => 1, "two" => 2 } * // turn 'auto add' on for a new hash table, storing ol flag * lFlag := hb_HAutoAdd( hsTable, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HSETAUTOADD() * $END$ */ /* $DOC$ * $TEMPLATE$ * Procedure * $NAME$ * HB_HALLOCATE() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Preallocates a hash table * $SYNTAX$ * HB_HALLOCATE( , ) * $ARGUMENTS$ * a hash table, created by HB_HASH() * * number of items to preallocate in the hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HDEFAULT() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Returns/sets a default value for a hash table. * $SYNTAX$ * HB_HDEFAULT( , ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * * $RETURNS$ * The previous default value assigned to the hash table * $DESCRIPTION$ * * $EXAMPLES$ * * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * TODO: locate and list those methods that use this feature * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSETAUTOADD() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'auto add' flag for the hash table * $SYNTAX$ * HB_HSETAUTOADD( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'auto add' flag of the hash table * $RETURNS$ * The hash table * $DESCRIPTION$ * This function is equivalent to HB_HAUTOADD() but it returns * the passed hash table rather than the old flag value * $EXAMPLES$ * LOCAL hsTable * // turn 'auto add' on for a new hash table * hsTable := hb_HSetAutoAdd( { "one" => 1, "two" => 2 }, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HAUTOADD(),HB_HSETBINARY(),HB_HSETCASEMATCH() * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSETCASEMATCH() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'case match' flag for the hash table * $SYNTAX$ * HB_HSETCASEMATCH( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'case match' flag of the hash table * $RETURNS$ * The hash table * $DESCRIPTION$ * This function is equivalent to HB_HCASEMATCH() but it returns * the passed hash table rather than the old flag value * $EXAMPLES$ * LOCAL hsTable * // turn 'case match' on for a new hash table * hsTable := hb_HSetCaseMatch( { "one" => 1, "two" => 2 }, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HCASEMATCH(),HB_HSETAUTOADD(),HB_HSETBINARY * $END$ */ /* $DOC$ * $TEMPLATE$ * Function * $NAME$ * HB_HSETBINARY() * $CATEGORY$ * API * $SUBCATEGORY$ * Hash table * $ONELINER$ * Sets the 'binary' flag for the hash table * $SYNTAX$ * HB_HSETBINARY( , [] ) -> * $ARGUMENTS$ * a hash table, created by HB_HASH() * * a logical value indicating to turn on or off * the 'binary' flag of the hash table * $RETURNS$ * The hash table * $DESCRIPTION$ * This function is equivalent to HB_HBINARY() but it returns * the passed hash table rather than the old flag value * $EXAMPLES$ * LOCAL hsTable * // turn 'binary' on for a new hash table * hsTable := hb_HSetBinary( { "one" => 1, "two" => 2 }, .T. ) * $TESTS$ * * $STATUS$ * R * $COMPLIANCE$ * H * $PLATFORMS$ * * $FILES$ * * $SEEALSO$ * HB_HBINARY(),HB_HSETAUTOADD(),HB_HSETCASEMATCH * $END$ */