//--------------------------------------------------------------------------- #pragma hdrstop //#include "stdafx.h" #include #include "wxTools.h" //#include #include //#include //#include //#include //#include //#include //#include #if defined( _VC ) #include < ctime > #endif #if defined( _BORLAND ) #include #endif #include #include #include #include #include #include #include #include #include #include #include //#include #include #include "tcDebug.h" //--------------------------------------------------------------------------- //#pragma package(smart_init) //--------------------------------------------------------------------------- //#if defined( _WX ) //------------------------------------------------------------------------------ //Сохранить данные с веб сервера в массив байт //накопление данных происходит в виде связанного списка, по приходу всего копируется в массив unsigned char* getDataFromURL(const wxString url,unsigned int* size) { RListOne* first=NULL,* next=NULL; //Элементы связанного списка unsigned int bufSize=512; //Размер буфера (и элемента в списке) *size=0; //Размер принятого wxURL murl(url); if (murl.GetError() == wxURL_NOERR) { wxInputStream* is = murl.GetInputStream(); if(is) { unsigned char* buf=new unsigned char[bufSize]; first=new RListOne; first->next=NULL; first->size=0; first->data=new unsigned char[bufSize]; next=first; for(;;) { is->Read(buf, bufSize); size_t n = is->LastRead(); if ( n == 0 ) break; *size+=n; for(size_t i=0;isize==bufSize) { next->next=new RListOne; next=next->next; next->next=NULL; next->size=0; next->data=new unsigned char[bufSize]; } next->data[next->size]=buf[i]; next->size++; } } delete[] buf; delete is; }; }; //собираем данные в массив из связанного списка unsigned char* data=NULL; if(*size==0) return data; data=new unsigned char[*size]; unsigned int pos=0; while(first!=NULL) { memcpy(&data[pos],first->data,first->size); pos+=first->size; next=first; first=first->next; delete[] next->data; //Освобождаем данные delete next; //Освобождаем элемент списка } return data; } //------------------------------------------------------------------------------ wxString getStringOnUrl(const wxString path) { //size_t iRead=0; wxString res = _T(""); wxURL url(path); ((wxProtocol&)url.GetProtocol()).SetTimeout(100); //url->SetProxy(wxT("proxy.localdomain:80")); if (url.GetError() == wxURL_NOERR) { wxInputStream *in_stream = url.GetInputStream(); if( in_stream ) { size_t st=102400; //шаг увеличения буфера 100 килобайт size_t sz=st; //размер текущего буфера unsigned int pos=0; char* buf = new char[sz]; do { //если собираемся прочитать байт в позизию больше че буфер то увеличиваем буфер if(pos>=sz) { char* newbuf = new char[sz+st]; memcpy (newbuf, buf, sz); delete[] buf; buf=newbuf; sz+=st; } buf[pos]=in_stream->GetC(); pos++; } while (in_stream->LastRead()>0); res = wxString::FromUTF8(buf,pos-1); delete[] buf; delete in_stream; } } //delete url; return res; } //------------------------------------------------------------------------------ //Сохранить с сервера url в файл path bool getFileOnWebServer(const wxString url,const wxString path) { bool res=true; wxURL murl(url); if (murl.GetError() == wxURL_NOERR) { wxInputStream* is = murl.GetInputStream(); if(is) { wxFileName fn(path); if(!wxFileName::DirExists(fn.GetPath())) wxFileName::Mkdir(fn.GetPath()); wxFile fOut(path, wxFile::write); if(fOut.IsOpened()) { char buf[1000]; for(;;) { is->Read(buf, 1000); size_t n = is->LastRead(); if ( n == 0 ) break; fOut.Write(buf, n); } }else res=false; delete is; }else res=false; }else res=false; return res; } //------------------------------------------------------------------------------ //вычислить хеш md5 из строки /*wxString md5String(wxString val) { if(val==_T("")) return _T(""); wxString result=_T(""); unsigned char md5digest[MD5_DIGEST_LENGTH]; wxCharBuffer cb=val.ToAscii(); size_t len=strlen((const char*)cb); const unsigned char* buf=(const unsigned char*)(const char*)cb; MD5(buf,len, md5digest); for(unsigned int i=0;iGetExecutablePath(); delete StandardPaths; return path; return ""; }*/ //------------------------------------------------------------------------------ wxString getAfterFirst(wxString str,wxString separator) { int p=str.Find(separator); if(p!=wxNOT_FOUND) { return str.SubString(p+separator.Len(),str.Len()-1); } return _T(""); } //------------------------------------------------------------------------------ wxString getAfterLast(wxString str,wxChar separator) { return str.AfterLast(separator); } //------------------------------------------------------------------------------ wxString getBeforeFirst(wxString str,wxString separator) { int p=str.Find(separator); if(p!=wxNOT_FOUND) return str.SubString(0,p-1); return _T(""); } //------------------------------------------------------------------------------ wxString getBeforeLast(wxString str,wxChar separator) { return str.BeforeLast(separator); } //------------------------------------------------------------------------------ //Заменить все вхождения строки find в sors на repl (wxString::Replace) wxString replaceStrings(wxString sors,wxString find,wxString repl) { if(find==repl) return sors; wxString rez=_T(""); int p=sors.Find(find); while(p!=wxNOT_FOUND) { rez+=sors.SubString(0,p-1)+repl; sors=sors.SubString(p+find.Len(),sors.Len()-1); p=sors.Find(find); } rez+=sors; return rez; } //------------------------------------------------------------------------------ void replaseChars(wxString& str,wxChar oldCh,wxChar newCh) { str.Replace(&oldCh,&newCh,true); } //------------------------------------------------------------------------------ wxString IntToStr(unsigned long i) { wxString str=_T(""); str.Printf(_T("%u"),i); return str; } //------------------------------------------------------------------------------ //Изять из строки только float в качестве разделителя точка wxString getFloatString(wxString str) { wxString res=_T(""); for(unsigned int i=0;i0) { size_t pos=Result.Find(_T('.')); if(pos!=wxNOT_FOUND) { Result=Result.Remove(pos+numdigits+1); for(size_t i=Result.length();i>pos;i--) if(Result[i-1]==_T('0')) Result=Result.Remove(i-1); else break; //Обрезаем нули сконца if(Result.length()==pos+1) Result=Result.Remove(pos); //Если в конце осталась точка } }else if(numdigits==0) { size_t pos=Result.Find(_T('.')); Result=Result.Remove(pos); } return Result; } //------------------------------------------------------------------------------ //Сохранить UTF8 строку не больше 256 байт void saveUTF8String(wxOutputStream *os, wxString str) { const wxCharBuffer buff = str.mb_str(wxConvUTF8); size_t len0 = strlen(buff); unsigned char len1=0; if(len0<=256) len1=(unsigned char)len0; os->Write(&len1,1); if(len1>0) os->Write(buff,len1); } //------------------------------------------------------------------------------ //Сохранить UTF8 строку не больше 256 байт void saveUTF8String(wxFFile *os, wxString str) { const wxCharBuffer buff = str.mb_str(wxConvUTF8); size_t len0 = strlen(buff); unsigned char len1=0; if(len0<=256) len1=(unsigned char)len0; os->Write(&len1,1); if(len1>0) os->Write(buff,len1); } //------------------------------------------------------------------------------ //Сохранить UTF8 строку не больше 65535 байт void saveUTF8String2(wxOutputStream *os, wxString str) { const wxCharBuffer buff = str.mb_str(wxConvUTF8); size_t len0 = strlen(buff); unsigned short len1=0; if(len0<=65535) len1=(unsigned short)len0; os->Write(&len1,2); if(len1>0) os->Write(buff,len1); } //------------------------------------------------------------------------------ //Вырезать из строки под строку (Если разделитель не найден то вырезает всю строку) wxString cutFirstSubStr(wxString &string,wxChar separator) { wxString str=string.BeforeFirst(separator); string=string.AfterFirst(separator); return str; } //------------------------------------------------------------------------------ //выризать из строки под строку wxString cutFirstSubStr(wxString &string,char ch) { wxString str=string.BeforeFirst(ch); string=string.AfterFirst(ch); return str; } //------------------------------------------------------------------------------ int StrToInt(wxString str) { long dblVal; str.ToLong(&dblVal); return dblVal; } //------------------------------------------------------------------------------ //Вырезать из строки только циферки и преобразовать int StrFullToInt(wxString str) { wxString tmp; for(int i=0;i<(int)str.length();i++) { if(str[i]=='-' ||str[i]=='.' || str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9') { tmp+=str[i]; } } long dblVal; tmp.ToLong(&dblVal); return dblVal; } //------------------------------------------------------------------------------ unsigned int StrFullToUInt(wxString str) { wxString tmp; for(int i=0;i<(int)str.length();i++) { if(str[i]=='.' || str[i]=='0' || str[i]=='1' || str[i]=='2' || str[i]=='3' || str[i]=='4' || str[i]=='5' || str[i]=='6' || str[i]=='7' || str[i]=='8' || str[i]=='9') { tmp+=str[i]; } } unsigned long dblVal; tmp.ToULong(&dblVal); return dblVal; } //------------------------------------------------------------------------------ double StrToDouble(wxString str) { double val; str.ToDouble(&val); return val; } //****************************************************************************** wxHtmlOpeningStatus MyHtmlWindow::OnOpeningURL(wxHtmlURLType WXUNUSED(type), const wxString& WXUNUSED(url), wxString *WXUNUSED(redirect)) const { return wxHTML_OPEN; } //------------------------------------------------------------------------------ void MyHtmlWindow::OnLinkClicked(const wxHtmlLinkInfo& link) { wxLaunchDefaultBrowser(link.GetHref()); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //Задание для очереди заданий TTask::TTask(int delay):wxThread(wxTHREAD_DETACHED) { critsectA=new wxCriticalSection(); critsectR=new wxCriticalSection(); listAnswer=new TSimpleList(10,false); listRequest=new TSimpleList(10,false); m_Cancel=false; m_delay=delay; //Стартуем поток if( Create() != wxTHREAD_NO_ERROR ) { //wxLogError(_T("Can’t create thread!")); }else Run(); } //------------------------------------------------------------------------------ void* TTask::Entry() //Функция потока для обработки заданий { RClientData* d; while(!m_Cancel) { d=getTask(); if(d) { //Определяем тип задания и отправляем на выполнение в основном это загрузка данных if(d->url!=_T("")) d->data=getDataFromURL(d->url,&d->size); addAnswer(d); } Sleep(m_delay); } //Удаляем задания d=getTask(); while(d!=NULL) { delete d; d=getTask(); } //Удаляем ответы на всяк случай если они никаму ненужны d=getAnswer(); while(d!=NULL) { delete d; d=getAnswer(); } return NULL; } //------------------------------------------------------------------------------ wxString TAMas::getAt(wxString id) { size_t i=0; while(m_id.Count()>i) { if(m_id.Item(i)==id) return m_val.Item(i); i++; } return _T(""); } //------------------------------------------------------------------------------ void TAMas::setAt(wxString id,wxString val) { m_id.Add(id); m_val.Add(val); } //------------------------------------------------------------------------------ void TAMas::Copy(TAMas& res) { for(unsigned int i=0;ipath=path; first=NULL; if (wxFileExists(path)) { wxTextFile* TextFile = new wxTextFile(); TextFile->Open(path); if (TextFile->Eof()) { TextFile->Close(); delete TextFile; }else { wxString str; wxString section; str = TextFile->GetFirstLine(); while(true) { if (str.Find('[')>=0) { section=str.AfterFirst('[').BeforeLast(']'); } if (str.Find('=')>=0) { TIniStruct* inistr= new TIniStruct; inistr->next=NULL; inistr->section=section; inistr->ident=str.BeforeFirst('='); inistr->value=str.AfterFirst('='); if (first==NULL) { first=inistr; last=inistr; }else { last->next=inistr; last=inistr; } } if (TextFile->Eof()) break; str = TextFile->GetNextLine(); } TextFile->Close(); delete TextFile; } } } //------------------------------------------------------------------------------ TIniFile::~TIniFile() { TIniStruct* inistrdel; TIniStruct* inistr = first; while (inistr!=NULL) { inistrdel=inistr; inistr=inistr->next; delete inistrdel; } } //------------------------------------------------------------------------------ wxString TIniFile::ReadString(wxString Section,wxString Ident,wxString Default) { TIniStruct* inistr = first; while (inistr!=NULL) { if ((inistr->section==Section) && (inistr->ident==Ident)) { return inistr->value; } inistr=inistr->next; } return Default; } //------------------------------------------------------------------------------ float TIniFile::ReadFloat(wxString Section,wxString Ident,float Default) { wxString Result; Result = Result.Format(_T("%f"),Default); Result=ReadString(Section,Ident,Result); double dblVal; Result.Replace(wxT("."), wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,wxLOCALE_CAT_NUMBER)); if(Result.ToDouble(&dblVal)) return dblVal; else return 0; } //------------------------------------------------------------------------------ long TIniFile::ReadLong(wxString Section,wxString Ident,long Default) { wxString Result; Result = Result.Format(_T("%d"),Default); Result=ReadString(Section,Ident,Result); long dblVal; Result.ToLong(&dblVal); return dblVal; } //------------------------------------------------------------------------------ unsigned long TIniFile::ReadULong(wxString Section,wxString Ident,unsigned long Default) { wxString Result; Result = Result.Format(_T("%u"),Default); Result=ReadString(Section,Ident,Result); unsigned long dblVal; Result.ToULong(&dblVal); return dblVal; } //------------------------------------------------------------------------------ bool TIniFile::ReadBool(wxString Section,wxString Ident,bool Default) { wxString Result; if(Default) Result = _T("1"); else Result = _T("0"); Result=ReadString(Section,Ident,Result); if(Result==_T("1")) return true; else return false; } //------------------------------------------------------------------------------ void TIniFile::WriteString(wxString Section,wxString Ident,wxString Value) { //ищем старое значение в заданной секции bool b=false; TIniStruct* lastSel = NULL; //Последний из тойже секции TIniStruct* inistr = first; while (inistr!=NULL) { if(inistr->section==Section) { lastSel=inistr; if(inistr->ident==Ident) { inistr->value=Value; b=true; break; } } inistr=inistr->next; } //если не найденно то добавляем новое значение if (!b) { TIniStruct* inistr= new TIniStruct; inistr->next=NULL; inistr->section=Section; inistr->ident=Ident; inistr->value=Value; if (first==NULL) { first=inistr; last=inistr; }else { if(lastSel==NULL) { last->next=inistr; last=inistr; } else { inistr->next=lastSel->next; lastSel->next=inistr; } } } } //------------------------------------------------------------------------------ void TIniFile::WriteFloat(wxString Section,wxString Ident,float Value) { wxString Result; Result = Result.Format(_T("%f"),Value); Result.Replace(wxLocale::GetInfo(wxLOCALE_DECIMAL_POINT,wxLOCALE_CAT_NUMBER),wxT(".")); WriteString(Section,Ident,Result); } //------------------------------------------------------------------------------ void TIniFile::WriteLong(wxString Section,wxString Ident,long Value) { wxString Result; Result = Result.Format(_T("%d"),Value); WriteString(Section,Ident,Result); } //------------------------------------------------------------------------------ void TIniFile::WriteULong(wxString Section,wxString Ident,unsigned long Value) { wxString Result; Result = Result.Format(_T("%u"),Value); WriteString(Section,Ident,Result); } //------------------------------------------------------------------------------ void TIniFile::WriteBool(wxString Section,wxString Ident,bool Value) { wxString Result; if(Value) Result =_T("1"); else Result =_T("0"); WriteString(Section,Ident,Result); } //------------------------------------------------------------------------------ //Сохранить из памяти в файл void TIniFile::Save() { wxTextFile* TextFile = new wxTextFile(); if(!wxFileExists(path)) TextFile->Create(path); TextFile->Open(path); if(TextFile->IsOpened()) { TextFile->Clear(); wxString LastSection=_T(""); TIniStruct* inistr = first; while (inistr!=NULL) { if (inistr->section!=LastSection) { TextFile->AddLine(_T("[")+inistr->section+_T("]")); LastSection=inistr->section; } TextFile->AddLine(inistr->ident+_T("=")+inistr->value); inistr=inistr->next; } TextFile->Write(); TextFile->Close(); } delete TextFile; } //****************************************************************************** TFileList::TFileList() { size=20; List = new LStream*[size]; count=0; } //------------------------------------------------------------------------------ TFileList::~TFileList() { for(unsigned int i=0;iis; free(List[i]->data); delete List[i]; } delete[] List; } //------------------------------------------------------------------------------ void TFileList::add(wxInputStream *is,wxString name) { if(count>=size)return; LStream *ls=new LStream; ls->name=name; ls->size=(unsigned int)is->GetSize(); ls->data=(char*)malloc(ls->size); //временно в поток потому что текстуру загружать в потоке отличном от контекста нельзя is->Read(ls->data,ls->size); ls->is=new wxMemoryInputStream(ls->data,ls->size); List[count]=ls; count++; } //------------------------------------------------------------------------------ wxInputStream* TFileList::get(wxString name) { for(unsigned int i=0;iname.Lower()==name.Lower()) return List[i]->is; } return NULL; } //------------------------------------------------------------------------------ unsigned int TFileList::getCount() { return count; } //------------------------------------------------------------------------------ LStream* TFileList::item(unsigned int i) { return List[i]; } //****************************************************************************** //------------------------------------------------------------------------------ //THTTPDownload сам вызовет delete если параметр wxTHREAD_DETACHED THTTPDownload::THTTPDownload(wxEvtHandler *parent,wxString url,int userInt,wxString userStr,void* userData,MyFuncPtrType userFun):wxThread(wxTHREAD_DETACHED) { m_Parent=parent; m_CD=new RClientData; m_CD->url=url; m_CD->clientInt=userInt; m_CD->clientStr=userStr; m_CD->clientData=userData; m_CD->clientFun=userFun; m_CD->size=0; m_CD->data=NULL; m_Cancel=false; //Стартуем поток if( Create() != wxTHREAD_NO_ERROR ) { //wxLogError(_T("Can’t create thread!")); }else Run(); } //------------------------------------------------------------------------------ THTTPDownload::~THTTPDownload() { } //------------------------------------------------------------------------------ void* THTTPDownload::Entry() { m_CD->data=getDataFromURL(m_CD->url,&m_CD->size); //если заданна пользовательская функция для обработки данных if(m_CD->clientFun!=NULL) { MyFuncPtrType my_func_ptr=m_CD->clientFun; (*my_func_ptr)(m_CD->size,m_CD->data,m_CD->clientData); } //Посылаем событие о окончании обработки данных if (m_Parent) { wxCommandEvent e(wxEVT_COMMAND_BUTTON_CLICKED,wxID_ANY); e.SetClientData(m_CD); m_Parent->AddPendingEvent(e); //Добавляем событие в очередь обработки } return NULL; } //------------------------------------------------------------------------------ //Отменить загрузку /*void THTTPDownload::Cancel() { m_Cancel=true; }*/ //------------------------------------------------------------------------------ //#endif