⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmrtf.c

📁 Linux下的多协议即时通讯程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
							return status;					} else {               /* parsing a hex encoded character */						if (ctx->ris != NMRTF_STATE_HEX)							return NMRTF_ASSERTION;						hex_byte = hex_byte << 4;						if (isdigit(ch))							hex_byte += (char) ch - '0';						else {							if (islower(ch)) {								if (ch < 'a' || ch > 'f')									return NMRTF_INVALID_HEX;								hex_byte += (char) ch - 'a' + 10;							} else {								if (ch < 'A' || ch > 'F')									return NMRTF_INVALID_HEX;								hex_byte += (char) ch - 'A' + 10;							}						}						hex_count--;						if (hex_count == 0) {							if ((status = rtf_dispatch_char(ctx, hex_byte)) != NMRTF_OK)								return status;							hex_count = 2;							hex_byte = 0;							ctx->ris = NMRTF_STATE_NORMAL;						}					}					break;            }        }    }    if (ctx->depth < 0)        return NMRTF_STACK_OVERFLOW;    if (ctx->depth > 0)        return NMRTF_UNMATCHED_BRACE;    return NMRTF_OK;}/* * Push the current state onto stack */static intrtf_push_state(NMRtfContext *ctx){    NMRtfStateSave *save = g_new0(NMRtfStateSave, 1);    save->chp = ctx->chp;    save->rds = ctx->rds;    save->ris = ctx->ris;	ctx->saved = g_slist_prepend(ctx->saved, save);    ctx->ris = NMRTF_STATE_NORMAL;    (ctx->depth)++;    return NMRTF_OK;}/* * Restore the state at the top of the stack */static intrtf_pop_state(NMRtfContext *ctx){    NMRtfStateSave *save_old;	GSList *link_old;    if (ctx->saved == NULL)        return NMRTF_STACK_UNDERFLOW;	save_old = ctx->saved->data;    ctx->chp = save_old->chp;    ctx->rds = save_old->rds;    ctx->ris = save_old->ris;    (ctx->depth)--;    g_free(save_old);	link_old = ctx->saved;	ctx->saved = g_slist_remove_link(ctx->saved, link_old);	g_slist_free_1(link_old);    return NMRTF_OK;}/* * Step 2: * Get a control word (and its associated value) and * dispatch the control. */static intrtf_parse_keyword(NMRtfContext *ctx){	int status = NMRTF_OK;    guchar ch;    gboolean param_set = FALSE;    gboolean is_neg = FALSE;    int param = 0;    char keyword[30];    char parameter[20];	int i;    keyword[0] = '\0';    parameter[0] = '\0';    if ((status = rtf_get_char(ctx, &ch)) != NMRTF_OK)        return status;    if (!isalpha(ch)) {		/* a control symbol; no delimiter. */        keyword[0] = (char) ch;        keyword[1] = '\0';        return rtf_dispatch_control(ctx, keyword, 0, param_set);    }	/* parse keyword */	for (i = 0; isalpha(ch) && (i < sizeof(keyword) - 1); rtf_get_char(ctx, &ch)) {		keyword[i] = (char) ch;		i++;	}	keyword[i] = '\0';	/* check for '-' indicated a negative parameter value  */    if (ch == '-') {        is_neg = TRUE;        if ((status = rtf_get_char(ctx, &ch)) != NMRTF_OK)            return status;    }	/* check for numerical param */    if (isdigit(ch)) {        param_set = TRUE;		for (i = 0; isdigit(ch) && (i < sizeof(parameter) - 1); rtf_get_char(ctx, &ch)) {			parameter[i] = (char) ch;			i++;		}		parameter[i] = '\0';        ctx->param = param = atoi(parameter);        if (is_neg)            ctx->param = param = -param;    }	/* space after control is optional, put character back if it is not a space */    if (ch != ' ')        rtf_unget_char(ctx, ch);    return rtf_dispatch_control(ctx, keyword, param, param_set);}/* * Route the character to the appropriate destination */static intrtf_dispatch_char(NMRtfContext *ctx, guchar ch){    if (ctx->ris == NMRTF_STATE_BIN && --(ctx->bytes_to_skip) <= 0)        ctx->ris = NMRTF_STATE_NORMAL;    switch (ctx->rds) {		case NMRTF_STATE_SKIP:			return NMRTF_OK;		case NMRTF_STATE_NORMAL:			return rtf_print_char(ctx, ch);        case NMRTF_STATE_FONTTABLE:            if (ch == ';')  {				rtf_add_font_entry(ctx, ctx->chp.font_idx,								   ctx->ansi->str, ctx->chp.font_charset);				g_string_truncate(ctx->ansi, 0);            }            else {                return rtf_print_char(ctx, ch);            }            return NMRTF_OK;		default:			return NMRTF_OK;    }}/* Handle a unicode character */static intrtf_dispatch_unicode_char(NMRtfContext *ctx, gunichar ch){    switch (ctx->rds) {		case NMRTF_STATE_SKIP:			return NMRTF_OK;		case NMRTF_STATE_NORMAL:        case NMRTF_STATE_FONTTABLE:			return rtf_print_unicode_char(ctx, ch);		default:			return NMRTF_OK;    }}/* * Output a character */static intrtf_print_char(NMRtfContext *ctx, guchar ch){	ctx->ansi = g_string_append_c(ctx->ansi, ch);    return NMRTF_OK;}/* * Output a unicode character */static intrtf_print_unicode_char(NMRtfContext *ctx, gunichar ch){	char buf[7];	int num;	/* convert and flush the ansi buffer to the utf8 buffer */	rtf_flush_data(ctx);	/* convert the unicode character to utf8 and add directly to the output buffer */	num = g_unichar_to_utf8((gunichar) ch, buf);	buf[num] = 0;	purple_debug_info("novell", "converted unichar 0x%X to utf8 char %s\n", ch, buf);	ctx->output = g_string_append(ctx->output, buf);	return NMRTF_OK;}/* * Flush the output text */static intrtf_flush_data(NMRtfContext *ctx){    int status = NMRTF_OK;	char *conv_data = NULL;	const char *enc = NULL;	GError *gerror = NULL;    if (ctx->rds == NMRTF_STATE_NORMAL && ctx->ansi->len > 0) {		enc = get_current_encoding(ctx);		conv_data = g_convert(ctx->ansi->str, ctx->ansi->len, "UTF-8", enc,							  NULL, NULL, &gerror);		if (conv_data) {			ctx->output = g_string_append(ctx->output, conv_data);			g_free(conv_data);			ctx->ansi = g_string_truncate(ctx->ansi, 0);		} else {			status = NMRTF_CONVERT_ERROR;			purple_debug_info("novell", "failed to convert data! error code = %d msg = %s\n",							gerror->code, gerror->message);			g_free(gerror);		}	}    return status;}/* * Handle a property change */static intrtf_apply_property(NMRtfContext *ctx, NMRtfProperty prop, int val){    if (ctx->rds == NMRTF_STATE_SKIP)  /* If we're skipping text, */        return NMRTF_OK;          /* don't do anything. */	/* Need to flush any temporary data before a property change*/	rtf_flush_data(ctx);    switch (prop) {		case NMRTF_PROP_FONT_IDX:			ctx->chp.font_idx = val;			break;		case NMRTF_PROP_FONT_CHARSET:			ctx->chp.font_charset = val;			break;		default:			return NMRTF_BAD_TABLE;    }    return NMRTF_OK;}/* * Step 3. * Search the table for keyword and evaluate it appropriately. * * Inputs: * keyword:   The RTF control to evaluate. * param:     The parameter of the RTF control. * param_set: TRUE if the control had a parameter; (that is, if param is valid) *            FALSE if it did not. */static intrtf_dispatch_control(NMRtfContext *ctx, char *keyword, int param, gboolean param_set){    int idx;    for (idx = 0; idx < table_size; idx++) {        if (strcmp(keyword, rtf_symbols[idx].keyword) == 0)            break;	}    if (idx == table_size)  {        if (ctx->skip_unknown)            ctx->rds = NMRTF_STATE_SKIP;        ctx->skip_unknown = FALSE;        return NMRTF_OK;    }    /* found it! use kwd_type and action to determine what to do with it. */    ctx->skip_unknown = FALSE;    switch (rtf_symbols[idx].kwd_type) {		case NMRTF_KWD_PROP:			if (rtf_symbols[idx].pass_default || !param_set)				param = rtf_symbols[idx].default_val;			return rtf_apply_property(ctx, rtf_symbols[idx].action, param);		case NMRTF_KWD_CHAR:			return rtf_dispatch_char(ctx, rtf_symbols[idx].action);		case NMRTF_KWD_DEST:			return rtf_change_destination(ctx, rtf_symbols[idx].action);		case NMRTF_KWD_SPEC:			return rtf_dispatch_special(ctx, rtf_symbols[idx].action);		default:			return NMRTF_BAD_TABLE;    }    return NMRTF_BAD_TABLE;}/* * Change to the destination specified. */static intrtf_change_destination(NMRtfContext *ctx, NMRtfDestinationType type){	/* if we're skipping text, don't do anything */    if (ctx->rds == NMRTF_STATE_SKIP)        return NMRTF_OK;    switch (type) {		case NMRTF_DEST_FONTTABLE:            ctx->rds = NMRTF_STATE_FONTTABLE;			g_string_truncate(ctx->ansi, 0);            break;		default:			ctx->rds = NMRTF_STATE_SKIP;       /* when in doubt, skip it... */			break;    }    return NMRTF_OK;}/* * Dispatch an RTF control that needs special processing */static intrtf_dispatch_special(NMRtfContext *ctx, NMRtfSpecialKwd type){	int status = NMRTF_OK;	guchar ch;    if (ctx->rds == NMRTF_STATE_SKIP && type != NMRTF_SPECIAL_BIN)  /* if we're skipping, and it's not */        return NMRTF_OK;                        /* the \bin keyword, ignore it. */    switch (type) {		case NMRTF_SPECIAL_BIN:			ctx->ris = NMRTF_STATE_BIN;			ctx->bytes_to_skip = ctx->param;			break;		case NMRTF_SPECIAL_SKIP:			ctx->skip_unknown = TRUE;			break;		case NMRTF_SPECIAL_HEX:			ctx->ris = NMRTF_STATE_HEX;			break;		case NMRTF_SPECIAL_UNICODE:			purple_debug_info("novell", "parsing unichar\n");			status = rtf_dispatch_unicode_char(ctx, ctx->param); 			/* Skip next char */			if (status == NMRTF_OK)				status = rtf_get_char(ctx, &ch);			break;		default:			status = NMRTF_BAD_TABLE;			break;    }    return status;}/* * Get the next character from the input stream */static intrtf_get_char(NMRtfContext *ctx, guchar *ch){    if (ctx->nextch >= 0) {        *ch = ctx->nextch;        ctx->nextch = -1;    }    else {		*ch = *(ctx->input);		ctx->input++;    }	if (*ch)		return NMRTF_OK;	else		return NMRTF_EOF;}/* * Move a character back into the input stream */static intrtf_unget_char(NMRtfContext *ctx, guchar ch){    ctx->nextch = ch;    return NMRTF_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -