Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

evautil.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 by yunfan                                          *
00003  *   yunfan_zg@163.com                                                     *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "evautil.h"
00021 #include <string>
00022 #ifdef _WIN32
00023 #include <winsock.h>
00024 #else
00025 #include <arpa/inet.h>
00026 #endif
00027 #include "md5.h"
00028 
00029 const char EvaUtil::smileyMap[QQ_SMILEY_AMOUNT] = {
00030         0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,
00031         0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x73,
00032         0x74,0x75,0x76,0x77,0x8a,0x8b,0x8c,0x8d,
00033         0x8e,0x8f,0x78,0x79,0x7a,0x7b,0x90,0x91,
00034         0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
00035         0x59,0x5a,0x5c,0x58,0x57,0x55,0x7c,0x7d,
00036         0x7e,0x7f,0x9a,0x9b,0x60,0x67,0x9c,0x9d,
00037         0x9e,0x5e,0x9f,0x89,0x80,0x81,0x82,0x62,
00038         0x63,0x64,0x65,0x66,0x83,0x68,0x84,0x85,
00039         0x86,0x87,0x6b,0x6e,0x6f,0x70,0x88,0xa0,
00040         0x50,0x51,0x52,0x53,0x54,0x56,0x5b,0x5d,
00041         0x5f,0x61,0x69,0x6a,0x6c,0x6d,0x71,0x72,
00042 };
00043 
00044 char EvaUtil::md5Buf[KEY_LENGTH];
00045 
00046 EvaUtil::textMap EvaUtil::map[QQ_SMILEY_AMOUNT];
00047 
00048 EvaUtil::EvaUtil()
00049 {
00050         initMap();
00051 }
00052 
00053 char *EvaUtil::doMd5(char *in, int len)
00054 {
00055         md5_state_t ctx;
00056         md5_init(&ctx);
00057         md5_append(&ctx, (md5_byte_t *)in, len);
00058         md5_finish(&ctx, (md5_byte_t *)md5Buf);
00059         return md5Buf;
00060 }
00061 
00062 char *EvaUtil::doMd5Md5(char *in, int len)
00063 {
00064         doMd5(in, len);
00065         doMd5(md5Buf, KEY_LENGTH);
00066         return md5Buf;
00067 }
00068 
00069 std::string EvaUtil::smileyToText(const char smileyCode)
00070 {
00071         int i = smileyToFileIndex(smileyCode);
00072         std::string text = map[i].py;
00073         return text;
00074 }
00075 
00076 char EvaUtil::textToSmiley(const std::string &textTag)
00077 {
00078         std::string strEn, strPy;
00079         for(int i=0; i<QQ_SMILEY_AMOUNT; i++){
00080                 strEn = map[i].en;
00081                 strPy = map[i].py;
00082                 if(strEn == textTag || strPy == textTag){
00083                         return smileyMap[i];
00084                 }
00085         }
00086         return 0;
00087 }
00088 
00089 int EvaUtil::textToFileIndex(const std::string &textTag)
00090 {
00091         char s = textToSmiley(textTag);
00092         return smileyToFileIndex(s);
00093 }
00094 
00095 int EvaUtil::smileyToFileIndex( const char smileyCode)
00096 {
00097         for(int i=0; i<QQ_SMILEY_AMOUNT; i++){
00098                 if(smileyMap[i]==smileyCode)
00099                         return i;
00100         }
00101         return -1;
00102 }
00103 
00104 std::string EvaUtil::fileIndexToText( const int fileIndex)
00105 {
00106         if(fileIndex<0 || fileIndex > 95 ) return "";
00107         return map[fileIndex].py;
00108 }
00109 
00110 std::string EvaUtil::convertToSend( const std::string & text)
00111 {
00112         std::string converted = "";
00113         int offset=0;
00114         char smileyTag = 0x14;
00115         char customTag = 0x15;
00116         bool isFirst32 = true;
00117         std::string code32FileTag = "";
00118         char seperator32_1 = 0x13;
00119         char seperator32_2 = 0x4c;
00120         for(uint i=0; i< text.length(); i++){
00121                 if(text[i] == '/'){
00122                         offset = i;
00123                         while(text[offset] != 0x00 && text[++offset]!=' ');
00124                         if((offset - i)<8){
00125                                 char code = textToSmiley(text.substr(i,offset-i));
00126                                 if(code){
00127                                         converted += smileyTag;
00128                                         converted += code;
00129                                         i=offset;
00130                                         continue;
00131                                 }
00132                         }
00133                         converted+=text[i];
00134                         continue;
00135                 }else{
00136                         if(text[i] == '['){
00137                                 std::string zdyTag = text.substr(i, 5);
00138                                 if(zdyTag == "[ZDY]"){
00139                                         offset = text.find("[/ZDY]", i);
00140                                         std::string zdyType = text.substr(i+6, 2);
00141                                         zdyTag = text.substr(i+5+4, offset-i-14);
00142                                         std::string sendFormat;
00143                                         sendFormat += customTag;
00144                                         if(zdyType == "32"){
00145                                                 if(isFirst32){
00146                                                         code32FileTag = zdyTag.substr(0, zdyTag.length() - 7);
00147                                                         code32FileTag += seperator32_1;
00148                                                         code32FileTag += seperator32_2;
00149                                                         isFirst32 = false;
00150                                                 }
00151                                                 sendFormat += "2"; // 0x32
00152                                                 sendFormat += zdyTag.substr(zdyTag.length() - 2, 2);
00153                                                 sendFormat += "999999";
00154                                         } else  if(zdyType == "36"){
00155                                                 sendFormat += "6"; // note: at the moment, we only use type 6
00156                                                 int len = zdyTag.length() + 5; // the len includes tag(1) and type(1) and itself(3)
00157                                                 char *strLen = new char[4];
00158                                                 sprintf(strLen, "%3d", len);
00159                                                 sendFormat += strLen;
00160                                                 delete strLen;
00161                                                 sendFormat += zdyTag;
00162                                         }
00163                                         converted += sendFormat;//printf("sendFormat:%s\n",sendFormat.c_str());
00164                                         i += (offset - i + 5);
00165                                         continue;
00166                                 }
00167                         }
00168                 }
00169                 converted+=text[i];
00170         }
00171         if(!isFirst32)
00172                 converted = code32FileTag + converted; 
00173         return converted;
00174 }
00175 
00176 std::string EvaUtil::convertToSend(const std::string &text, bool *hasImage)
00177 {
00178         std::string converted = "";
00179         int offset=0;
00180         char smileyTag = 0x14;
00181         char customTag = 0x15;
00182         bool isFirst32 = true;
00183         std::string code32FileTag = "";
00184         char seperator32_1 = 0x13;
00185         char seperator32_2 = 0x4c;
00186         for(uint i=0; i< text.length(); i++){
00187                 if(text[i] == '/'){
00188                         offset = i;
00189                         while(text[offset] != 0x00 && text[++offset]!=' ');
00190                         if((offset - i)<8){
00191                                 char code = textToSmiley(text.substr(i,offset-i));
00192                                 if(code){
00193                                         converted += smileyTag;
00194                                         converted += code;
00195                                         i=offset;
00196                                         continue;
00197                                 }
00198                         }
00199                         converted+=text[i];
00200                         continue;
00201                 }else{
00202                         if(text[i] == '['){
00203                                 std::string zdyTag = text.substr(i, 5);
00204                                 if(zdyTag == "[ZDY]"){
00205                                         offset = text.find("[/ZDY]", i);
00206                                         std::string zdyType = text.substr(i+6, 2);
00207                                         zdyTag = text.substr(i+5+4, offset-i-14);
00208                                         std::string sendFormat;
00209                                         sendFormat += customTag;
00210                                         if(zdyType == "32"){
00211                                                 if(isFirst32){
00212                                                         code32FileTag = zdyTag.substr(0, zdyTag.length() - 7);
00213                                                         code32FileTag += seperator32_1;
00214                                                         code32FileTag += seperator32_2;
00215                                                         isFirst32 = false;
00216                                                 }
00217                                                 sendFormat += "2"; // 0x32
00218                                                 sendFormat += zdyTag.substr(zdyTag.length() - 2, 2);
00219                                                 sendFormat += "999999";
00220                                         } else  if(zdyType == "36"){
00221                                                 sendFormat += "6"; // note: at the moment, we only use type 6
00222                                                 int len = zdyTag.length() + 5; // the len includes tag(1) and type(1) and itself(3)
00223                                                 char *strLen = new char[4];
00224                                                 sprintf(strLen, "%3d", len);
00225                                                 sendFormat += strLen;
00226                                                 delete strLen;
00227                                                 sendFormat += zdyTag;
00228                                         }
00229                                         converted += sendFormat;
00230                                         i += (offset - i + 5);
00231                                         continue;
00232                                 }
00233                         }
00234                 }
00235                 converted+=text[i];
00236         }
00237         if(!isFirst32){
00238                 converted = code32FileTag + converted; 
00239                 *hasImage = true;
00240         } else
00241                 *hasImage = false;
00242         return converted;
00243 }
00244 
00245 void EvaUtil::initMap()
00246 {
00247         strcpy(map[0].en,"/:o"); strcpy(map[0].py, "/jy");
00248         strcpy(map[1].en, "/:~"); strcpy(map[1].py, "/pz");
00249         strcpy(map[2].en, "/:*"); strcpy(map[2].py, "/se");
00250         strcpy(map[3].en, "/:|"); strcpy(map[3].py, "/fd");
00251         strcpy(map[4].en, "/8-)"); strcpy(map[4].py, "/dy");
00252         strcpy(map[5].en, "/:<"); strcpy(map[5].py, "/ll");
00253         strcpy(map[6].en, "/:$"); strcpy(map[6].py, "/hx");
00254         strcpy(map[7].en, "/:x"); strcpy(map[7].py, "/bz");
00255         strcpy(map[8].en, "/:z"); strcpy(map[8].py, "/shui");
00256         strcpy(map[9].en, "/:'"); strcpy(map[9].py, "/dk");
00257         
00258         strcpy(map[10].en, "/:-|"); strcpy(map[10].py, "/gg");
00259         strcpy(map[11].en, "/:@"); strcpy(map[11].py, "/fn");
00260         strcpy(map[12].en, "/:P"); strcpy(map[12].py, "/tp");
00261         strcpy(map[13].en, "/:D"); strcpy(map[13].py, "/cy");
00262         strcpy(map[14].en, "/:)"); strcpy(map[14].py, "/wx");
00263         strcpy(map[15].en, "/:("); strcpy(map[15].py, "/ng");
00264         strcpy(map[16].en, "/:+"); strcpy(map[16].py, "/kuk");
00265         strcpy(map[17].en, "/:#"); strcpy(map[17].py, "/feid");
00266         strcpy(map[18].en, "/:Q"); strcpy(map[18].py, "/zk");
00267         strcpy(map[19].en, "/:t"); strcpy(map[19].py, "/tu");
00268         
00269                 
00270         strcpy(map[20].en, "/;P"); strcpy(map[20].py, "/tx");
00271         strcpy(map[21].en, "/;-D"); strcpy(map[21].py, "/ka");
00272         strcpy(map[22].en, "/;d"); strcpy(map[22].py, "/baiy");
00273         strcpy(map[23].en, "/;o"); strcpy(map[23].py, "/am");
00274         strcpy(map[24].en, "/:g"); strcpy(map[24].py, "/jie");
00275         strcpy(map[25].en, "/|-)"); strcpy(map[25].py, "/kun");
00276         strcpy(map[26].en, "/:!"); strcpy(map[26].py, "/jk");
00277         strcpy(map[27].en, "/:L"); strcpy(map[27].py, "/lh");
00278         strcpy(map[28].en, "/:>"); strcpy(map[28].py, "/hanx");
00279         strcpy(map[29].en, "/:;"); strcpy(map[29].py, "/db");
00280         
00281         strcpy(map[30].en, "/;f"); strcpy(map[30].py, "/fendou");
00282         strcpy(map[31].en, "/:-S"); strcpy(map[31].py, "/zhm");
00283         strcpy(map[32].en, "/?"); strcpy(map[32].py, "/yiw");
00284         strcpy(map[33].en, "/;x"); strcpy(map[33].py, "/xu");
00285         strcpy(map[34].en, "/;@"); strcpy(map[34].py, "/yun");
00286         strcpy(map[35].en, "/:8"); strcpy(map[35].py, "/zhem");
00287         strcpy(map[36].en, "/;!"); strcpy(map[36].py, "/shuai");
00288         strcpy(map[37].en, "/!!!"); strcpy(map[37].py, "/kl");
00289         strcpy(map[38].en, "/xx"); strcpy(map[38].py, "/qiao");
00290         strcpy(map[39].en, "/bye"); strcpy(map[39].py, "/zj");
00291         
00292                 
00293         strcpy(map[40].en, "/go"); strcpy(map[40].py, "/shan");
00294         strcpy(map[41].en, "/shake"); strcpy(map[41].py, "/fad");
00295         strcpy(map[42].en, "/love"); strcpy(map[42].py, "/aiq");
00296         strcpy(map[43].en, "/jump"); strcpy(map[43].py, "/tiao");
00297         strcpy(map[44].en, "/find"); strcpy(map[44].py, "/zhao");
00298         strcpy(map[45].en, "/&"); strcpy(map[45].py, "/mm");
00299         strcpy(map[46].en, "/pig"); strcpy(map[46].py, "/zt");
00300         strcpy(map[47].en, "/cat"); strcpy(map[47].py, "/maom");
00301         strcpy(map[48].en, "/dog"); strcpy(map[48].py, "/xg");
00302         strcpy(map[49].en, "/hug"); strcpy(map[49].py, "/yb");
00303         
00304         strcpy(map[50].en, "/$"); strcpy(map[50].py, "/qianc");
00305         strcpy(map[51].en, "/(!)"); strcpy(map[51].py, "/dp");
00306         strcpy(map[52].en, "/cup"); strcpy(map[52].py, "/bei");
00307         strcpy(map[53].en, "/cake"); strcpy(map[53].py, "/dg");
00308         strcpy(map[54].en, "/li"); strcpy(map[54].py, "/shd");
00309         strcpy(map[55].en, "/bome"); strcpy(map[55].py, "/zhd");
00310         strcpy(map[56].en, "/kn"); strcpy(map[56].py, "/dao");
00311         strcpy(map[57].en, "/footb"); strcpy(map[57].py, "/zq");
00312         strcpy(map[58].en, "/music"); strcpy(map[58].py, "/yy");
00313         strcpy(map[59].en, "/shit"); strcpy(map[59].py, "/bb");
00314         
00315                 
00316         strcpy(map[60].en, "/coffee"); strcpy(map[60].py, "/kf");
00317         strcpy(map[61].en, "/eat"); strcpy(map[61].py, "/fa");
00318         strcpy(map[62].en, "/pill"); strcpy(map[62].py, "/yw");
00319         strcpy(map[63].en, "/rose"); strcpy(map[63].py, "/mg");
00320         strcpy(map[64].en, "/fade"); strcpy(map[64].py, "/dx");
00321         strcpy(map[65].en, "/kiss"); strcpy(map[65].py, "/wen");
00322         strcpy(map[66].en, "/heart"); strcpy(map[66].py, "/xin");
00323         strcpy(map[67].en, "/break"); strcpy(map[67].py, "/xs");
00324         strcpy(map[68].en, "/meeting"); strcpy(map[68].py, "/hy");
00325         strcpy(map[69].en, "/gift"); strcpy(map[69].py, "/lw");
00326         
00327         strcpy(map[70].en, "/phone"); strcpy(map[70].py, "/dh");
00328         strcpy(map[71].en, "/time"); strcpy(map[71].py, "/sj");
00329         strcpy(map[72].en, "/email"); strcpy(map[72].py, "/yj");
00330         strcpy(map[73].en, "/tv"); strcpy(map[73].py, "/ds");
00331         strcpy(map[74].en, "/sun"); strcpy(map[74].py, "/ty");
00332         strcpy(map[75].en, "/moon"); strcpy(map[75].py, "/yl");
00333         strcpy(map[76].en, "/strong"); strcpy(map[76].py, "/qiang");
00334         strcpy(map[77].en, "/weak"); strcpy(map[77].py, "/ruo");
00335         strcpy(map[78].en, "/share"); strcpy(map[78].py, "/ws");
00336         strcpy(map[79].en, "/v"); strcpy(map[79].py, "/shl");
00337         
00338                 
00339         strcpy(map[80].en, "/<D>"); strcpy(map[80].py, "/dd");
00340         strcpy(map[81].en, "/<J>"); strcpy(map[81].py, "/mn");
00341         strcpy(map[82].en, "/<H>"); strcpy(map[82].py, "/hl");
00342         strcpy(map[83].en, "/<M>"); strcpy(map[83].py, "/mamao");
00343         strcpy(map[84].en, "/<QQ>"); strcpy(map[84].py, "/qz");
00344         strcpy(map[85].en, "/<L>"); strcpy(map[85].py, "/fw");
00345         strcpy(map[86].en, "/<O>"); strcpy(map[86].py, "/oh");
00346         strcpy(map[87].en, "/<B>"); strcpy(map[87].py, "/bj");
00347         strcpy(map[88].en, "/<U>"); strcpy(map[88].py, "/qsh");
00348         strcpy(map[89].en, "/<W>"); strcpy(map[89].py, "/xig");
00349         
00350         strcpy(map[90].en, "/<!!>"); strcpy(map[90].py, "/xy");
00351         strcpy(map[91].en, "/<~>"); strcpy(map[91].py, "/duoy");
00352         strcpy(map[92].en, "/<Z>"); strcpy(map[92].py, "/xr");
00353         strcpy(map[93].en, "/<*>"); strcpy(map[93].py, "/xixing");
00354         strcpy(map[94].en, "/<00>"); strcpy(map[94].py, "/nv");
00355         strcpy(map[95].en, "/<11>"); strcpy(map[95].py, "/nan");
00356 };
00357 
00358 void EvaUtil::calcSuns( const unsigned short level, int * suns, int * moons, int * stars )
00359 {
00360         *suns = 0;
00361         *moons = 0;
00362         *stars = 0;
00363         
00364         *suns = level/16;
00365         *moons = (level%16)/4;
00366         *stars = level%4;
00367 }
00368 
00369 std::string EvaUtil::customSmileyToText( const char * buf, int * smileyLength, const char *uuid)
00370 {
00371         if(buf[0] != 0x15) return "";
00372         
00373         char *strTmp = new char[1000];
00374         std::string strRet = "[ZDY]";
00375         int pos=1;
00376         switch( buf[pos++] ){
00377         case 0x32:{
00378                 if(!uuid) break;
00379                 char ext = buf[pos++]; // ignore 1 byte, 'A':jpg, 'C':gif
00380                 char seq = buf[pos++] - 0x11; // the image tail sequence
00381                 pos += 6; // "999999", always be
00382 
00383                 strRet += "[32]";
00384                 strRet += uuid;
00385                 strRet += seq;
00386                 switch(ext){
00387                 case 'A':
00388                         strRet += ".jpg";
00389                         break;
00390                 case 'C':
00391                         strRet += ".gif";
00392                 default:
00393                         printf("EvaUtil::customSmileyToText -- unknown file extension : 0x%2x\n", 0xff&ext);
00394                         break;
00395                 }
00396                 strRet += "[/32]";
00397                 }
00398                 break;
00399         case 0x33:{
00400                 pos++; // ignore 1 unknown byte
00401                 memcpy(strTmp, buf+pos, 32 + 1 + 3); // copy filename, contains 32(md5 of the file) + 1('.') + 3("GIF')
00402                 strTmp[32 + 1 + 3] = 0x00;
00403                 pos += (32+1+3);
00404                 
00405                 strRet += "[33]";
00406                 strRet += std::string(strTmp);
00407                 
00408                 int len = (buf[pos++] - 'A') & 0xff;
00409                 memcpy(strTmp, buf+pos, len);
00410                 strTmp[len] = 0x00;
00411                 pos += len; 
00412                 
00413                 strRet += std::string(strTmp);
00414                 strRet += "[/33]";
00415                 }
00416                 break;
00417         case 0x34:{
00418                 strRet += "[34]";
00419                 strRet += buf[pos++];
00420                 strRet += "[/34]";
00421                 }
00422                 break;
00423         case 0x36:{
00424                 char *partLen = new char[4];
00425                 int lenLen = 0;
00426                 while(buf[pos + lenLen] == 0x20){
00427                         partLen[lenLen++] = '0';
00428                 };
00429                 memcpy(partLen + lenLen, buf + pos + lenLen, 3 - lenLen);
00430                 partLen[3]=0x00;
00431                 int len = atoi(partLen);printf("36 len:%d\n",len);
00432                 delete partLen;
00433                 
00434                 strRet += "[36]";
00435                 memcpy(strTmp, buf+pos+3, len - pos - 3);
00436                 strTmp[len - pos - 3] = 0x00;
00437                 strRet += strTmp;
00438                 strRet += "[/36]";
00439                 
00440                 pos = len; // ignore 0x15 and 0x36 and 3 bytes(length of this part)
00441                 }
00442                 break;
00443         case 0x37:{
00444                 char *partLen = new char[4];
00445                 int lenLen = 0;
00446                 while(buf[pos + lenLen] == 0x20){
00447                         partLen[lenLen++] = '0';
00448                 };
00449                 memcpy(partLen + lenLen, buf + pos + lenLen, 3 - lenLen);
00450                 partLen[3]=0x00;
00451                 int len = atoi(partLen);printf("37 len:%d\n",len);
00452                 delete partLen;
00453                 
00454                 strRet += "[37]";
00455                 memcpy(strTmp, buf+pos+3, len -pos-3);
00456                 strTmp[len - pos - 3] = 0x00;
00457                 strRet += strTmp;
00458                 strRet += "[/37]";
00459                 
00460                 pos = len;
00461                 }
00462                 break;
00463         default:
00464                 sprintf(strTmp,"%d", buf[pos-1]);
00465                 strRet += "[";
00466                 strRet += strTmp;
00467                 strRet += "]";
00468                 break;
00469         }
00470         delete strTmp;
00471         *smileyLength = pos;
00472         strRet += "[/ZDY]";
00473 //      printf("DONE\n--%s\n", strRet.c_str());
00474         return strRet;
00475 }
00476 
00477 int EvaUtil::write16(unsigned char *buf, const unsigned short value )
00478 {
00479         unsigned short tmp = htons(value);
00480         memcpy(buf, &tmp, 2);
00481         return 2;
00482 }
00483 
00484 int EvaUtil::write32( unsigned char *buf, const unsigned int value )
00485 {
00486         unsigned int tmp = htonl(value);
00487         memcpy(buf, &tmp, 4);
00488         return 4;
00489 }
00490 
00491 unsigned short EvaUtil::read16( const unsigned char * buf )
00492 {
00493         unsigned short tmp;
00494         memcpy(&tmp, buf, 2);
00495         return ntohs(tmp);
00496 }
00497 
00498 unsigned int EvaUtil::read32( const unsigned char * buf )
00499 {
00500         unsigned int tmp;
00501         memcpy(&tmp, buf, 4);
00502         return ntohl(tmp);
00503 }

Generated on Mon May 15 20:48:41 2006 for libeva by  doxygen 1.4.4