/* * \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; }
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)); }