Utilities: Miscellany
[Query Object Framework]


Files

file  qofutil.h
 QOF utility functions.

Defines

#define QOF_MOD_UTIL   "qof-utilities"
#define stpcpy   g_stpcpy
 omitted if stpcpy exists.
#define CACHE_INSERT(str)   qof_util_string_cache_insert((gconstpointer)(str))
#define CACHE_REMOVE(str)   qof_util_string_cache_remove((str))
#define CACHE_REPLACE(dst, src)
#define QOF_CACHE_NEW(void)   qof_util_string_cache_insert("")

Functions

gint safe_strcmp (const gchar *da, const gchar *db)
gint safe_strcasecmp (const gchar *da, const gchar *db)
gint null_strcmp (const gchar *da, const gchar *db)
gchar * strncasestr (const guchar *str1, const guchar *str2, size_t len)
gchar * strcasestr (const gchar *str1, const gchar *str2)
gchar * ultostr (gulong val, gint base)
gboolean qof_util_string_isnum (const guchar *s)
gint qof_util_double_compare (gdouble v1, gdouble v2)
 Compare two gdouble values.
const gchar * qof_util_whitespace_filter (const gchar *val)
gint qof_util_bool_to_int (const gchar *val)
gchar * qof_util_param_to_string (QofEntity *ent, const QofParam *param)
 Converts a parameter to a string for storage or display.
gboolean qof_util_param_set_string (QofEntity *ent, const QofParam *param, const gchar *value_string)
 Set a parameter from a value string.
gchar * qof_util_make_utf8 (gchar *string)
 Convert strings received from the wrapped objects into UTF-8.
void qof_util_string_cache_destroy (void)
void qof_util_string_cache_remove (gconstpointer key)
gpointer qof_util_string_cache_insert (gconstpointer key)
gboolean qof_util_param_edit (QofInstance *inst, const QofParam *param)
 Prepare to edit a parameter.
gboolean qof_util_param_commit (QofInstance *inst, const QofParam *param)
 Commit this parameter change, with undo support.

Convenience wrappers

void qof_init (void)
 Initialise the Query Object Framework.
void qof_close (void)
 Safely close down the Query Object Framework.

typedef enum as string macros

#define ENUM_BODY(name, value)   name value,
#define AS_STRING_CASE(name, value)   case name: { return #name; }
#define FROM_STRING_CASE(name, value)
#define DEFINE_ENUM(name, list)
#define AS_STRING_DEC(name, list)   const gchar* name##asString(name n);
#define AS_STRING_FUNC(name, list)
#define FROM_STRING_DEC(name, list)
#define FROM_STRING_FUNC(name, list)

enum as string with no typedef

Similar but used when the enum is NOT a typedef Make sure you use the DEFINE_ENUM_NON_TYPEDEF macro.

You can precede the FROM_STRING_FUNC_NON_TYPEDEF and AS_STRING_FUNC_NON_TYPEDEF macros with the keyword static if appropriate.

ENUM_BODY is used in both types.

#define DEFINE_ENUM_NON_TYPEDEF(name, list)
#define FROM_STRING_DEC_NON_TYPEDEF(name, list)
#define FROM_STRING_CASE_NON_TYPEDEF(name, value)   if (strcmp(str, #name) == 0) { *type = name; }
#define FROM_STRING_FUNC_NON_TYPEDEF(name, list)
#define AS_STRING_DEC_NON_TYPEDEF(name, list)   const gchar* name##asString(enum name n);
#define AS_STRING_FUNC_NON_TYPEDEF(name, list)
#define AS_STRING_CASE_NON_TYPEDEF(name, value)   case name: { return #name; }

Define Documentation

#define AS_STRING_FUNC ( name,
list   ) 

Value:

const gchar* name##asString(name n) { \
        switch (n) {                      \
            list(AS_STRING_CASE)          \
            default: return "";  } }

Definition at line 66 of file qofutil.h.

#define AS_STRING_FUNC_NON_TYPEDEF ( name,
list   ) 

Value:

const gchar* name##asString(enum name n) {     \
       switch (n) {                               \
           list(AS_STRING_CASE_NON_TYPEDEF)       \
           default: return ""; } }

Definition at line 119 of file qofutil.h.

#define CACHE_REPLACE ( dst,
src   ) 

Value:

do {          \
        gpointer tmp = CACHE_INSERT((src));   \
        CACHE_REMOVE((dst));                  \
        (dst) = tmp;                          \
    } while (0)

Definition at line 325 of file qofutil.h.

#define DEFINE_ENUM ( name,
list   ) 

Value:

typedef enum {                       \
        list(ENUM_BODY)                  \
    }name;

Definition at line 58 of file qofutil.h.

#define DEFINE_ENUM_NON_TYPEDEF ( name,
list   ) 

Value:

enum name {                               \
        list(ENUM_BODY)                       \
    };

Definition at line 98 of file qofutil.h.

#define FROM_STRING_CASE ( name,
value   ) 

Value:

if (strcmp(str, #name) == 0) {       \
        return name;  }

Definition at line 54 of file qofutil.h.

#define FROM_STRING_DEC ( name,
list   ) 

Value:

name name##fromString                \
    (const gchar* str);

Definition at line 72 of file qofutil.h.

#define FROM_STRING_DEC_NON_TYPEDEF ( name,
list   ) 

Value:

void name##fromString                          \
   (const gchar* str, enum name *type);

Definition at line 103 of file qofutil.h.

#define FROM_STRING_FUNC ( name,
list   ) 

Value:

name name##fromString                \
    (const gchar* str) {                 \
    if(str == NULL) { return 0; }        \
        list(FROM_STRING_CASE)           \
        return 0;  }

Definition at line 76 of file qofutil.h.

#define FROM_STRING_FUNC_NON_TYPEDEF ( name,
list   ) 

Value:

void name##fromString                          \
   (const gchar* str, enum name *type) {          \
   if(str == NULL) { return; }                    \
    list(FROM_STRING_CASE_NON_TYPEDEF) }

Definition at line 110 of file qofutil.h.


Function Documentation

gint null_strcmp ( const gchar *  da,
const gchar *  db 
) [inline]

The null_strcmp compares strings a and b the same way that strcmp() does, except that either may be null. This routine assumes that a null string is equal to the empty string.

Definition at line 115 of file qofutil.c.

00116 {
00117     if (da && db)
00118         return strcmp (da, db);
00119     if (!da && db && 0 == db[0])
00120         return 0;
00121     if (!db && da && 0 == da[0])
00122         return 0;
00123     if (!da && db)
00124         return -1;
00125     if (da && !db)
00126         return +1;
00127     return 0;
00128 }

void qof_close ( void   ) 

Safely close down the Query Object Framework.

Use in place of separate close / shutdown functions (like guid_shutdown(), qof_query_shutdown() etc.) to protect against future changes.

Definition at line 780 of file qofutil.c.

00781 {
00782     qof_query_shutdown ();
00783     qof_object_shutdown ();
00784     guid_shutdown ();
00785     qof_date_close ();
00786     qof_util_string_cache_destroy ();
00787 }

void qof_init ( void   ) 

Initialise the Query Object Framework.

Use in place of separate init functions (like guid_init() and qof_query_init() etc.) to protect against future changes.

Definition at line 769 of file qofutil.c.

00770 {
00771     qof_util_get_string_cache ();
00772     guid_init ();
00773     qof_date_init ();
00774     qof_object_initialize ();
00775     qof_query_init ();
00776     qof_book_register ();
00777 }

gint qof_util_bool_to_int ( const gchar *  val  ) 

Return integer 1 if the string starts with 't' or 'T' or contains the word 'true' or 'TRUE'; if string is a number, return that number. (Leading whitespace is ignored).

Definition at line 252 of file qofutil.c.

00253 {
00254     const gchar *p = qof_util_whitespace_filter (val);
00255     if (!p)
00256         return 0;
00257     if ('t' == p[0])
00258         return 1;
00259     if ('T' == p[0])
00260         return 1;
00261     if ('y' == p[0])
00262         return 1;
00263     if ('Y' == p[0])
00264         return 1;
00265     if (strstr (p, "true"))
00266         return 1;
00267     if (strstr (p, "TRUE"))
00268         return 1;
00269     if (strstr (p, "yes"))
00270         return 1;
00271     if (strstr (p, "YES"))
00272         return 1;
00273     return atoi (val);
00274 }

gchar* qof_util_make_utf8 ( gchar *  string  ) 

Convert strings received from the wrapped objects into UTF-8.

A wrapper for g_locale_to_utf8 that removes the extra arguments. If the string is already valid UTF-8, it is returned unchanged.

Returns:
the converted string or the original, unchanged, string on error or if the string is already UTF-8.

Definition at line 333 of file qofutil.c.

00334 {
00335     gchar *value;
00336 
00337     if (!string)
00338         return NULL;
00339     if (g_utf8_validate (string, -1, NULL))
00340         return string;
00341     value = g_locale_to_utf8 (string, -1, NULL, NULL, NULL);
00342     if (!value)
00343     {
00344         PWARN (" unable to convert from locale %s", string);
00345         PINFO ("trying to convert from ISO-8859-15.");
00346         value = g_convert (string, -1, "UTF-8", "ISO-8859-15",
00347             NULL, NULL, NULL);
00348         if (!value)
00349         {
00350             PERR (" conversion failed");
00351             return string;
00352         }
00353         return value;
00354     }
00355     return value;
00356 }

gboolean qof_util_param_commit ( QofInstance *  inst,
const QofParam param 
)

Commit this parameter change, with undo support.

Calls the commit() routine of the backend to commit an edit. If an undo operation has been started, also maintains the undo record so the change can be undone.

param_name can only be NULL if the QofSQLite backend is not in use.

Parameters:
inst The QofInstance.
param The parameter being modified.
Returns:
FALSE on error, otherwise TRUE.

Definition at line 309 of file qofutil.c.

00310 {
00311     QofUndo *undo_data;
00312     QofBackend * be;
00313 
00314     if (!inst)
00315         return FALSE;
00316     (inst->editlevel)--;
00317     if (0 < inst->editlevel)
00318         return FALSE;
00319     be = qof_book_get_backend (inst->book);
00320     inst->param = param;
00321     if (be && qof_backend_commit_exists (be))
00322         qof_backend_run_commit (be, inst);
00323     if (param != NULL)
00324     {
00325         undo_data = inst->book->undo_data;
00326         if (undo_data->undo_operation_open)
00327             qof_undo_commit (inst, param);
00328     }
00329     return TRUE;
00330 }

gboolean qof_util_param_edit ( QofInstance *  inst,
const QofParam param 
)

Prepare to edit a parameter.

Calls the begin() routine of the backend to prepare for an edit. If an undo operation has been started, also prepares an undo record.

param_name can only be NULL if the QofSQLite backend is not in use.

Note:
The intention is that preparing and committing parameter changes is done outside the object using QofParam->param_setfcn but objects can obtain the QofParam themselves if preferred.
Making parameter changes using qof_util_param_edit and qof_util_param_commit makes for simpler QofUndo code because the undo handlers are called implicitly.

qof_book_start_operation (book, "edit PARAM_X");
param = qof_class_get_parameter(OBJ_TYPE, PARAM_NAME);
retbool = qof_util_param_edit (inst, param);
if (retbool)
	param->param_setfcn(ent, value);
retbool = qof_util_param_commit (inst, param);

Parameters:
inst The QofInstance.
param The parameter being modified.
Returns:
FALSE on error, otherwise TRUE.

Definition at line 281 of file qofutil.c.

00282 {
00283     QofBackend *be;
00284     QofUndo *undo_data;
00285 
00286     if (!inst)
00287         return FALSE;
00288     (inst->editlevel)++;
00289     if (1 < inst->editlevel)
00290         return FALSE;
00291     if (0 >= inst->editlevel)
00292         inst->editlevel = 1;
00293     be = qof_book_get_backend (inst->book);
00294     if (param != NULL)
00295     {
00296         undo_data = inst->book->undo_data;
00297         inst->param = param;
00298         if (undo_data->undo_operation_open)
00299             qof_undo_modify (inst, param);
00300     }
00301     if (be && qof_backend_begin_exists (be))
00302         qof_backend_run_begin (be, inst);
00303     else
00304         inst->dirty = TRUE;
00305     return TRUE;
00306 }

gboolean qof_util_param_set_string ( QofEntity ent,
const QofParam param,
const gchar *  value_string 
)

Set a parameter from a value string.

Used by string-based backends to set a value from a string previously written out to storage.

The string must be the same format as produced by qof_util_param_to_string for the same parameter type.

Parameters:
ent The entity in which the value is to be set.
param The parameter that stores the value.
value_string A string of exactly the same format as produced by qof_util_param_to_string for the parameter type.
e.g. a numeric type would require a string like 50/100 and a time type would require a UTC date stamp like 1907-10-07T03:34:29Z

Returns:
FALSE if the string does not match the required type or cannot be set, TRUE on success.

