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 113 of file qofutil.c.

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

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 778 of file qofutil.c.

00779 {
00780     qof_query_shutdown ();
00781     qof_object_shutdown ();
00782     guid_shutdown ();
00783     qof_date_close ();
00784     qof_util_string_cache_destroy ();
00785 }

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 767 of file qofutil.c.

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

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 250 of file qofutil.c.

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

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 331 of file qofutil.c.

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

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 307 of file qofutil.c.

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

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 279 of file qofutil.c.

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

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 585 of file qofutil.c.

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

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 402 of file qofutil.c.

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

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 379 of file qofutil.c.

00380 {
00381     if (qof_string_cache)
00382         g_cache_destroy (qof_string_cache);
00383     qof_string_cache = NULL;
00384 }

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 394 of file qofutil.c.

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

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 387 of file qofutil.c.

00388 {
00389     if (key)
00390         g_cache_remove (qof_util_get_string_cache (), key);
00391 }

gboolean qof_util_string_isnum ( const guchar *  s  ) 

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

Definition at line 196 of file qofutil.c.

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

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 232 of file qofutil.c.

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

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 93 of file qofutil.c.

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

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 73 of file qofutil.c.

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

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             if (strncasecmp (str1, str2, strlen (str2)) == 0)
00052                 return (gchar *) str1;
00053         }
00054         str1++;
00055     }
00056     return NULL;
00057 }

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 132 of file qofutil.c.

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


Generated on Mon Jul 13 05:15:16 2009 for QOF by  doxygen 1.5.9