/* ** Copyright (C) 2005-2006 by Carnegie Mellon University. ** ** @OPENSOURCE_HEADER_START@ ** ** Use of the SILK system and related source code is subject to the terms ** of the following licenses: ** ** GNU Public License (GPL) Rights pursuant to Version 2, June 1991 ** Government Purpose License Rights (GPLR) pursuant to DFARS 252.225-7013 ** ** NO WARRANTY ** ** ANY INFORMATION, MATERIALS, SERVICES, INTELLECTUAL PROPERTY OR OTHER ** PROPERTY OR RIGHTS GRANTED OR PROVIDED BY CARNEGIE MELLON UNIVERSITY ** PURSUANT TO THIS LICENSE (HEREINAFTER THE "DELIVERABLES") ARE ON AN ** "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY ** KIND, EITHER EXPRESS OR IMPLIED AS TO ANY MATTER INCLUDING, BUT NOT ** LIMITED TO, WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABILITY, INFORMATIONAL CONTENT, NONINFRINGEMENT, OR ERROR-FREE ** OPERATION. CARNEGIE MELLON UNIVERSITY SHALL NOT BE LIABLE FOR INDIRECT, ** SPECIAL OR CONSEQUENTIAL DAMAGES, SUCH AS LOSS OF PROFITS OR INABILITY ** TO USE SAID INTELLECTUAL PROPERTY, UNDER THIS LICENSE, REGARDLESS OF ** WHETHER SUCH PARTY WAS AWARE OF THE POSSIBILITY OF SUCH DAMAGES. ** LICENSEE AGREES THAT IT WILL NOT MAKE ANY WARRANTY ON BEHALF OF ** CARNEGIE MELLON UNIVERSITY, EXPRESS OR IMPLIED, TO ANY PERSON ** CONCERNING THE APPLICATION OF OR THE RESULTS TO BE OBTAINED WITH THE ** DELIVERABLES UNDER THIS LICENSE. ** ** Licensee hereby agrees to defend, indemnify, and hold harmless Carnegie ** Mellon University, its trustees, officers, employees, and agents from ** all claims or demands made against them (and any related losses, ** expenses, or attorney's fees) arising out of, or relating to Licensee's ** and/or its sub licensees' negligent use or willful misuse of or ** negligent conduct or willful misconduct regarding the Software, ** facilities, or other rights or assistance granted by Carnegie Mellon ** University under this License, including, but not limited to, any ** claims of product liability, personal injury, death, damage to ** property, or violation of any laws or regulations. ** ** Carnegie Mellon University Software Engineering Institute authored ** documents are sponsored by the U.S. Department of Defense under ** Contract F19628-00-C-0003. Carnegie Mellon University retains ** copyrights in all material produced under this contract. The U.S. ** Government retains a non-exclusive, royalty-free license to publish or ** reproduce these documents, or allow others to do so, for U.S. ** Government purposes only pursuant to the copyright license under the ** contract clause at 252.227.7013. ** ** @OPENSOURCE_HEADER_END@ */ #ifndef _SKSTRINGMAP_H #define _SKSTRINGMAP_H #include "silk.h" RCSIDENTVAR(rcsID_STRINGMAP_H, "$SiLK: skstringmap.h 4285 2006-07-18 18:03:13Z mthomas $"); #include "sklinkedlist.h" #include "skvector.h" /* ** skstringmap.h ** ** An ordered list of string->id mappings to support named columns. ** ** The basic usage is to create a sk_stringmap_t and to add ** sk_stringmap_entry_t items to it, each of which is a name/value ** pair. ** ** Then, once processing begins, call skStringMapMatch() with the ** user's string, and it will return either a valid result set (an ** sk_vector_t of sk_stringmap_entry_t*), or a parse error. ** ** Sample Usage (does not check error cases) ** ** sk_stringmap_t *name_id_map; ** sk_stringmap_entry_t mappings[] = { ** { "foo", 1 }, ** { "bar", 2 }, ** }; ** char *user_input = "foo,baz"; ** sk_vector_t *match_vec; ** sk_stringmap_status_t rv; ** sk_stringmap_id_t found_id; ** ** // Create map and add entries ** skStringMapCreate( &name_id_map ); ** skStringMapAddIDArray( name_id_map, 2, mappings ); ** skStringMapAddID( name_id_map, "baz", 3 ); ** ** // Create vector for results of search ** skVectorNew( &match_vec ); ** ** // Map user's input and process each entry ** rv = skStringMapMatch( match_vec, name_id_map, user_input ); ** if( rv == SKSTRINGMAP_OK ) { ** size_t count = skVectorGetCount( match_vec ); ** size_t i; ** sk_stringmap_entry_t *entry; ** for( i = 0; i < count; ++i ) { ** skVectorGetValue( &entry, match_vec, i ); ** found_id = entry->id; ** // DO STUFF WITH THE IDS MATCHED ** } ** } ** ** // Clean up ** skVectorDestroy( match_vec ); ** skStringMapDestroy( name_id_map ); */ /* function result status */ typedef enum { SKSTRINGMAP_OK = 0, /* Command was successful */ SKSTRINGMAP_ERR_INPUT = -127, /* Indicates bad input, e.g. NULL pointer */ SKSTRINGMAP_ERR_MEM, /* A memory allocation call failed */ SKSTRINGMAP_ERR_LIST, /* The following values can be returned while adding a new * key/value pair to the map. */ SKSTRINGMAP_ERR_DUPLICATE_ENTRY, /* The new key was found to be a duplicate of a key already in the * map. */ SKSTRINGMAP_ERR_ZERO_LENGTH_ENTRY, /* The new key was found to be the empty string. */ SKSTRINGMAP_ERR_NUMERIC_START_ENTRY, /* The key was found to start with a number but to contain * non-numeric characters. */ SKSTRINGMAP_ERR_ALPHANUM_START_ENTRY, /* The key was found to start with a non-alphanumeric * character. */ SKSTRINGMAP_ERR_PARSER, /* The parser encountered an unexpected error unrelated to the * user's input */ /* The following values can be returned while parsing user input * and finding entries in the map. */ SKSTRINGMAP_PARSE_NO_MATCH, /* The user's input is not an exact match nor a prefix match for * any key. */ SKSTRINGMAP_PARSE_AMBIGUOUS, /* The user's input matches matches no key exactly and is a prefix * match for multiple keys. */ SKSTRINGMAP_PARSE_UNPARSABLE /* The user's input is not parsable or contains an invalid range * e.g., 3-2 */ } sk_stringmap_status_t; typedef sk_link_list_t sk_stringmap_t; typedef uint32_t sk_stringmap_id_t; typedef struct { /* string name key */ char *name; /* unsigned integer id value */ sk_stringmap_id_t id; } sk_stringmap_entry_t; sk_stringmap_status_t skStringMapCreate( sk_stringmap_t **out_str_map); /* * Creates a new string-map and puts the result into 'out_str_map'. * */ sk_stringmap_status_t skStringMapDestroy( sk_stringmap_t *map); /* * Destroys the string-map 'str_map'. * */ sk_stringmap_status_t skStringMapAddID( sk_stringmap_t *str_map, const char *name, sk_stringmap_id_t id); /* * Adds a single key/value pair ['name' => 'id'] to the StringMap, * 'str_map'. */ sk_stringmap_status_t skStringMapAddIDArray( sk_stringmap_t *str_map, int entryc, const sk_stringmap_entry_t *entryv); /* * Adds multiple entries from the 'entryv' array, each entry of the * form {"name", id}, to the StringMap 'str_map'. * * When 'entryc' is positive or zero, it is taken as the count of * entries in 'entryv'. When 'entryc' is negative, 'entryv' is * considered to be a NULL-terminated array of entries; i.e., all * entries in 'entryv' are added one of the form {NULL, 0} is * reached. */ sk_stringmap_status_t skStringMapRemoveByName( sk_stringmap_t *str_map, const char *name); /* * Remove a single entry from the StringMap whose name is 'name'. * * Arguments * * sk_stringmap_t *str_map - a pointer to the StringMap list from * which to remove the entry * * const char *name - the string key of the entry to remove */ sk_stringmap_status_t skStringMapRemoveByID( sk_stringmap_t *str_map, sk_stringmap_id_t id); /* * Remove all entries from the StringMap whose ID is 'id'. * * Arguments * * sk_stringmap_t *str_map - a pointer to the StringMap list from * which to remove the entry or entries * * sk_stringmap_id_t id - the ID of the entry or entries to remove */ sk_stringmap_status_t skStringMapRemoveIDArray( sk_stringmap_t *str_map, int entryc, const sk_stringmap_entry_t *entryv); /* * Removes multiple entries from the StringMap * * Arguments * * sk_stringmap_t *str_map - a pointer to the StringMap from which to * remove the entries * * int entryc - count of the number of entries in entryv to remove * * sk_stringmap_entry_t *entryv - array of entries to remove from * the StringMap; only the name (key) of each entry is relevant; * the IDs in the entryv are ignored. */ sk_stringmap_status_t skStringMapMatch( sk_vector_t *out_vec, char **bad_token, const sk_stringmap_t *str_map, const char *user_string); /* * Take the user entered string, 'user_string' containing tokens * separated by commas(,) and hyphens(-), parse it to get a list of * keys, search the StringMap 'str_map' for those keys, and fill * the vector 'out_vec' with pointers to the sk_stringmap_entry_t's * that matched the keys. * * When non-NULL, 'bad_token' should contain a pointer to a * C-string to hold the token that was being parsed when a parse * error occurred. It is the caller's responsibility to free() * this string. * * Pointers to the matched entries will be appened to 'out_vec', * whose elements should be sizeof(sk_stringmap_entry_t*). The * caller should not modify nor free the elements in the vector. */ sk_stringmap_status_t skStringMapGetEntry( sk_stringmap_entry_t **out_entry, const sk_stringmap_t *str_map, const char *user_string); /* * Take the user entered string 'user_string' containing a SINGLE * key and search the StringMap 'str_map' to find the * sk_stringmap_entry_t that has that string as a key, setting * 'out_entry' to point to that key and returning SKSTRINGMAP_OK. * The caller should not modify nor free the returned entry. * * Returns SKSTRINGMAP_PARSE_AMBIGUOUS if 'user_string' matches * multiple entries, SKSTRINGMAP_PARSE_NO_MATCH if it matches no * entries. */ sk_stringmap_status_t skStringMapGetNames( sk_vector_t *out_vec, const sk_stringmap_t *list, sk_stringmap_id_t id); /* * Given an id, append to the vector 'out_vec' all entries in the * StringMap 'map' that have keys mapping to that id. * * 'out_vec' should be a vector whose elements are * sizeof(sk_stringmap_entry_t*). The caller should not modify nor * free the elements in the vector. */ sk_stringmap_status_t skStringMapPrintMap( FILE *outstream, const sk_stringmap_t *str_map); /* * Print the map keys and values to the given file stream. The map * is printed in a human readable format of the form * * { "key1" : value1, "key2" : value2, ... } * * Arguments * * FILE *outstream - the output stream to which to print * * sk_stringmap_t *str_map - pointer to the StringMap to print */ #endif /* _SKSTRINGMAP_H */