Definition at line 587 of file qofutil.c.

00589 {
00590     void (*string_setter) (QofEntity *, const gchar *);
00591     void (*time_setter) (QofEntity *, QofTime *);
00592     void (*numeric_setter) (QofEntity *, QofNumeric);
00593     void (*guid_setter) (QofEntity *, const GUID *);
00594     void (*double_setter) (QofEntity *, gdouble);
00595     void (*boolean_setter) (QofEntity *, gboolean);
00596     void (*i32_setter) (QofEntity *, gint32);
00597     void (*i64_setter) (QofEntity *, gint64);
00598     void (*char_setter) (QofEntity *, gchar);
00599 /*  void (*kvp_frame_setter) (QofEntity *, KvpFrame *);
00600     void (*reference_setter) (QofEntity *, QofEntity *);
00601     void (*collection_setter) (QofEntity *, QofCollection *);*/
00602 
00603     g_return_val_if_fail (ent, FALSE);
00604     g_return_val_if_fail (param, FALSE);
00605     g_return_val_if_fail (value_string, FALSE);
00606 
00607     if (safe_strcmp (param->param_type, QOF_TYPE_STRING) == 0)
00608     {
00609         string_setter =
00610             (void (*)(QofEntity *,
00611                 const gchar *)) param->param_setfcn;
00612         if (string_setter != NULL)
00613             string_setter (ent, value_string);
00614 //      registered_type = TRUE;
00615     }
00616     if (safe_strcmp (param->param_type, QOF_TYPE_TIME) == 0)
00617     {
00618         QofTime *qt;
00619         QofDate *qd;
00620 
00621         qd = qof_date_parse (value_string, QOF_DATE_FORMAT_UTC);
00622         if (!qd)
00623             return FALSE;
00624         qt = qof_date_to_qtime (qd);
00625         time_setter = 
00626             (void (*)(QofEntity *, QofTime *))
00627             param->param_setfcn;
00628         if ((time_setter != NULL) && (qof_time_is_valid (qt)))
00629             time_setter (ent, qt);
00630         qof_date_free (qd);
00631 //      registered_type = TRUE;
00632     }
00633     if ((safe_strcmp (param->param_type, QOF_TYPE_NUMERIC) == 0) ||
00634         (safe_strcmp (param->param_type, QOF_TYPE_DEBCRED) == 0))
00635     {
00636         QofNumeric num;
00637         numeric_setter =
00638             (void (*)(QofEntity *,
00639                 QofNumeric)) param->param_setfcn;
00640         if (!qof_numeric_from_string (value_string, &num) ||
00641             (qof_numeric_check (num) != QOF_ERROR_OK))
00642             return FALSE;
00643         if (numeric_setter != NULL)
00644             numeric_setter (ent, num);
00645 //      registered_type = TRUE;
00646     }
00647     if (safe_strcmp (param->param_type, QOF_TYPE_GUID) == 0)
00648     {
00649         GUID * guid;
00650 
00651         guid = guid_malloc();
00652         guid_new (guid);
00653         guid_setter =
00654             (void (*)(QofEntity *,
00655                 const GUID *)) param->param_setfcn;
00656         if (!string_to_guid(value_string, guid))
00657             return FALSE;
00658         if (guid_setter != NULL)
00659             guid_setter (ent, guid);
00660 //      registered_type = TRUE;
00661     }
00662     if (safe_strcmp (param->param_type, QOF_TYPE_INT32) == 0)
00663     {
00664         gint32 i32;
00665         gchar *tail;
00666 
00667         errno = 0;
00668         i32_setter =
00669             (void (*)(QofEntity *, gint32)) param->param_setfcn;
00670         i32 =
00671             (gint32) strtol (value_string, &tail, 0);
00672         if ((i32_setter != NULL) && (errno == 0))
00673 
00674             i32_setter (ent, i32);
00675 //      registered_type = TRUE;
00676     }
00677     if (safe_strcmp (param->param_type, QOF_TYPE_INT64) == 0)
00678     {
00679         gint64 i64;
00680         gchar *tail;
00681 
00682         errno = 0;
00683         i64 = strtoll (value_string, &tail, 0);
00684         i64_setter =
00685             (void (*)(QofEntity *, gint64)) param->param_setfcn;
00686         if ((i64_setter != NULL) && (errno == 0))
00687             i64_setter (ent, i64);
00688 //      registered_type = TRUE;
00689     }
00690     if (safe_strcmp (param->param_type, QOF_TYPE_DOUBLE) == 0)
00691     {
00692         gdouble db;
00693         gchar *tail;
00694 
00695         errno = 0;
00696         db = strtod (value_string, &tail);
00697         double_setter =
00698             (void (*)(QofEntity *, gdouble)) param->param_setfcn;
00699         if ((double_setter != NULL) && (errno == 0))
00700             double_setter (ent, db);
00701 //      registered_type = TRUE;
00702     }
00703     if (safe_strcmp (param->param_type, QOF_TYPE_BOOLEAN) == 0)
00704     {
00705         gint val;
00706         gboolean b;
00707 
00708         boolean_setter =
00709             (void (*)(QofEntity *, gboolean)) param->param_setfcn;
00710         val = qof_util_bool_to_int(value_string);
00711         if ((val > 1) || (val < 0))
00712             return FALSE;
00713         b = (val == 1) ? TRUE : FALSE;
00714         if (boolean_setter != NULL)
00715             boolean_setter (ent, val);
00716 //      registered_type = TRUE;
00717     }
00718     if (safe_strcmp (param->param_type, QOF_TYPE_KVP) == 0)
00719     {
00720         /* unsupported */
00721         return FALSE;
00722 /*      KvpFrame * frame;
00723         KvpValue * value;
00724 
00725         kvp_frame_setter =
00726             (void (*)(QofEntity *, KvpFrame *)) param->param_setfcn;
00727         if (kvp_frame_setter != NULL)
00728             kvp_frame_setter (rule->targetEnt, cm_kvp);
00729 //      registered_type = TRUE;*/
00730     }
00731     if (safe_strcmp (param->param_type, QOF_TYPE_CHAR) == 0)
00732     {
00733         char_setter =
00734             (void (*)(QofEntity *, gchar)) param->param_setfcn;
00735         if (char_setter != NULL)
00736             char_setter (ent, value_string[0]);
00737 //      registered_type = TRUE;
00738     }
00739     if (safe_strcmp (param->param_type, QOF_TYPE_COLLECT) == 0)
00740     {
00741         /* unsupported */
00742         return FALSE;
00743     }
00744     if (safe_strcmp (param->param_type, QOF_TYPE_CHOICE) == 0)
00745     {
00746         /* unsupported*/
00747         return FALSE;
00748     }
00749 /*  if (registered_type == FALSE)
00750     {
00751         referenceEnt =
00752             cm_param->param_getfcn (rule->importEnt, cm_param);
00753         if (referenceEnt)
00754         {
00755             reference_setter =
00756                 (void (*)(QofEntity *, QofEntity *)) cm_param->
00757                 param_setfcn;
00758             if (reference_setter != NULL)
00759             {
00760                 reference_setter (rule->targetEnt, referenceEnt);
00761             }
00762         }
00763     }*/
00764     return TRUE;
00765 }

gchar* qof_util_param_to_string ( QofEntity ent,
const QofParam param 
)

Converts a parameter to a string for storage or display.

The returned string must be freed by the caller.

Use qof_util_param_set_string to set the parameter using the string. Designed for backends that store all values as strings.

Definition at line 404 of file qofutil.c.

00405 {
00406     gchar *param_string;
00407     gchar param_sa[GUID_ENCODING_LENGTH + 1];
00408     gboolean known_type;
00409     QofType paramType;
00410     const GUID *param_guid;
00411     QofNumeric param_numeric, (*numeric_getter) (QofEntity *, const QofParam *);
00412     gdouble param_double, (*double_getter) (QofEntity *, const QofParam *);
00413     gboolean param_boolean, (*boolean_getter) (QofEntity *, const QofParam *);
00414     gint32 param_i32, (*int32_getter) (QofEntity *, const QofParam *);
00415     gint64 param_i64, (*int64_getter) (QofEntity *, const QofParam *);
00416     gchar param_char, (*char_getter) (QofEntity *, const QofParam *);
00417 
00418     param_string = NULL;
00419     known_type = FALSE;
00420     g_return_val_if_fail (ent && param, NULL);
00421     paramType = param->param_type;
00422     if (safe_strcmp (paramType, QOF_TYPE_STRING) == 0)
00423     {
00424         param_string = g_strdup (param->param_getfcn (ent, param));
00425         if (param_string == NULL)
00426             param_string = g_strup("");
00427         known_type = TRUE;
00428         return param_string;
00429     }
00430     if (safe_strcmp (paramType, QOF_TYPE_TIME) == 0)
00431     {
00432         QofTime *param_qt;
00433         QofDate *qd;
00434         param_qt = param->param_getfcn (ent, param);
00435         qd = qof_date_from_qtime (param_qt);
00436         return qof_date_print (qd, QOF_DATE_FORMAT_UTC);
00437     }
00438     if ((safe_strcmp (paramType, QOF_TYPE_NUMERIC) == 0) ||
00439         (safe_strcmp (paramType, QOF_TYPE_DEBCRED) == 0))
00440     {
00441         numeric_getter =
00442             (QofNumeric (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00443         param_numeric = numeric_getter (ent, param);
00444         param_string = g_strdup (qof_numeric_to_string (param_numeric));
00445         known_type = TRUE;
00446         return param_string;
00447     }
00448     if (safe_strcmp (paramType, QOF_TYPE_GUID) == 0)
00449     {
00450         param_guid = param->param_getfcn (ent, param);
00451         guid_to_string_buff (param_guid, param_sa);
00452         param_string = g_strdup (param_sa);
00453         known_type = TRUE;
00454         return param_string;
00455     }
00456     if (safe_strcmp (paramType, QOF_TYPE_INT32) == 0)
00457     {
00458         int32_getter =
00459             (gint32 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00460         param_i32 = int32_getter (ent, param);
00461         param_string = g_strdup_printf ("%d", param_i32);
00462         known_type = TRUE;
00463         return param_string;
00464     }
00465     if (safe_strcmp (paramType, QOF_TYPE_INT64) == 0)
00466     {
00467         int64_getter =
00468             (gint64 (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00469         param_i64 = int64_getter (ent, param);
00470         param_string = g_strdup_printf ("%" G_GINT64_FORMAT, param_i64);
00471         known_type = TRUE;
00472         return param_string;
00473     }
00474     if (safe_strcmp (paramType, QOF_TYPE_DOUBLE) == 0)
00475     {
00476         double_getter =
00477             (double (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00478         param_double = double_getter (ent, param);
00479         param_string = g_strdup_printf ("%f", param_double);
00480         known_type = TRUE;
00481         return param_string;
00482     }
00483     if (safe_strcmp (paramType, QOF_TYPE_BOOLEAN) == 0)
00484     {
00485         boolean_getter =
00486             (gboolean (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00487         param_boolean = boolean_getter (ent, param);
00488         /* Boolean values need to be lowercase for QSF validation. */
00489         if (param_boolean == TRUE)
00490         {
00491             param_string = g_strdup ("true");
00492         }
00493         else
00494         {
00495             param_string = g_strdup ("false");
00496         }
00497         known_type = TRUE;
00498         return param_string;
00499     }
00500     /* "kvp" contains repeating values, cannot be a single string for the frame. */
00501     if (safe_strcmp (paramType, QOF_TYPE_KVP) == 0)
00502     {
00503         KvpFrame *frame = NULL;
00504         frame = param->param_getfcn (ent, param);
00505         known_type = TRUE;
00506         if (!kvp_frame_is_empty (frame))
00507         {
00508             GHashTable *hash = kvp_frame_get_hash (frame);
00509             param_string = g_strdup_printf ("%s(%d)", QOF_TYPE_KVP,
00510                 g_hash_table_size (hash));
00511         }
00512         /* ensure a newly allocated string is returned, even
00513         if the frame is empty. */
00514         else
00515         {
00516             param_string = g_strdup("");
00517         }
00518         return param_string;
00519     }
00520     if (safe_strcmp (paramType, QOF_TYPE_CHAR) == 0)
00521     {
00522         char_getter =
00523             (gchar (*)(QofEntity *, const QofParam *)) param->param_getfcn;
00524         param_char = char_getter (ent, param);
00525         known_type = TRUE;
00526         return g_strdup_printf ("%c", param_char);
00527     }
00528     /* "collect" contains repeating values, cannot be a single string. */
00529     if (safe_strcmp (paramType, QOF_TYPE_COLLECT) == 0)
00530     {
00531         QofCollection *col = NULL;
00532         col = param->param_getfcn (ent, param);
00533         known_type = TRUE;
00534         return g_strdup_printf ("%s(%d)",
00535             qof_collection_get_type (col), qof_collection_count (col));
00536     }
00537     if (safe_strcmp (paramType, QOF_TYPE_CHOICE) == 0)
00538     {
00539         QofEntity *child = NULL;
00540         child = param->param_getfcn (ent, param);
00541         if (!child)
00542         {
00543             return param_string;
00544         }
00545         known_type = TRUE;
00546         return g_strdup (qof_object_printable (child->e_type, child));
00547     }
00548     if (safe_strcmp (paramType, QOF_PARAM_BOOK) == 0)
00549     {
00550         QofBackend *be;
00551         QofBook *book;
00552         book = param->param_getfcn (ent, param);
00553         PINFO (" book param %p", book);
00554         be = qof_book_get_backend (book);
00555         known_type = TRUE;
00556         PINFO (" backend=%p", be);
00557         if (!be)
00558         {
00559             return QOF_PARAM_BOOK;
00560         }
00561         param_string = g_strdup (be->fullpath);
00562         PINFO (" fullpath=%s", param_string);
00563         if (param_string)
00564         {
00565             return param_string;
00566         }
00567         param_guid = qof_entity_get_guid ((QofEntity*)book);
00568         guid_to_string_buff (param_guid, param_sa);
00569         PINFO (" book GUID=%s", param_sa);
00570         param_string = g_strdup (param_sa);
00571         return param_string;
00572     }
00573     if (!known_type)
00574     {
00575         QofEntity *child = NULL;
00576         child = param->param_getfcn (ent, param);
00577         if (!child)
00578         {
00579             return param_string;
00580         }
00581         return g_strdup (qof_object_printable (child->e_type, child));
00582     }
00583     return g_strdup ("");
00584 }

void qof_util_string_cache_destroy ( void   ) 

The QOF String Cache:

Many strings used throughout QOF and QOF applications are likely to be duplicated.

QOF provides a reference counted cache system for the strings, which shares strings whenever possible.

Use qof_util_string_cache_insert to insert a string into the cache (it will return a pointer to the cached string). Basically you should use this instead of g_strdup.

Use qof_util_string_cache_remove (giving it a pointer to a cached string) if the string is unused. If this is the last reference to the string it will be removed from the cache, otherwise it will just decrement the reference count. Basically you should use this instead of g_free.

Just in case it's not clear: The remove function must NOT be called for the string you passed INTO the insert function. It must be called for the _cached_ string that is _returned_ by the insert function.

Note that all the work is done when inserting or removing. Once cached the strings are just plain C strings.

The string cache is demand-created on first use. Destroy the qof_util_string_cache

Definition at line 381 of file qofutil.c.

00382 {
00383     if (qof_string_cache)
00384         g_cache_destroy (qof_string_cache);
00385     qof_string_cache = NULL;
00386 }

gpointer qof_util_string_cache_insert ( gconstpointer  key  ) 

You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the destroy notifier above.

Definition at line 396 of file qofutil.c.

00397 {
00398     if (key)
00399         return g_cache_insert(qof_util_get_string_cache(), (gpointer)key);
00400     return NULL;
00401 }

void qof_util_string_cache_remove ( gconstpointer  key  ) 

You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or values, for that matter.)

Definition at line 389 of file qofutil.c.

00390 {
00391     if (key)
00392         g_cache_remove (qof_util_get_string_cache (), key);
00393 }

gboolean qof_util_string_isnum ( const guchar *  s  ) 

Returns true if string s is a number, possibly surrounded by whitespace.

Definition at line 198 of file qofutil.c.

00199 {
00200     if (s == NULL)
00201         return FALSE;
00202     if (*s == 0)
00203         return FALSE;
00204 
00205     while (*s && isspace (*s))
00206         s++;
00207 
00208     if (*s == 0)
00209         return FALSE;
00210     if (!isdigit (*s))
00211         return FALSE;
00212 
00213     while (*s && isdigit (*s))
00214         s++;
00215 
00216     if (*s == 0)
00217         return TRUE;
00218 
00219     while (*s && isspace (*s))
00220         s++;
00221 
00222     if (*s == 0)
00223         return TRUE;
00224 
00225     return FALSE;
00226 }

const gchar* qof_util_whitespace_filter ( const gchar *  val  ) 

Return NULL if the field is whitespace (blank, tab, formfeed etc.) Else return pointer to first non-whitespace character.

Definition at line 234 of file qofutil.c.

00235 {
00236     size_t len;
00237     if (!val)
00238         return NULL;
00239 
00240     len = strspn (val, "\a\b\t\n\v\f\r ");
00241     if (0 == val[len])
00242         return NULL;
00243     return val + len;
00244 }

gint safe_strcasecmp ( const gchar *  da,
const gchar *  db 
)

case sensitive comparison of strings da and db - either may be NULL. A non-NULL string is greater than a NULL string.

Parameters:
da string 1.
db string 2.
Returns:
If da == NULL && db != NULL, returns -1. If da != NULL && db == NULL, returns +1. If da != NULL && db != NULL, returns the result of strcmp(da, db). If da == NULL && db == NULL, returns 0.

Definition at line 95 of file qofutil.c.

00096 {
00097     if ((da) && (db))
00098     {
00099         if ((da) != (db))
00100         {
00101             gint retval = strcasecmp ((da), (db));
00102             /* if strings differ, return */
00103             if (retval)
00104                 return retval;
00105         }
00106     }
00107     else if ((!(da)) && (db))
00108         return -1;
00109     else if ((da) && (!(db)))
00110         return +1;
00111     return 0;
00112 }

gint safe_strcmp ( const gchar *  da,
const gchar *  db 
)

The safe_strcmp compares strings da and db the same way that strcmp() does, except that either may be null. This routine assumes that a non-null string is always greater than a null string.

Parameters:
da string 1.
db string 2.
Returns:
If da == NULL && db != NULL, returns -1. If da != NULL && db == NULL, returns +1. If da != NULL && db != NULL, returns the result of strcmp(da, db). If da == NULL && db == NULL, returns 0.
Todo:
replace with g_strcmp0 from glib 2.16

Definition at line 75 of file qofutil.c.

00076 {
00077     if ((da) && (db))
00078     {
00079         if ((da) != (db))
00080         {
00081             gint retval = strcmp ((da), (db));
00082             /* if strings differ, return */
00083             if (retval)
00084                 return retval;
00085         }
00086     }
00087     else if ((!(da)) && (db))
00088         return -1;
00089     else if ((da) && (!(db)))
00090         return +1;
00091     return 0;
00092 }

gchar* strncasestr ( const guchar *  str1,
const guchar *  str2,
size_t  len 
)

Search for str2 in first nchar chars of str1, ignore case. Return pointer to first match, or null. These are just like that strnstr and the strstr functions, except that they ignore the case.

Definition at line 45 of file qofutil.c.

00046 {
00047     while (*str1 && len--)
00048     {
00049         if (toupper (*str1) == toupper (*str2))
00050         {
00051             size_t l;
00052             l = strlen ((gchar*)str2);
00053             if (strncasecmp ((gchar*)str1, (gchar*)str2, l) == 0)
00054                 return (gchar *) str1;
00055         }
00056         str1++;
00057     }
00058     return NULL;
00059 }

gchar* ultostr ( gulong  val,
gint  base 
)

The ultostr() subroutine is the inverse of strtoul(). It accepts a number and prints it in the indicated base. The returned string should be g_freed when done.

Definition at line 134 of file qofutil.c.

00135 {
00136     gchar buf[MAX_DIGITS];
00137     gulong broke[MAX_DIGITS];
00138     gint i;
00139     gulong places = 0, reval;
00140 
00141     if ((2 > base) || (36 < base))
00142         return NULL;
00143 
00144     /* count digits */
00145     places = 0;
00146     for (i = 0; i < MAX_DIGITS; i++)
00147     {
00148         broke[i] = val;
00149         places++;
00150         val /= base;
00151         if (0 == val)
00152             break;
00153     }
00154 
00155     /* normalize */
00156     reval = 0;
00157     for (i = places - 2; i >= 0; i--)
00158     {
00159         reval += broke[i + 1];
00160         reval *= base;
00161         broke[i] -= reval;
00162     }
00163 
00164     /* print */
00165     for (i = 0; i < (gint) places; i++)
00166     {
00167         if (10 > broke[i])
00168         {
00169             buf[places - 1 - i] = 0x30 + broke[i];  /* ascii digit zero */
00170         }
00171         else
00172         {
00173             buf[places - 1 - i] = 0x41 - 10 + broke[i]; /* ascii capital A */
00174         }
00175     }
00176     buf[places] = 0x0;
00177 
00178     return g_strdup (buf);
00179 }


Generated on Sat Aug 15 15:46:32 2009 for QOF by  doxygen 1.5.9