Exemplo n.º 1
0
/*
 * \internal Analizuje przychodzący pakiet odpowiedzi i zapisuje wynik
 * w strukturze \c gg_event.
 *
 * \param sess Struktura sesji
 * \param e Struktura zdarzenia
 * \param packet Pakiet odpowiedzi
 * \param length Długość pakietu odpowiedzi
 *
 * \return 0 jeśli się powiodło, -1 w przypadku błędu
 */
int gg_pubdir50_handle_reply_sess(struct gg_session *sess, struct gg_event *e, const char *packet, int length)
{
	const char *end = packet + length, *p;
	struct gg_pubdir50_reply *r = (struct gg_pubdir50_reply*) packet;
	gg_pubdir50_t res;
	int num = 0;
	
	gg_debug(GG_DEBUG_FUNCTION, "** gg_pubdir50_handle_reply_sess(%p, %p, %p, %d);\n", sess, e, packet, length);

	if (!sess || !e || !packet) {
		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() invalid arguments\n");
		errno = EFAULT;
		return -1;
	}

	if (length < 5) {
		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() packet too short\n");
		errno = EINVAL;
		return -1;
	}

	if (!(res = gg_pubdir50_new(r->type))) {
		gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() unable to allocate reply\n");
		return -1;
	}

	e->event.pubdir50 = res;

	res->seq = gg_fix32(r->seq);

	switch (res->type) {
		case GG_PUBDIR50_READ:
			e->type = GG_EVENT_PUBDIR50_READ;
			break;

		case GG_PUBDIR50_WRITE:
			e->type = GG_EVENT_PUBDIR50_WRITE;
			break;

		default:
			e->type = GG_EVENT_PUBDIR50_SEARCH_REPLY;
			break;
	}

	/* brak wyników? */
	if (length == 5)
		return 0;

	/* pomiń początek odpowiedzi */
	p = packet + 5;

	while (p < end) {
		const char *field, *value;

		field = p;

		/* sprawdź, czy nie mamy podziału na kolejne pole */
		if (!*field) {
			num++;
			field++;
		}

		value = NULL;
		
		for (p = field; p < end; p++) {
			/* jeśli mamy koniec tekstu... */
			if (!*p) {
				/* ...i jeszcze nie mieliśmy wartości pola to
				 * wiemy, że po tym zerze jest wartość... */
				if (!value)
					value = p + 1;
				else
					/* ...w przeciwym wypadku koniec
					 * wartości i możemy wychodzić
					 * grzecznie z pętli */
					break;
			}
		}
		
		/* sprawdźmy, czy pole nie wychodzi poza pakiet, żeby nie
		 * mieć segfaultów, jeśli serwer przestanie zakańczać pakietów
		 * przez \0 */

		if (p == end) {
			gg_debug(GG_DEBUG_MISC, "// gg_pubdir50_handle_reply() premature end of packet\n");
			goto failure;
		}

		p++;

		/* jeśli dostaliśmy namier na następne wyniki, to znaczy że
		 * mamy koniec wyników i nie jest to kolejna osoba. */
		if (!strcasecmp(field, "nextstart")) {
			res->next = atoi(value);
			num--;
		} else {
			if (sess->encoding == GG_ENCODING_CP1250) {
				if (gg_pubdir50_add_n(res, num, field, value) == -1)
					goto failure;
			} else {
				char *tmp;

				tmp = gg_cp_to_utf8(value);

				if (tmp == NULL)
					goto failure;

				if (gg_pubdir50_add_n(res, num, field, tmp) == -1) {
					free(tmp);
					goto failure;
				}

				free(tmp);
			}
		}
	}	

	res->count = num + 1;
	
	return 0;

failure:
	gg_pubdir50_free(res);
	return -1;
}
Exemplo n.º 2
0
HtmlToGG::HtmlToGG(const char* str) : format(NULL)
{			
	vector<gg_msg_color> formats;

	gg_msg_richtext header;
	gg_msg_color def;

	header.flag = 0x02;
	header.length = 6;

	def.format.position = 0;
	def.format.font = GG_FONT_COLOR;
	def.color.red = 0;
	def.color.green = 0;
	def.color.blue = 0;

	//cpy(&formats,(char*)&header,sizeof(gg_msg_richtext));
	formats.push_back(def);

	char* utf8 = gg_cp_to_utf8(str);
	string utf(utf8);
	free(utf8);

	// dodajemy span do html-a
	string temp = "<span style=\"color:#000000; font-family:'MS Shell Dlg 2'; font-size:9pt; \">";
	temp += filter(rnToBr(utf));
	temp += "</span>";
	temp += '\0';
	html.assign(temp);
	
	// obrobka tagow <b> <u> <i>
	bool bold=false,italic=false,underline=false;
	unsigned int pos; // pozycja razem z formatowaniem
	unsigned int text_pos = 1; // pozycja w tekscie (po usunieciu formatowania)
	unsigned int str_len=strlen(str);
	bool*tag = new bool[str_len]; // tutaj -1 jesli czysty tekst, 1 jesli znacznik
	for(pos=0;pos<str_len;pos++) tag[pos]=false;
	if(str_len>2)
	{
		pos=2;
		text_pos = 2;
		while(pos<str_len)
		{
			if(bold||italic||underline) // moga wystapic dopiero przy pierwszym przejsciu petli
			{
				if(str[pos]=='>' && (str[pos-1]=='b'||str[pos-1]=='B') && str[pos-2]=='/' && str[pos-3]=='<') // </b> </B>
				{
					def.format.font &= ~GG_FONT_BOLD;
					text_pos -= 4;
					def.format.position = text_pos+1;
					formats.push_back(def);
					bold=false;
					tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true; tag[pos-3]=true;// oznaczamy ze 4 poprzednie znaki sa znacznikiem a nie plain text-em
				}
				else if(str[pos]=='>' && (str[pos-1]=='i'||str[pos-1]=='I') && str[pos-2]=='/' && str[pos-3]=='<') // </i> </I>
				{
					def.format.font &= ~GG_FONT_ITALIC;
					text_pos -= 4;
					def.format.position = text_pos+1;
					formats.push_back(def);
					italic=false;
					tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true; tag[pos-3]=true;
				}
				else if(str[pos]=='>' && (str[pos-1]=='u'||str[pos-1]=='U') && str[pos-2]=='/' && str[pos-3]=='<') // </u> </U>
				{
					def.format.font &= ~GG_FONT_UNDERLINE;
					text_pos -= 4;
					def.format.position = text_pos+1;
					formats.push_back(def);
					underline=false;
					tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true; tag[pos-3]=true;
				}
			}
			if(str[pos]=='>' && (str[pos-1]=='b'||str[pos-1]=='B') && str[pos-2]=='<') // <b> <B>
			{
				def.format.font |= GG_FONT_BOLD;
				text_pos -= 3;
				def.format.position = text_pos+1;
				formats.push_back(def);
				bold=true;
				tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true; // oznaczamy ze 3 poprzednie znaki sa znacznikiem a nie plain text-em

			}
			else if(str[pos]=='>' && (str[pos-1]=='i'||str[pos-1]=='I') && str[pos-2]=='<') // <i> <I>
			{
				def.format.font |= GG_FONT_ITALIC;
				text_pos -= 3;
				def.format.position = text_pos+1;
				formats.push_back(def);
				italic=true;
				tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true;
			}
			else if(str[pos]=='>' && (str[pos-1]=='u'||str[pos-1]=='U') && str[pos-2]=='<') // <u> <U>
			{
				def.format.font |= GG_FONT_UNDERLINE;
				text_pos -= 3;
				def.format.position = text_pos+1;
				formats.push_back(def);
				underline=true;
				tag[pos]=true; tag[pos-1]=true; tag[pos-2]=true;
			}
			pos++; 
			text_pos++;
		}
	}

	// tworzenie plain-textu
	for(pos=0;pos<str_len;pos++)
	{
		if(!tag[pos])
			plain+=str[pos];
	}
	plain += '\0';
	delete [] tag; 

	//usuwanie duplikatow (w sytuacji gdy jeden tag sie konczy a zaczyna nastepny)
	vector<gg_msg_color> cleaned;
	for(pos=0;pos<formats.size()-1;pos++)
		if(formats[pos].format.position!=formats[pos+1].format.position)
			cleaned.push_back(formats[pos]);
	if(formats[pos].format.position!=text_pos) // po co dodawac informacje o konczacym sie tagu skoro za nim i tak nic nie ma..
		cleaned.push_back(formats[pos]);

	this->formatlen = cleaned.size()*sizeof(gg_msg_color)+sizeof(gg_msg_richtext);
	header.length = formatlen-sizeof(gg_msg_richtext);
	this->format = new unsigned char[formatlen];
	memcpy(format,&header,sizeof(gg_msg_richtext));
	for(pos=0;pos<cleaned.size();pos++)
		memcpy(format+sizeof(gg_msg_richtext)+pos*sizeof(gg_msg_color),&cleaned[pos],sizeof(gg_msg_color));
}