static void
received_chat_msg_cb(PurpleAccount *account, char *sender, char *buffer,
					 PurpleConversation *chat, PurpleMessageFlags flags, void *data)
{
	gboolean on_focus;
	char *message, *notification;
	int len;
	
	DEBUG_MSG("received_chat_msg_cb\n");
		
	g_return_if_fail( is_allowed(account) );
		
	on_focus = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_focus");
	if(chat != NULL && !on_focus && chat->ui_ops->has_focus(chat))
		return;
		
	// copy string to temporary variable)
	message = malloc(s_strlen(buffer)+1);
	strcpy(message, buffer);
	special_entries(message);
	strip_tags(message);
	
	len = s_strlen(sender) + s_strlen(message) + 3;
	// message
	notification = malloc( len );
	g_snprintf(notification, len, "%s: %s", sender, message);
	
	gntp_notify("chat-msg-received", NULL, "Chat Message", notification, NULL);
	
	free(message);
	free(notification);
}
static void
buddy_signed_off_cb(PurpleBuddy *buddy, void *data)
{
	int len;
	char* buddy_nick, *buddy_name, *icon_path, *growl_msg;
	PurpleBuddyIcon* icon;

	DEBUG_MSG("buddy_signed_off_cb\n");
	
	g_return_if_fail( buddy != NULL );	
	g_return_if_fail( is_allowed(purple_buddy_get_account(buddy)) );
		
	buddy_nick = (char*)purple_buddy_get_alias(buddy);
	buddy_name = (char*)purple_buddy_get_name(buddy);
	icon = purple_buddy_get_icon(buddy);
	icon_path = (char*)purple_buddy_icon_get_full_path(icon);
		
	len = s_strlen(buddy_nick) + s_strlen(buddy_name) + 2;
	
	growl_msg = malloc( len );
	
	g_snprintf(growl_msg, len, "%s\n%s", buddy_nick, buddy_name );
	gntp_notify("buddy-sign-out", icon_path, "Signed Off", growl_msg, NULL);
	
	free(growl_msg);
}
static void
buddy_icon_changed_cb(PurpleBuddy *buddy)
{	
	PurpleBuddyIcon* icon;
	int len;
	char *icon_path, *buddy_nick, *buddy_name, *growl_msg;
	
	DEBUG_MSG("buddy_icon_changed_cb\n");
	
	g_return_if_fail( buddy != NULL );

	buddy_nick = (char*)purple_buddy_get_alias(buddy);
	buddy_name = (char*)purple_buddy_get_name(buddy);
	icon = purple_buddy_get_icon(buddy);
	icon_path = (char*)purple_buddy_icon_get_full_path(icon);
	
	if(buddy_nick == NULL)
		DEBUG_MSG("buddy_nick is NULL\n");
	if(buddy_name == NULL)
		DEBUG_MSG("buddy_name is NULL\n");	
	if(icon == NULL)
		DEBUG_MSG("icon is NULL\n");	
	if(icon_path == NULL)
		DEBUG_MSG("icon_path is NULL\n");	
	
	if(icon_path != NULL)
	{
		if(g_list_find_custom(img_list, icon_path, (GCompareFunc)strcmp))
		{
			DEBUG_MSG("icon_path found in list - leaving function\n");
			return;
		}
		img_list = g_list_prepend(img_list, icon_path);
		
		if(g_list_find_custom(img_list, icon_path, (GCompareFunc)strcmp))
			DEBUG_MSG("icon_path added to list of known icons\n");
	}
		
	// is allowed?
	g_return_if_fail( is_allowed(purple_buddy_get_account(buddy)) );	
	//hack to hide spam when signing on to account
	g_return_if_fail( GetTickCount() - start_tick_image > 500 );
	
	len = s_strlen(buddy_nick) + s_strlen(buddy_name) + 2;
	growl_msg = malloc( len ); 
	g_snprintf(growl_msg, len, "%s\n%s", buddy_nick, buddy_name );
	
	gntp_notify("buddy-change-image", icon_path, "Changed Image", growl_msg, NULL);
	free(growl_msg);
}
static void
received_im_msg_cb(PurpleAccount *account, char *sender, char *buffer,
				   PurpleConversation *conv, PurpleMessageFlags flags, void *data)
{	
	gboolean on_focus;
	char *message, *notification, *buddy_nick, *iconpath;
	PurpleBuddy* buddy;
	PurpleBuddyIcon* icon;
	int len;
	
	DEBUG_MSG("received_im_msg_cb\n");
		
	g_return_if_fail( is_allowed(account) );
		
	on_focus = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_focus");
	if(conv != NULL && !on_focus && conv->ui_ops->has_focus(conv))
		return;
	
	
	// copy string to temporary variable)
	message = malloc(s_strlen(buffer)+1);
	strcpy(message, buffer);
	special_entries(message);
	strip_tags(message);

	
	// nickname
	buddy = purple_find_buddy(account, sender);
	if(buddy == NULL)
		buddy_nick = sender;
	else
		buddy_nick = (char*)purple_buddy_get_alias( buddy );
	
	len = s_strlen(buddy_nick) + s_strlen(message) + 3;

	// message
	notification = malloc( len );
	g_snprintf(notification, len, "%s: %s", buddy_nick, message);
	
	// icon
	icon = purple_buddy_get_icon( buddy );
	iconpath = purple_buddy_icon_get_full_path( icon );
	
	gntp_notify("im-msg-received", iconpath, "IM Message", notification, NULL);
	
	free(message);
	free(notification);
}
Exemple #5
0
CStringBuffer CConsoleClipboard::GetClipboardText()
{
	CStringBuffer tmp;

#ifdef OK_SYS_WINDOWS
	if (!IsClipboardFormatAvailable(_CLIPBOARDTEXTFORMAT))
		return tmp;

	HWND hwnd = GetConsoleWindow();

	if ( !hwnd )
		return tmp;
    if (!OpenClipboard(hwnd)) 
		return tmp;
 
    HGLOBAL hglb = GetClipboardData(_CLIPBOARDTEXTFORMAT); 
    if (hglb != NULL) 
    { 
        LPTSTR  lptstr = (LPTSTR)GlobalLock(hglb); 
        if (lptstr != NULL) 
        {
			dword tlen = s_strlen(lptstr, INT_MAX);
			tmp.SetSize(__FILE__LINE__ tlen + 1);
			s_strcpy(CastMutable(CPointer, tmp.GetString()), tlen + 1, lptstr);
            GlobalUnlock(hglb); 
        } 
    } 
    CloseClipboard();
#endif
#ifdef OK_SYS_UNIX
	tmp = _clipboardtext;
#endif
	return tmp;
 }
// returns NULL if its the same
GList* buddy_status_is_new(PurpleBuddy* buddy, char* status_msg)
{
	struct buddy_status temp; 
	temp.buddy = buddy;
	GList* node = g_list_find_custom(buddys_status, &temp, (GCompareFunc)compare_status);
	if(node != NULL)
	{
		DEBUG_MSG("buddy status node found\n");
		struct buddy_status* node_status = node->data;
		if(strcmp(status_msg, node_status->status) == 0)
			return NULL;
	}
	else
	{
		DEBUG_MSG("buddy status node created\n");
		struct buddy_status* node_status = malloc(sizeof(struct buddy_status));
		char* the_status = malloc( s_strlen(status_msg)+1 );
		strcpy(the_status, status_msg);
		
		node_status->buddy = buddy;
		node_status->status = the_status;
		buddys_status = g_list_prepend(buddys_status, node_status);
	}
	
	return node;
}
Exemple #7
0
int main()
{
    char string[] = "Hello, world";

    printf("%d\n", s_strlen(string));
    return 0;
}
Exemple #8
0
size_t
s_strlcat(Char *dst, const Char *src, size_t siz)
{
        Char *d = dst;
        const Char *s = src;
        size_t n = siz;
        size_t dlen;

        /* Find the end of dst and adjust bytes left but don't go past end */
        while (n-- != 0 && *d != '\0')
                d++;
        dlen = d - dst;
        n = siz - dlen;

        if (n == 0)
                return(dlen + s_strlen((Char *)s));
        while (*s != '\0') {
                if (n != 1) {
                        *d++ = *s;
                        n--;
                }
                s++;
        }
        *d = '\0';

        return(dlen + (s - src));       /* count does not include NUL */
}
Exemple #9
0
/* Simple test for possible abbreviation. If item starts and ends in
 * capitals and is less than 4 chars long then it's an abbreviation.
 */
s_bool s_test_abbreviation(const char *item_string, s_erc *error)
{
	const char *tmp;
	size_t len;


	S_CLR_ERR(error);
	len = s_strlen(item_string, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_abbreviation",
				  "Call to \"s_strlen\" failed"))
		return FALSE;

	tmp = s_strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", item_string[len-1], error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_period_abbreviation",
				  "Call to \"s_strchr\" failed"))
		return FALSE;

	if (tmp == NULL) /* item is probably not abbreviation, doesn't end in a capital */
		return FALSE;

	tmp = s_strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", item_string[0], error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_abbreviation",
				  "Call to \"s_strchr\" failed"))
		return FALSE;

	/* item starts and ends with capital and is less than 4 chars
	   long, so is probably an abbreviation */
	if ((tmp != NULL) && (len < 4))
		return TRUE;

	return FALSE;
}
static void
chat_buddy_left_cb(PurpleConversation *conv, const char *user,
				   const char *reason, void *data)
{
	char *notification;
	int len = s_strlen((char*)conv->title)+s_strlen((char*)user) + 7;
	
	DEBUG_MSG("chat_buddy_left_cb\n");
	
	g_return_if_fail( is_allowed(purple_conversation_get_account(conv)) );
		
	notification = malloc( len );
	g_snprintf(notification, len, "%s left %s", user, conv->title);
	
	gntp_notify("chat-buddy-sign-out", NULL, "Chat Leave", notification, NULL);
	free(notification);
}
static void
connection_error_cb(PurpleConnection *gc, PurpleConnectionError err,
                    const gchar *desc, void *data)
{
	char* growl_msg;
	PurpleAccount* account = purple_connection_get_account(gc);
	const gchar *username =	purple_account_get_username(account);
	int len = s_strlen((char*)desc) + s_strlen((char*)username) + 2 ;
	
	DEBUG_MSG("connection_error_cb\n");
	
	growl_msg = malloc( len);
	g_snprintf(growl_msg, len, "%s\n%s", desc, username);
	
	gntp_notify("connection-error", NULL, "Connection Error", growl_msg, NULL);
	
	free(growl_msg);
}
static int
is_allowed(PurpleAccount *account)
{
	char* id;
	char *path;
	int len;
	gboolean allowed_protocol;
	gboolean available, unavailable, invisible, away;
	
	available = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_available");
	unavailable = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_unavailable");
	invisible = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_invisible");
	away = purple_prefs_get_bool("/plugins/core/pidgin-gntp/on_away");
		
	if(!available && acc_status == PURPLE_STATUS_AVAILABLE)
			return 0;
	if(!unavailable && acc_status == PURPLE_STATUS_UNAVAILABLE)
			return 0;
	if(!invisible && acc_status == PURPLE_STATUS_INVISIBLE)
			return 0;
	if(!away && acc_status == PURPLE_STATUS_AWAY)
			return 0;
	if(!away && acc_status == PURPLE_STATUS_EXTENDED_AWAY)
			return 0;
			
	id = (char*)purple_account_get_protocol_id (account);		
	len = s_strlen("/plugins/core/pidgin-gntp/") + s_strlen(id) + 1;
	
	path = malloc( len ); 
	g_snprintf(path, len, "%s%s", "/plugins/core/pidgin-gntp/", id );
	
	if(!purple_prefs_exists(path))
		purple_prefs_add_bool(path, TRUE);
		
	allowed_protocol = purple_prefs_get_bool(path);
	free(path);
	
	if(!allowed_protocol)
		return 0;
					
	DEBUG_MSG("allowed by current settings\n");	
	return 1;
}
void s_strcpy(char *str1, char *str2)
{
  int len;
  int i;
  len = s_strlen(str2);
  for (i = 0; i <= len; i++) {
    str1[i] = str2[i];
  }
  return;
}
static void
chat_buddy_joined_cb(PurpleConversation *conv, const char *user,
					 PurpleConvChatBuddyFlags flags, gboolean new_arrival, void *data)
{	
	char *notification;
	int len = s_strlen((char*)conv->title)+s_strlen((char*)user) + 9;
	
	DEBUG_MSG("chat_buddy_joined_cb\n");
	
	g_return_if_fail( is_allowed(purple_conversation_get_account(conv)) );
		
	//hack to hide spam when join channel
	if( GetTickCount() - start_tick_chat < 10000) return;

	notification = malloc( len );
	g_snprintf(notification, len, "%s joined %s", user, conv->title);
	
	gntp_notify("chat-buddy-sign-in", NULL, "Chat Join", notification, NULL);
	free(notification);
}
static gint
chat_invited_cb(PurpleAccount *account, const char *inviter,
				const char *room_name, const char *message,
				const GHashTable *components, void *data)
{
	char *notification;
	int len = 	s_strlen((char*)inviter)+
				s_strlen((char*)room_name)+
				s_strlen((char*)message) + 23;
	
	DEBUG_MSG("chat_invited_cb\n");
	
	if( !is_allowed(account) )
		return 0;
		
	notification = malloc( len );
	g_snprintf(notification, len, "%s has invited you to %s\n%s", inviter, room_name, message);
	
	gntp_notify("chat-invited", NULL, "Chat Invite", notification, NULL);
	free(notification);
	
	return 0;
}
static void
chat_topic_changed_cb(PurpleConversation *conv, const char *who,
					  const char *topic, void *data)
{
	char *notification;
	int len = 	s_strlen((char*)who)+
				s_strlen((char*)conv->title)+
				s_strlen((char*)topic) + 40;
							
	DEBUG_MSG("chat_topic_changed_cb\n");
	
	if(conv == NULL || topic == NULL || who == NULL)
		return;
	
	g_return_if_fail( is_allowed(purple_conversation_get_account(conv)) );
		
	notification = malloc( len );
					
	g_snprintf(notification, len, "%s topic: %s\nby %s", conv->title, topic, who);				
	
	gntp_notify("chat-topic-change", NULL, "Chat Topic Changed", notification, NULL);
	
	free(notification);
}
Exemple #17
0
static const char* getLastChars (const char* string, int n,  s_erc *error)
{
	char* result = NULL;
	char tmp[7];
	int i = 0;

	int j = s_strlen(string, error);
	if (S_CHK_ERR(error, S_CONTERR,
			  "getLastChars",
			  "Call to \"s_strlen\" failed"))
		return NULL;

	if (string == NULL || j < n )
		return NULL;

	while (string[i] != '\0' && j > 0 )
	{
		s_strncpy (tmp, string +i, 1, error);
		if (S_CHK_ERR(error, S_CONTERR,
				  "getLastChars",
				  "Call to \"s_strncpy\" failed"))
			return NULL;

		j -= 1;

		if ( j < n )
		{
			s_sappend (&result, tmp, error);
			if (S_CHK_ERR(error, S_CONTERR,
					  "getLastChars",
					  "Call to \"s_sappend\" failed"))
				return NULL;
		}

		i += s_width(tmp, error);
		if (S_CHK_ERR(error, S_CONTERR,
				  "getLastChars",
				  "Call to \"s_width\" failed"))
			return NULL;
	}

		return result;
}
int main(void)
{
	s_erc error = S_SUCCESS; /* start of with a clean slate */
	size_t word_length;


	/* initialize speect */
	error = speect_init(NULL);
	if (error != S_SUCCESS)
	{
		printf("Failed to initialize Speect\n");
		return 1;
	}

	/* get the length (number of characters) of the given word. */
	word_length = s_strlen("こんにちは", &error);
	if (S_CHK_ERR(&error, S_CONTERR,
				  "main",
				  "Call to \"s_strlen\" failed"))
	{
		speect_quit();
		return 1;
	}
	else
	{
		printf("the length (number of characters) of 'こんにちは' is %lu\n", (unsigned long)word_length);
	}

	/* quit speect */
	error = speect_quit();
	if (error != S_SUCCESS)
	{
		printf("Call to 'speect_quit' failed\n");
		return 1;
	}

	return 0;
}
Exemple #19
0
/* test if the capital in the token and the post punc period in the
 * item are a break. break is is period and capital is seperated by
 * more than one space, for example "done.  And blah"
 */
s_bool s_test_period_capital(const char *token_whitespace, const char *token_string,
							 const char *item_post_punc, s_erc *error)
{
	const char *tmp;
	size_t len;


	S_CLR_ERR(error);
	tmp = s_strchr(item_post_punc, '.', error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_period_capital",
				  "Call to \"s_strchr\" failed"))
		return FALSE;

	if (tmp == NULL) /* post punc is not period, no break */
		return FALSE;

	len = s_strlen(token_whitespace, error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_period_capital",
				  "Call to \"s_strlen\" failed"))
		return FALSE;

	if (len < 2) /* maybe token is a abbreviation, ambiguous */
		return FALSE;

	tmp = s_strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", token_string[0], error);
	if (S_CHK_ERR(error, S_CONTERR,
				  "s_test_period_capital",
				  "Call to \"s_strchr\" failed"))
		return FALSE;

	if (tmp == NULL) /* token does not start with a capital letter */
		return FALSE;

	return TRUE;
}
static PurplePluginPrefFrame *
get_plugin_pref_frame(PurplePlugin *plugin)
{
	PurplePluginPrefFrame *frame;
	PurplePluginPref *ppref;

	PurpleAccount *account;
	char *name, *id, *path;
	int len;
	GList *l, *listed_protocols;
	
	DEBUG_MSG("get_plugin_pref_frame");
	
	frame = purple_plugin_pref_frame_new();

	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/on_focus", "show message when window is focused");
	purple_plugin_pref_frame_add(frame, ppref);
	
	ppref = purple_plugin_pref_new_with_label("Send notifications when status is:");
	purple_plugin_pref_frame_add(frame, ppref);	
	
	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/on_available", "available");
	purple_plugin_pref_frame_add(frame, ppref);
	
	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/on_unavailable", "unavailable");
	purple_plugin_pref_frame_add(frame, ppref);
	
	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/on_invisible", "invisible");
	purple_plugin_pref_frame_add(frame, ppref);
	
	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/on_away", "away");
	purple_plugin_pref_frame_add(frame, ppref);
	
	
	ppref = purple_plugin_pref_new_with_label("Starting delay (to prevent spam while connecting):");
	purple_plugin_pref_frame_add(frame, ppref);
	
	ppref = purple_plugin_pref_new_with_name_and_label(
	"/plugins/core/pidgin-gntp/hack_ms", "value in milliseconds (1000ms = 1 sec)");
	purple_plugin_pref_set_bounds(ppref, 0, 30000);
	purple_plugin_pref_frame_add(frame, ppref);
	
	
	ppref = purple_plugin_pref_new_with_label("Following protocols sends notifications:");
	purple_plugin_pref_frame_add(frame, ppref);
		
	listed_protocols = NULL;
	for (l = purple_accounts_get_all(); l != NULL; l = l->next)
	{
		account = (PurpleAccount *)l->data;
		
		name = (char*)purple_account_get_protocol_name (account);
		id = (char*)purple_account_get_protocol_id (account);		
		
		if( !g_list_find_custom(listed_protocols, id, (GCompareFunc)strcmp) )
		{
			listed_protocols = g_list_prepend (listed_protocols, id);
			
			len = s_strlen("/plugins/core/pidgin-gntp/") + s_strlen(id) + 1;
			path = malloc( len ); 
			g_snprintf(path, len, "%s%s", "/plugins/core/pidgin-gntp/", id );
				
			if(!purple_prefs_exists(path))
				purple_prefs_add_bool(path, TRUE);
			
			ppref = purple_plugin_pref_new_with_name_and_label(path, name);
			purple_plugin_pref_frame_add(frame, ppref);
			free(path);
		}
	}
	g_list_free(listed_protocols);
			
	ppref = purple_plugin_pref_new_with_label(REV);
	purple_plugin_pref_frame_add(frame, ppref);

	return frame;
}
Exemple #21
0
/*

    Function:   iSrchFilterGetSearchBitmapFromFilter()

    Purpose:    This function collects and searches filters and returns
                a bit map if there are any filters.
                
                The filter can either be a list name (mapping to a file),
                or a list of terms. If it is a list of terms, then each term has to be
                comma separated and must not contain any spaces.
                
                A search bitmap will not be allocated if no terms were found
                and an existing bitmap was not passed

    Parameters: pssSrchSearch           search structure
                psiSrchIndex            index structure
                uiLanguageID            language ID
                pspfSrchParserFilter    search parser string filter
                uiStartDocumentID       start document ID restriction (0 for no restriction)
                uiEndDocumentID         end document ID restriction (0 for no restriction)
                ppsbSrchBitmap          return pointer for the search bitmap structure 

    Globals:    none

    Returns:    SRCH error code

*/
static int iSrchFilterGetSearchBitmapFromFilter
(
    struct srchSearch *pssSrchSearch,
    struct srchIndex *psiSrchIndex,
    unsigned int uiLanguageID,
    struct srchParserFilter *pspfSrchParserFilter, 
    unsigned int uiStartDocumentID,
    unsigned int uiEndDocumentID,
    struct srchBitmap **ppsbSrchBitmap
)
{

    int                         iError = SRCH_NoError;
    void                        *pvLngStemmer = NULL;
    
    unsigned int                uiSrchParserSearchCacheID = SRCH_PARSER_MODIFIER_UNKNOWN_ID;
    
    unsigned char               pucConfigValue[SRCH_INFO_SYMBOL_MAXIMUM_LENGTH + 1] = {'\0'};
    unsigned char               pucFilterFilePath[UTL_FILE_PATH_MAX + 1] = {'\0'};
    FILE                        *pfFilterFile = NULL;
    off_t                       zFilterFileLength = 0;
    unsigned char               *pucFilterFileMappingPtr = NULL;
    time_t                      tFilterFileLastUpdate = (time_t)0;

    wchar_t                     *pwcTerms = NULL;
    wchar_t                     *pwcNormalizedExcludedTermsStrtokPtr = NULL;

    struct srchTermDictInfo     *pstdiSrchTermDictInfos = NULL;
    struct srchTermDictInfo     *pstdiSrchTermDictInfosPtr = NULL;
    unsigned int                uiSrchTermDictInfosLength = 0;
    unsigned int                uiI = 0;
    
    unsigned int                uiNormalizedTermsLength = 0;

    wchar_t                     *pwcTerm = NULL;
    unsigned char               *pucTerm = NULL;
    
    unsigned char               *pucFieldIDBitmap = NULL;

    

/*     iUtlLogDebug(UTL_LOG_CONTEXT, "iSrchFilterGetSearchBitmapFromFilter - pspfSrchParserFilter->pwcFilter: '%ls'", pspfSrchParserFilter->pwcFilter); */


    ASSERT(pssSrchSearch != NULL);
    ASSERT(psiSrchIndex != NULL);
    ASSERT(uiLanguageID >= 0);
    ASSERT(pspfSrchParserFilter != NULL);
    ASSERT(uiStartDocumentID >= 0);
    ASSERT(uiEndDocumentID >= 0);
    ASSERT(ppsbSrchBitmap != NULL);


    /* Create the stemmer */
    if ( (iError = iLngStemmerCreateByID(psiSrchIndex->uiStemmerID, uiLanguageID, &pvLngStemmer)) != LNG_NoError ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Failed to create a stemmer, lng error: %d.", iError);
        iError = SRCH_FilterCreateStemmerFailed;
        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
    }

    /* Get the parser search cache ID */
    if ( (iError = iSrchParserGetModifierID(pssSrchSearch->pvSrchParser, SRCH_PARSER_MODIFIER_SEARCH_CACHE_ID, &uiSrchParserSearchCacheID)) != SRCH_NoError ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Failed to get the parser search cache ID, srch error: %d.", iError);
        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
    }


    /* Terms based filter */
    if ( pspfSrchParserFilter->uiFilterTypeID == SRCH_PARSER_FILTER_TYPE_TERMS_ID ) {
        ;
    }
    
    /* List based filter */
    else if ( pspfSrchParserFilter->uiFilterTypeID == SRCH_PARSER_FILTER_TYPE_LIST_ID ) {

        unsigned char   *pucFilterDirectoryPath = NULL;
        unsigned char   *pucFilterName = NULL;
        unsigned char   pucFilterFileName[UTL_FILE_PATH_MAX + 1] = {'\0'};


        /* Check for the filter file if there is a location for these files */
        if ( (iError = iUtlConfigGetValue(pssSrchSearch->pvUtlConfig, SRCH_SEARCH_CONFIG_FILTER_FILES_LOCATION, pucConfigValue, SRCH_INFO_SYMBOL_MAXIMUM_LENGTH + 1)) != UTL_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to get the file file location from the search configuration, symbol name: '%s', utl error: %d.", 
                    SRCH_SEARCH_CONFIG_FILTER_FILES_LOCATION, iError); 
            iError = SRCH_FilterInvalidFilterFileLocation;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Get a pointer to the filter directory path, exclude the file protocol url if it is there */
        pucFilterDirectoryPath = (s_strncasecmp(pucConfigValue, SRCH_FILTER_FILE_PROTOCOL_URL, s_strlen(SRCH_FILTER_FILE_PROTOCOL_URL)) == 0) ? 
                pucConfigValue + s_strlen(SRCH_FILTER_FILE_PROTOCOL_URL) : pucConfigValue;

        /* Convert the filter from wide characters to utf-8, pucFilterName is allocated */
        if ( (iError = iLngConvertWideStringToUtf8_d(pspfSrchParserFilter->pwcFilter, 0, &pucFilterName)) != LNG_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to convert a filter name from wide characters to utf-8, lng error: %d.", iError);
            iError = SRCH_FilterCharacterSetConvertionFailed;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Create the filter file name */
        snprintf(pucFilterFileName, UTL_FILE_PATH_MAX + 1, "%s%s", pucFilterName, SRCH_FILTER_FILENAME_EXTENSION);
        
        /* Free the utf-8 filter file name */
        s_free(pucFilterName);

        /* Create the filter file path */
        if ( (iError = iUtlFileMergePaths(pucFilterDirectoryPath, pucFilterFileName, pucFilterFilePath, UTL_FILE_PATH_MAX + 1)) != UTL_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to create the filter file path, file file name: '%s', filter directory path: '%s', utl error: %d", 
                    pucFilterFileName, pucFilterDirectoryPath, iError); 
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
    
        /* Check if the filter file is there */
        if ( bUtlFileIsFile(pucFilterFilePath) == false ) {
                iUtlLogError(UTL_LOG_CONTEXT, "Failed to find the filter file: '%s'.", pucFilterFilePath); 
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Open the filter file */
        if ( (pfFilterFile = s_fopen(pucFilterFilePath, "r")) == NULL ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to open the filter file: '%s'.", pucFilterFilePath); 
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Get the filter file modification date */            
        if ( (iError = iUtlFileGetFileModificationTimeT(pfFilterFile, &tFilterFileLastUpdate)) != UTL_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to get the last modification time of the filter file: '%s', utl error: %d.", pucFilterFilePath, iError); 
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
    }


    /* Get the bitmap from the search cache, note that we dont need to differentiate between terms or lists 
    ** since terms will have a tFilterFileLastUpdate of 0 and lists will have a non-zero tFilterFileLastUpdate 
    */
    if ( uiSrchParserSearchCacheID == SRCH_PARSER_MODIFIER_SEARCH_CACHE_ENABLE_ID ) {

        if ( (iError = iSrchCacheGetSearchBitmap(pssSrchSearch->pvSrchCache, psiSrchIndex, pspfSrchParserFilter->pwcFilter, 
                tFilterFileLastUpdate, ppsbSrchBitmap)) == SRCH_NoError ) {

            /* We are all set */
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
    }

    
    /* Terms based filter */
    if ( pspfSrchParserFilter->uiFilterTypeID == SRCH_PARSER_FILTER_TYPE_TERMS_ID ) {
    
        /* Make a straight copy of the terms */
        if ( (pwcTerms = s_wcsdup(pspfSrchParserFilter->pwcFilter)) == NULL ) {
            iError = SRCH_MemError;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
        
        iSrchReportAppend(pssSrchSearch->pvSrchReport, "%s The search filtered on the following terms: '%ls'\n", REP_SEARCH_RESTRICTION, pspfSrchParserFilter->pwcFilter);

    }
    /* List based filter */
    else if ( pspfSrchParserFilter->uiFilterTypeID == SRCH_PARSER_FILTER_TYPE_LIST_ID ) {

        /* Get the file length */
        if ( (iError = iUtlFileGetFileLength(pfFilterFile, &zFilterFileLength)) != UTL_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to get the length of the filter file: '%s', utl error: %d.", pucFilterFilePath, iError); 
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
        
        /* Map in the entire file */
        if ( (iError = iUtlFileMemoryMap(fileno(pfFilterFile), 0, zFilterFileLength, PROT_READ, (void **)&pucFilterFileMappingPtr) != UTL_NoError) ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to map in the filter file: '%s', utl error: %d.", pucFilterFilePath, iError);
            iError = SRCH_FilterInvalidFilterFile;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Convert the terms from utf-8 to wide characters, pwcTerms is allocated */
        if ( (iError = iLngConvertUtf8ToWideString_d(pucFilterFileMappingPtr, zFilterFileLength, &pwcTerms)) != LNG_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to convert the terms from utf-8 to wide characters, lng error: %d.", iError);
            iError = SRCH_FilterCharacterSetConvertionFailed;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }

        /* Unmap the filter file */
        iUtlFileMemoryUnMap(pucFilterFileMappingPtr, zFilterFileLength);
        pucFilterFileMappingPtr = NULL;

        /* Close the filter file */
        s_fclose(pfFilterFile);
        pfFilterFile = NULL;

        /* Convert newlines to commas */
        iUtlStringsReplaceCharacterInWideString(pwcTerms, L'\n', L',');

        iSrchReportAppend(pssSrchSearch->pvSrchReport, "%s The search filtered on the following list: '%ls'\n", REP_SEARCH_RESTRICTION, pspfSrchParserFilter->pwcFilter);
    }



    /* Allocate a field ID bitmap only if there are any fields other than field ID 0 */
    if ( psiSrchIndex->uiFieldIDMaximum > 0 ) {

        /* Allocate the field ID bitmap - field ID 0 is not a field */
        if ( (pucFieldIDBitmap = (unsigned char *)s_malloc(sizeof(unsigned char) * UTL_BITMAP_GET_BITMAP_BYTE_LENGTH(psiSrchIndex->uiFieldIDMaximum))) == NULL ) {
            iError = SRCH_MemError;
            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
        }
    }


    /* Loop parsing the terms */
    for ( pwcTerm = s_wcstok(pwcTerms, SRCH_FILTER_TERM_SEPARATORS, (wchar_t **)&pwcNormalizedExcludedTermsStrtokPtr); pwcTerm != NULL; 
            pwcTerm = s_wcstok(NULL, SRCH_FILTER_TERM_SEPARATORS, (wchar_t **)&pwcNormalizedExcludedTermsStrtokPtr) ) {

        /* Trim the string if needed, we do this so that we can handle lists like 'bats, lions, elephants' */
        iUtlStringsTrimWideString(pwcTerm);

        /* Term contains spaces, treat as a phrase */
        if ( s_wcschr(pwcTerm, L' ') != NULL ) {

            wchar_t                     *pwcTermStrtokPtr = NULL;
            wchar_t                     *pwcSubTerm = NULL;
            struct srchPostingsList     *psplSrchPostingsList = NULL;

            /* Get the first subterm - wcstok_r along spaces */
            pwcSubTerm = s_wcstok(pwcTerm, L" ", (wchar_t **)&pwcTermStrtokPtr);

            /* Loop while there are subterm */
            while ( pwcSubTerm != NULL ) {

                boolean     bFieldIDBitmapSet = false;

                /* Clear the bitmap */
                if ( pucFieldIDBitmap != NULL ) {
                    UTL_BITMAP_CLEAR_POINTER(pucFieldIDBitmap, psiSrchIndex->uiFieldIDMaximum);
                }

                /* Process the term, this returns a pointer to the processed term and sets the bitmap as needed */
                if ( (iError = iSrchFilterProcessTerm(pssSrchSearch, psiSrchIndex, pvLngStemmer, pwcSubTerm, pucFieldIDBitmap, psiSrchIndex->uiFieldIDMaximum, 
                        &pwcSubTerm, &bFieldIDBitmapSet)) != SRCH_NoError ) {
                    goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                }

                /* Skip the term if it was stemmed out of existence */
                if ( bUtlStringsIsWideStringNULL(pwcSubTerm) == false ) {

                    unsigned char               *pucSubTerm = NULL;
                    struct srchPostingsList     *psplSrchPostingsTempList = NULL;


                    /* Convert the subterm from wide characters to utf-8, pucSubTerm is allocated */
                    if ( (iError = iLngConvertWideStringToUtf8_d(pwcSubTerm, 0, &pucSubTerm)) != LNG_NoError ) {
                        iUtlLogError(UTL_LOG_CONTEXT, "Failed to convert a filter term from wide characters to utf-8, lng error: %d.", iError);
                        iError = SRCH_FilterCharacterSetConvertionFailed;
                        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                    }

                    /* Search to postings list */
                    iError = iSrchTermSearchGetSearchPostingsListFromTerm(pssSrchSearch, psiSrchIndex, pucSubTerm, SRCH_SEARCH_TERM_WEIGHT_DEFAULT, 
                            (bFieldIDBitmapSet == true) ? pucFieldIDBitmap : NULL, (bFieldIDBitmapSet == true) ? psiSrchIndex->uiFieldIDMaximum : 0, 
                            0, 0, 0, &psplSrchPostingsTempList);

                    /* Free the subterm */
                    s_free(pucSubTerm);

                    /* Check the returned error */
                    if ( iError != SRCH_NoError ) {
                        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                    }

                    
                    /* Break here if there was no terms returned as this will kill the phrase */
                    if ( (psplSrchPostingsTempList == NULL) || (psplSrchPostingsTempList->uiSrchPostingsLength == 0) ) {
                        
                        iSrchPostingFreeSrchPostingsList(psplSrchPostingsTempList);
                        psplSrchPostingsTempList = NULL;

                        iSrchPostingFreeSrchPostingsList(psplSrchPostingsList);
                        psplSrchPostingsList = NULL;

                        break;
                    }


                    /* Merge the postings lists, ADJ with a distance of 1 and a strict boolean match */
                    if ( psplSrchPostingsList != NULL ) {
                        if ( (iError = iSrchPostingMergeSrchPostingsListsADJ(psplSrchPostingsList, psplSrchPostingsTempList, 1, SRCH_PARSER_MODIFIER_BOOLEAN_OPERATION_STRICT_ID, &psplSrchPostingsList)) != SRCH_NoError ) {
                            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                        }
                    }
                    else {
                        psplSrchPostingsList = psplSrchPostingsTempList;
                    }
                }
            
                /* Get the next subterm */
                pwcSubTerm = s_wcstok(NULL, L" ", (wchar_t **)&pwcTermStrtokPtr);
            }
            
            
            /* Set the search bitmap structure from the search postings list structure */
            if ( psplSrchPostingsList != NULL ) {

                struct srchPosting      *pspSrchPostingsPtr = NULL;
                struct srchPosting      *pspSrchPostingsEnd = NULL;
                unsigned int            uiLastDocumentID = 0;
                
                unsigned char           *pucBitmapPtr = NULL;

                /* We only process the search postings list structure if there is something in it */
                if ( psplSrchPostingsList->uiSrchPostingsLength > 0 ) {
                
                    /* Allocate the search bitmap structure if it has not yet been allocated */
                    if ( *ppsbSrchBitmap == NULL ) {
                        if ( (iError = iSrchBitmapCreate(NULL, psiSrchIndex->uiDocumentCount + 1, false, ppsbSrchBitmap)) != SRCH_NoError ) {
                            iUtlLogError(UTL_LOG_CONTEXT, "Failed to create a new search bitmap, srch error: %d.", iError);
                            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                        }
                    }
    
    
                    /* Dereference the bitmap array */
                    pucBitmapPtr = (*ppsbSrchBitmap)->pucBitmap;
                
                    /* Set the bitmap for these documents  */
                    for ( pspSrchPostingsPtr = psplSrchPostingsList->pspSrchPostings, pspSrchPostingsEnd = psplSrchPostingsList->pspSrchPostings + psplSrchPostingsList->uiSrchPostingsLength; 
                            pspSrchPostingsPtr < pspSrchPostingsEnd; pspSrchPostingsPtr++ ) {
                        
                        /* Set the document in the bitmap if it has not already been set */
                        if ( pspSrchPostingsPtr->uiDocumentID != uiLastDocumentID ) {
                            UTL_BITMAP_SET_BIT_IN_POINTER(pucBitmapPtr, pspSrchPostingsPtr->uiDocumentID);
                            uiLastDocumentID = pspSrchPostingsPtr->uiDocumentID;
                        }
                    }
                }
                
                /* Free the postings list */
                iSrchPostingFreeSrchPostingsList(psplSrchPostingsList);
                psplSrchPostingsList = NULL;
            }
        }

        /* Term does not contain spaces, treat as a term */
        else {

            boolean     bFieldIDBitmapSet = false;

            /* Clear the bitmap */
            if ( pucFieldIDBitmap != NULL ) {
                UTL_BITMAP_CLEAR_POINTER(pucFieldIDBitmap, psiSrchIndex->uiFieldIDMaximum);
            }

            /* Process the term, this returns a pointer to the processed term and sets the bitmap as needed */
            if ( (iError = iSrchFilterProcessTerm(pssSrchSearch, psiSrchIndex, pvLngStemmer, pwcTerm, pucFieldIDBitmap, psiSrchIndex->uiFieldIDMaximum, 
                    &pwcTerm, &bFieldIDBitmapSet)) != SRCH_NoError ) {
                goto bailFromiSrchFilterGetSearchBitmapFromFilter;
            }
    
            /* Skip the term if it was stemmed out of existence */
            if ( bUtlStringsIsWideStringNULL(pwcTerm) == false ) {

                /* Convert the term from wide characters to utf-8, pucTerm is allocated */
                if ( (iError = iLngConvertWideStringToUtf8_d(pwcTerm, 0, &pucTerm)) != LNG_NoError ) {
                    iUtlLogError(UTL_LOG_CONTEXT, "Failed to convert a filter term from wide characters to utf-8, lng error: %d.", iError);
                    iError = SRCH_FilterCharacterSetConvertionFailed;
                    goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                }

                /* Expand the term if it contains a wildcard (or two) */
                if ( s_strpbrk(pucTerm, SRCH_PARSER_WILDCARDS_STRING) != NULL ) {
                
                    /* Expand the term */
                    iError = iSrchTermDictLookupWildCard(psiSrchIndex, pucTerm, (bFieldIDBitmapSet == true) ? pucFieldIDBitmap : NULL, 
                            (bFieldIDBitmapSet == true) ? psiSrchIndex->uiFieldIDMaximum : 0, &pstdiSrchTermDictInfos, &uiSrchTermDictInfosLength);
                    
                    /* Check for non recoverable errors */
                    if ( !((iError == SRCH_NoError) || (iError == SRCH_TermDictTermBadRange) || (iError == SRCH_TermDictTermBadWildCard) ||
                            (iError == SRCH_IndexHasNoTerms) || (iError == SRCH_TermDictTermNotFound) || (iError == SRCH_TermDictTermDoesNotOccur)) ) {
                        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                    }
                    
                    /* Reset the error */
                    iError = SRCH_NoError;


                    /* Loop through all the terms in the term list */
                    for ( pstdiSrchTermDictInfosPtr = pstdiSrchTermDictInfos, uiI = 0; uiI < uiSrchTermDictInfosLength; pstdiSrchTermDictInfosPtr++, uiI++ ) {

                        /* Search to bitmap */
                        if ( (iError = iSrchTermSearchGetSearchBitmapFromTerm(pssSrchSearch, psiSrchIndex, pstdiSrchTermDictInfosPtr->pucTerm, 
                                (bFieldIDBitmapSet == true) ? pucFieldIDBitmap : NULL, ((bFieldIDBitmapSet == true) ? psiSrchIndex->uiFieldIDMaximum : 0), 
                                0, uiStartDocumentID, uiEndDocumentID, ppsbSrchBitmap)) != SRCH_NoError ) {
                            goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                        }
                    }
                }
                else {
                
                    /* Search to bitmap */
                    if ( (iError = iSrchTermSearchGetSearchBitmapFromTerm(pssSrchSearch, psiSrchIndex, pucTerm, (bFieldIDBitmapSet == true) ? pucFieldIDBitmap : NULL, 
                            ((bFieldIDBitmapSet == true) ? psiSrchIndex->uiFieldIDMaximum : 0), 0, uiStartDocumentID, uiEndDocumentID, ppsbSrchBitmap)) != SRCH_NoError )  {
                        goto bailFromiSrchFilterGetSearchBitmapFromFilter;
                    }
                }


                /* Free the term */
                s_free(pucTerm);
            }
        }
    }



    /* Store the bipmap to cache if the cache is enabled */
    if ( uiSrchParserSearchCacheID == SRCH_PARSER_MODIFIER_SEARCH_CACHE_ENABLE_ID ) {
        if ( *ppsbSrchBitmap != NULL ) {
            iSrchCacheSaveSearchBitmap(pssSrchSearch->pvSrchCache, psiSrchIndex, pspfSrchParserFilter->pwcFilter, tFilterFileLastUpdate, *ppsbSrchBitmap);
        }    
    }    



    /* Bail label */
    bailFromiSrchFilterGetSearchBitmapFromFilter:


    /* Free the stemmer */
    iLngStemmerFree(pvLngStemmer);
    pvLngStemmer = NULL;

    /* List based filter */
    if ( pspfSrchParserFilter->uiFilterTypeID == SRCH_PARSER_FILTER_TYPE_LIST_ID ) {

        /* Unmap the terms file */
        iUtlFileMemoryUnMap(pucFilterFileMappingPtr, zFilterFileLength);
        pucFilterFileMappingPtr = NULL;
    
        /* Close the terms file */
        s_fclose(pfFilterFile);
    }
        
    /* Free the term information structure */
    if ( pstdiSrchTermDictInfos != NULL ) {
        for ( pstdiSrchTermDictInfosPtr = pstdiSrchTermDictInfos, uiI = 0; uiI < uiSrchTermDictInfosLength; pstdiSrchTermDictInfosPtr++, uiI++ ) {
            s_free(pstdiSrchTermDictInfosPtr->pucTerm);
        }
        s_free(pstdiSrchTermDictInfos);
    }

    s_free(pucFieldIDBitmap);

    s_free(pucTerm);
    s_free(pwcTerms);


    /* Handle the error */
    if ( iError != SRCH_NoError ) {
        iSrchBitmapFree(*ppsbSrchBitmap);
        *ppsbSrchBitmap = NULL;
    }


    return (iError);

}
Exemple #22
0
/*

    Function:   iPrsParseTextFile()

    Purpose:    Adds term to the index for a given file.

    Parameters: pppPrsParser    structure containing the various parser options 
                                we use to parse the data
                ppfPrsFormat    file profile pointing to the various file options 
                                we use to parse the data
                pucFilePath     file path to be parsed
                pfInputFile     data stream to be parsed
                pfIndexerFile   structured index stream output file
                pfDataLength    return pointer for the data length parsed

    Globals:    none

    Returns:    0 on success, -1 on error

*/
int iPrsParseTextFile
(
    struct prsParser *pppPrsParser,
    struct prsFormat *ppfPrsFormat,
    unsigned char *pucFilePath,
    FILE *pfInputFile,
    FILE *pfIndexerFile,
    float *pfDataLength
)
{

    int             iError = UTL_NoError;
    int             iStatus = 0;
    FILE            *pfLocalFile = NULL;
    unsigned char   *pucLine = NULL;
    unsigned char   *pucNormalizedLine = NULL;
    wchar_t         *pwcLine = NULL;
    unsigned int    uiLineLength = 0;
    unsigned int    ulLineCapacity = 0;
    unsigned int    uiNormalizedLineCapacity = 0;
    wchar_t         *pwcParseLinePtr = NULL;
    off_t           zCurrentOffset = 0;
    off_t           zStartOffset = 0;
    off_t           zEndOffset = 0;
    unsigned int    uiTermPosition = 0;
    unsigned char   pucTrueFilePath[UTL_FILE_PATH_MAX + 1] = {'\0'};

    unsigned int    uiLanguageID = LNG_LANGUAGE_ANY_ID;
    unsigned int    uiFieldID = 0;
    boolean         bIndexLine = false;
    boolean         bParseLine = false;
    boolean         bTermPositions = false;

    boolean         bIndexing = false;
    boolean         bSetStartCharacter = true;
    boolean         bFinishDocument = false;

    float           fLineLength = 0;
    float           fDataLength = 0;


    /* Check the parameters */
    if ( pppPrsParser == NULL ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Null 'pppPrsParser' parameter passed to 'iPrsParseTextFile'."); 
        return (-1);
    }

    if ( ppfPrsFormat == NULL ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Null 'ppfPrsFormat' parameter passed to 'iPrsParseTextFile'."); 
        return (-1);
    }

    if ( pfIndexerFile == NULL ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Null 'pfIndexerFile' parameter passed to 'iPrsParseTextFile'."); 
        return (-1);
    }

    if ( (bUtlStringsIsStringNULL(pucFilePath) == true) && (pfInputFile == NULL) ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Null or empty 'pucFilePath' &'pfInputFile' parameters passed to 'iPrsParseTextFile'."); 
        return (-1);
    }

    if ( (bUtlStringsIsStringNULL(pucFilePath) == false) && (pfInputFile != NULL) ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Invalid 'pucFilePath' &'pfInputFile' parameters passed to 'iPrsParseTextFile'."); 
        return (-1);
    }

    if ( pfDataLength == NULL ) {
        iUtlLogError(UTL_LOG_CONTEXT, "Null 'pfDataLength' parameter passed to 'iPrsParseTextFile'."); 
        return (-1);
    }


    /* Preset the data length return pointer */
    *pfDataLength = 0;
        

    /* Open the file path if it was provided */
    if ( bUtlStringsIsStringNULL(pucFilePath) == false ) {

        /* Get the real file path of this file */
        if ( (iError = iUtlFileGetTruePath(pucFilePath, pucTrueFilePath, UTL_FILE_PATH_MAX + 1)) != UTL_NoError ) {
            iUtlLogError(UTL_LOG_CONTEXT, "Failed to get the true path of the file path: '%s', utl error: %d.", pucFilePath, iError);
            iStatus = -1;
            goto bailFromlPrsParseTextFile;
        }
    
        /* Open the file to index */
        if ( (pfLocalFile = s_fopen(pucTrueFilePath, "r")) == NULL ) {
            /* Send a message 
            ** M    message
            */
            if ( fprintf(pfIndexerFile, "M File: '%s' could not be opened.\n", pucTrueFilePath) < 0 ) {
                iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer");
            }
            iStatus = -1;
            goto bailFromlPrsParseTextFile;
        }

        /* Send a message to the indexer
        ** M    (Message to be displayed by the indexer)
        */
        if ( pppPrsParser->bSuppressMessages == false ) {
            if ( fprintf(pfIndexerFile, "M Parsing file: '%s'.\n", pucTrueFilePath) < 0 ) {
                iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer");
            }
        }
    }
    /* Otherwise read from the input file */ 
    else if ( pfInputFile != NULL ) {
        pfLocalFile = pfInputFile;
    }
    /* Otherwise croak */
    else {
        iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to find data either from a file path or an input file stream");
    }


    
    /* Initialize for the first document */
    zCurrentOffset = 0;
    zStartOffset = 0;
    zEndOffset = 0;
    uiTermPosition = 1;

    bIndexing = false;
    bSetStartCharacter = true;
    bFinishDocument = false;


    /* Loop around reading every line in the file */
    while ( true ) {
    
        boolean         bEoF = false;
        unsigned char   *pucLineEndPtr = NULL;


        /* Reset the line to an empty string, note that pucLine is dynamically
        ** allocated so we make sure that it is allocated before doing so 
        */
        if ( pucLine != NULL ) {
            pucLine[0] = '\0';
        }

        /* Reset the line length */
        uiLineLength = 0;

        /* This ugly little loop reads stuff from the file we are indexing making sure that
        ** it reads an entire actual line (ie not limited by the fact that fgets() can only 
        ** read fixed length buffers) and erases any end of line characters
        */
        do {

            /* Allocate/reallocate lines if needed */
            if ( (pucLine == NULL) || (ulLineCapacity == 0) || ((uiLineLength + BUFSIZ) > ulLineCapacity) ) {

                unsigned char   *pucLinePtr = NULL;


                /* Extend the line */
                if ( (pucLinePtr = (unsigned char *)s_realloc(pucLine, (size_t)(sizeof(unsigned char) * (ulLineCapacity + BUFSIZ)))) == NULL ) {
                    iStatus = -1;
                    goto bailFromlPrsParseTextFile;
                }

                /* Hand over the pointer */
                pucLine = pucLinePtr;

                /* Clear the new allocation */
                s_memset(pucLine + ulLineCapacity, 0, BUFSIZ);
                
                /* Set the line capacity */
                ulLineCapacity += BUFSIZ;

                
                /* Extend the normalized line if normalization is supported */
                if ( pppPrsParser->pvLngUnicodeNormalizer != NULL ) {
                
                    unsigned char    *pucNormalizedLinePtr = NULL;
                    
                    /* Set the normalized line capacity */
                    uiNormalizedLineCapacity = ulLineCapacity * LNG_UNICODE_NORMALIZATION_EXPANSION_MULTIPLIER_MAX;

                    /* Extend the normalized line */
                    if ( (pucNormalizedLinePtr = (unsigned char *)s_realloc(pucNormalizedLine, (size_t)(sizeof(unsigned char) * uiNormalizedLineCapacity))) == NULL ) {
                        iStatus = -1;
                        goto bailFromlPrsParseTextFile;
                    }
    
                    /* Hand over the pointer */
                    pucNormalizedLine = pucNormalizedLinePtr;
                }

                
                /* Extend the wide character line */
                {
                    wchar_t     *pwcLinePtr = NULL;
                
                    /* Extend the wide character line */
                    if ( (pwcLinePtr = (wchar_t *)s_realloc(pwcLine, (size_t)(sizeof(wchar_t) * ulLineCapacity))) == NULL ) {
                        iStatus = -1;
                        goto bailFromlPrsParseTextFile;
                    }
    
                    /* Hand over the pointer */
                    pwcLine = pwcLinePtr;
                }
            }


            /* Read the next line chunk, appending to the current line and setting the end of file flag */
            bEoF = (s_fgets(pucLine + uiLineLength, ulLineCapacity - uiLineLength, pfLocalFile) == NULL) ? true : false;

            /* Get the new line length here for optimization */
            uiLineLength = s_strlen(pucLine);

            /* Erase the trailing new line - be platform sensitive, handle PC first, then Unix and Mac  */
            if ( (uiLineLength >= 2) && (pucLine[uiLineLength - 2] == '\r') ) {
                pucLineEndPtr = pucLine + (uiLineLength - 2);
                uiLineLength -= 2;
            }
            else if ( (uiLineLength >= 1) && ((pucLine[uiLineLength - 1] == '\n') || (pucLine[uiLineLength - 1] == '\r')) ) {
                pucLineEndPtr = pucLine + (uiLineLength - 1);
                uiLineLength -= 1;
            }
            else if ( (uiLineLength >= 1) && (bEoF == true) ) {
                pucLineEndPtr = pucLine + uiLineLength;
            }
            else {
                pucLineEndPtr = NULL;
            }

            if ( pucLineEndPtr != NULL ) {
                *pucLineEndPtr = '\0';
            }

        } while ( (pucLineEndPtr == NULL) && (bEoF == false) );


        /* Increment the line length */
        fLineLength++;

        /* Increment the data length */
        fDataLength += uiLineLength;
        

        /* Set the current character */
        zCurrentOffset += uiLineLength;


        /* Check to see if we have reached the end of the file, if we have we finish the document and bail */
        if ( (bEoF == true) && (pucLineEndPtr == NULL) ) {
            
            /* Finish the document if we are indexing */
            if ( bIndexing == true ) {
                
                /* Finish the document */
                if ( iPrsFinishDocument(pppPrsParser, ppfPrsFormat, pfIndexerFile, pucTrueFilePath, zStartOffset, zCurrentOffset - 1, uiTermPosition - 1) != 0 ) {
                    iStatus = -1;
                    goto bailFromlPrsParseTextFile;
                }
            }
            
            break;
        }


        /* Reset the wide character line */
        if ( pwcLine != NULL ) {
            pwcLine[0] = L'\0';
        }
        
        /* Set the parse line pointer */
        pwcParseLinePtr = pwcLine;

        /* Convert the line from its native character set to wide characters */
        if ( bUtlStringsIsStringNULL(pucLine) == false ) {
            
            /* Set the line pointer */
            unsigned char   *pucLinePtr = pucLine;
            
            /* Use a separate variable for the line length */
            unsigned int    uiLineAllocatedByteLength = ulLineCapacity * sizeof(wchar_t);


            /* Clean the unicode if requested */
            if ( pppPrsParser->bCleanUnicode == true ) {
                
                /* Clean the unicode */
                if ( (iError = iLngUnicodeCleanUtf8String(pucLinePtr, PRS_UNICODE_REPLACEMENT_CHARACTER)) != LNG_NoError ) {
                    iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to clean the string, lng error: %d, string: '%s'", iError, pucLinePtr);
                }
            }


            /* Normalize the line if the unicode normalizer is enabled */
            if ( pppPrsParser->pvLngUnicodeNormalizer != NULL ) {
                
                /* Normalize the line */
                if ( (iError = iLngUnicodeNormalizeString(pppPrsParser->pvLngUnicodeNormalizer, pucLinePtr, uiLineLength, &pucNormalizedLine, &uiNormalizedLineCapacity)) != LNG_NoError ) {
                    iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to normalize the string, lng error: %d, string: '%s'", iError, pucLinePtr);
                }
                
                /* Set the line pointer */
                pucLinePtr = pucNormalizedLine;
                uiLineLength = s_strlen(pucLinePtr);
            }


            /* Convert the line from utf-8 to wide character, note the conversion error handling */
            if ( (iError = iLngConverterConvertString(pppPrsParser->pvLngConverter, ((pppPrsParser->bSkipUnicodeErrors == true) ? LNG_CONVERTER_SKIP_ON_ERROR : LNG_CONVERTER_RETURN_ON_ERROR), 
                    pucLinePtr, uiLineLength, (unsigned char **)&pwcLine, &uiLineAllocatedByteLength)) != LNG_NoError ) {
                iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to convert the string from utf-8 set to wide characters, lng error: %d, string: '%s'", iError, pucLinePtr);
            }

            /* Set the parse line pointer */
            pwcParseLinePtr = pwcLine;
        }


        /* Check for a document start if a start function was supplied */
        if ( (ppfPrsFormat->bPrsDocumentStartFunction != NULL) && (ppfPrsFormat->bPrsDocumentStartFunction(pwcParseLinePtr) == true) ) {
            
            /* We need to finish the current document if we are currently indexing */
            if ( bIndexing == true ) {

                /* Set the end character if it has not been set, this occurs if we have 
                ** both a start function and an end function, and we detect a new document
                ** start without having first detected a document end
                */
                if ( zEndOffset <= zStartOffset ) {
                    zEndOffset = (zCurrentOffset - uiLineLength) - 1;
                }
                
                /* Finish the document, we do this here because we dont want to process the current line, it belongs to the new document */
                if ( iPrsFinishDocument(pppPrsParser, ppfPrsFormat, pfIndexerFile, pucTrueFilePath, zStartOffset, zEndOffset, uiTermPosition - 1) != 0 ) {
                    iStatus = -1;
                    goto bailFromlPrsParseTextFile;
                }

                /* Check to see if we have reached the document count limit and bail if we have */
                if ( (pppPrsParser->uiDocumentCountMax > 0) && (pppPrsParser->uiDocumentCount >= pppPrsParser->uiDocumentCountMax) ) {
                    break;
                }

                /* Initialize for the next document */
                uiTermPosition = 1;
            }
            else {
                /* Turn on indexing */
                bIndexing = true;
            }
            
            /* Set the start character */
            zStartOffset = zCurrentOffset - uiLineLength;
            bSetStartCharacter = false;
        }

        /* We are always indexing if there is no start function, because if we
        ** reach the end of a document, we are automatically indexing the next one
        */
        else if ( ppfPrsFormat->bPrsDocumentStartFunction == NULL ) {
            
            /* Make sure indexing is turned on */
            bIndexing = true;
            
            /* Set the start character if needed */
            if ( bSetStartCharacter == true ) {
                zStartOffset = zCurrentOffset - uiLineLength;
                bSetStartCharacter = false;
            }
        }

        
        /* Check for a document end if an end function was supplied */ 
        if ( (ppfPrsFormat->bPrsDocumentEndFunction != NULL) && (ppfPrsFormat->bPrsDocumentEndFunction(pwcParseLinePtr) == true) && (fLineLength > 1) ) {
            
            /* Finish the document if we run into a document end */ 
            if ( bIndexing == true ) {
            
                /* Request that we set a new start character, finish the document, and turn off indexing */
                bSetStartCharacter = true;
                bFinishDocument = true;
                bIndexing = false;
                
                /* Set the end character */
                zEndOffset = zCurrentOffset - 1;
            }
        }
        
        /* No end function */
        else if ( ppfPrsFormat->bPrsDocumentEndFunction == NULL ) {
            /* Set the end character */
            zEndOffset = zCurrentOffset - 1;
        }



        /* Just loop to read the next line if we are not indexing and we dont need to finish a document */
        if ( (bIndexing == false) && (bFinishDocument == false) ) {
            continue;
        }



        /* Clear the parameters */
        uiLanguageID = LNG_LANGUAGE_ANY_ID;
        uiFieldID = 0;
        bIndexLine = true;
        bParseLine = true;
        bTermPositions = true;

        /* Process the document line */
        if ( ppfPrsFormat->vPrsDocumentLineFunction != NULL ) {
            ppfPrsFormat->vPrsDocumentLineFunction(pwcParseLinePtr, &uiLanguageID, &uiFieldID, &bIndexLine, &bParseLine, &bTermPositions);
        }


        /* Index the contents of the line */
        if ( bIndexLine == true ) {

            /* Parse the line */
            if ( bParseLine == true ) {

                /* Parse the text line */
                if ( iPrsParseTextLine(pppPrsParser, ppfPrsFormat, pfIndexerFile, pwcParseLinePtr, pwcParseLinePtr + s_wcslen(pwcParseLinePtr), 
                        uiLanguageID, uiFieldID, (bTermPositions == true) ? &uiTermPosition : NULL) != 0 ) {
                    if ( fprintf(pfIndexerFile, "M Failed to add the document terms.\n") < 0 ) {
                        iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer");
                    }
                }
            }
            /* Get a term from the line and add */
            else {

                wchar_t     *pwcLinePtr = NULL;


                /* Find the start of the term */
                for ( pwcLinePtr = pwcParseLinePtr; *pwcLinePtr != L'\0'; pwcLinePtr++ ) { 
                    if ( iswalnum(*pwcLinePtr) != 0 ) {
                        break;
                    }
                }


                /* Is the term long enough to add? */
                if ( s_wcslen(pwcLinePtr) >= pppPrsParser->uiTermLengthMinimum ) {
    
                    /* Send the language line if the language is known */
                    if ( uiLanguageID != LNG_LANGUAGE_ANY_ID ) {

                        unsigned char   pucLanguageCode[LNG_LANGUAGE_CODE_LENGTH + 1] = {'\0'};
                        
                        if ( iLngGetLanguageCodeFromID(uiLanguageID, pucLanguageCode, LNG_LANGUAGE_CODE_LENGTH + 1) == LNG_NoError ) {
                
                            /* Send the language
                            ** L language{A}
                            */
                            if ( fprintf(pfIndexerFile, "L %s\n", pucLanguageCode) < 0 ) {
                                iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a language line to the indexer");
                            }
                        }
                    }

                    /* Send the term to the indexer */
                    if ( iPrsSendTermToIndexer(pppPrsParser, ppfPrsFormat, pfIndexerFile, pwcLinePtr, pwcLinePtr + s_wcslen(pwcLinePtr), 
                            uiFieldID, (bTermPositions == true) ? uiTermPosition : 0) != 0 ) {
                        if ( fprintf(pfIndexerFile, "M Failed to add a document term.\n") < 0 ) {
                            iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer");
                        }
                    }
                    
                    /* Increment the term position */
                    if ( bTermPositions == true ) {
                        uiTermPosition++;
                    }
                }
            }
        }

    
        /* Finish the document if we were requested to do so */    
        if ( bFinishDocument == true ) {

            /* Finish the current document */
            if ( iPrsFinishDocument(pppPrsParser, ppfPrsFormat, pfIndexerFile, pucTrueFilePath, zStartOffset, zEndOffset, uiTermPosition - 1) != 0 ) {
                if ( fprintf(pfIndexerFile, "M Failed to finish adding a document.\n") < 0 ) {
                    iUtlLogPanic(UTL_LOG_CONTEXT, "Failed to send a message line to the indexer");
                }
            }
    
            /* Check to see if we have reached the document count limit */
            if ( (pppPrsParser->uiDocumentCountMax > 0) && (pppPrsParser->uiDocumentCount >= pppPrsParser->uiDocumentCountMax) ) {
                break;
            }
            
            /* Initialize for the next document */
            uiTermPosition = 1;
    
            /* Turn off the flag requesting that we finish the document */
            bFinishDocument = false;
        }
        

    }    /* while (true) */



    /* Bail label */
    bailFromlPrsParseTextFile:
    

    /* Close the file descriptor if we opened it ourselves */
    if ( bUtlStringsIsStringNULL(pucFilePath) == false ) {
        s_fclose(pfLocalFile);
    }

    /* Free the line pointers */
    s_free(pucLine);
    s_free(pucNormalizedLine);
    s_free(pwcLine);

    
    /* Increment the data length return pointer */
    *pfDataLength += fDataLength;


    return (iStatus);

}
/**************************************************************************
 * Buddy List subsystem signal callbacks
 **************************************************************************/				
static void
buddy_status_changed_cb(PurpleBuddy *buddy, PurpleStatus *old_status, PurpleStatus *status)
{
	char *status_name, *old_status_name, *status_msg;
	char* buddy_nick, *buddy_name, *icon_path, *growl_msg;
	PurpleBuddyIcon* icon;
	int len, hack_ms;
	PurpleAccount* account;

	DEBUG_MSG("buddy_status_changed_cb\n");
	
	g_return_if_fail( buddy != NULL );
	account = purple_buddy_get_account(buddy);
	g_return_if_fail( is_allowed(account) );	

	status_name 	= (char *)purple_status_get_name(status);
	old_status_name = (char *)purple_status_get_name(old_status);
	buddy_nick = (char*)purple_buddy_get_alias(buddy);
	buddy_name = (char*)purple_buddy_get_name(buddy);
	icon = purple_buddy_get_icon(buddy);
	icon_path = (char*)purple_buddy_icon_get_full_path(icon);

	status_msg = custom_get_buddy_status_text(buddy);
	if( status_msg == NULL )
		status_msg = "";
	special_entries(status_msg);
	strip_tags(status_msg);
		
	//hack to hide spam when signing on to account
	hack_ms = purple_prefs_get_int("/plugins/core/pidgin-gntp/hack_ms");
	
	GList *node = buddy_status_is_new(buddy, status_msg);
	
	if( GetTickCount() - start_tick_im < hack_ms) return;
	
	if( node != NULL )
	{
		DEBUG_MSG("status node received\n");
		struct buddy_status* node_status = node->data;
		
		free(node_status->status);
		char* the_status = malloc( s_strlen(status_msg)+1 );
		strcpy(the_status, status_msg);
		node_status->status = the_status;
		
		if(status_msg[0] == 0)
		{	
			len = s_strlen(buddy_nick) + s_strlen(buddy_name) + 25;
			growl_msg = malloc( len );
			g_snprintf(growl_msg, len, "status message removed\n%s\n%s",buddy_nick, buddy_name );							
			
			gntp_notify("buddy-change-msg", icon_path, "Status Message Changed", growl_msg, NULL);
			free(growl_msg);
		}
		else
		{
			len = s_strlen(buddy_nick) + s_strlen(buddy_name) + s_strlen(status_msg)+5;
			growl_msg = malloc( len );
			g_snprintf(growl_msg, len, "\"%s\"\n%s\n%s",
												status_msg, buddy_nick, buddy_name );
												
			gntp_notify("buddy-change-msg", icon_path, "Status Changed", growl_msg, NULL);
			free(growl_msg);
		}
	}
	
	if( strcmp(status_name, old_status_name) == 0)
		return;
		
	len = s_strlen(buddy_nick) + s_strlen(buddy_name) + s_strlen(status_name) + 3;
		
	growl_msg = malloc( len );
	
	g_snprintf(growl_msg, len, "%s\n%s\n%s",
										status_name, buddy_nick, buddy_name );
										
	gntp_notify("buddy-change-status", icon_path, "Status Changed", growl_msg, NULL);
	
	free(growl_msg);
}