// NeL - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdmisc.h" #include "nel/misc/algo.h" using namespace std; #ifdef DEBUG_NEW #define new DEBUG_NEW #endif namespace NLMISC { bool testWildCard(const std::string &strIn, const std::string &wildCard) { return testWildCard(strIn.c_str(), wildCard.c_str()); } // *************************************************************************** bool testWildCard(const char *strIn, const char *wildCard) { // run the 2 string in //el while(*wildCard!=0 && *strIn!=0) { // if same char, continue. if(*wildCard==*strIn) { wildCard++; strIn++; } // if wildCard is ?, continue else if(*wildCard=='?') { wildCard++; strIn++; } // if wildcard is *, recurs check. else if(*wildCard=='*') { wildCard++; // if last *, its OK. if(*wildCard==0) return true; // else must check next strings. else { // build the wilcard token. eg from "*pipo?", take "pipo" string token; while(*wildCard!='*' && *wildCard!='?' && *wildCard!=0) { token+= *wildCard; wildCard++; } // if token size is empty, error if(token.empty()) return false; // in strIn, search all the occurence of token. For each solution, recurs test. string sCopy= strIn; string::size_type pos= sCopy.find(token, 0); while(pos!=string::npos) { // do a testWildCard test on the remaining string/wildCard if( testWildCard(strIn+pos+token.size(), wildCard) ) // if succeed, end return true; // fails=> test with another occurence of token in the string. pos= sCopy.find(token, pos+1); } // if all failed, fail return false; } } // else fail else return false; } // If quit here because end Of 2 strs, OK. if(*wildCard==0 && *strIn==0) return true; // if quit here because wildCard=="*" and s="", OK too. if(*strIn==0 && wildCard[0]=='*' && wildCard[1]==0) return true; /* Else false: It may be wildCard="?aez" and s="" => error It may be wildCard="" and s="aer" => error */ return false; } // *************************************************************************** void splitString(const std::string &str, const std::string &separator, std::vector &retList) { string::size_type pos=0; string::size_type newPos=0; retList.clear(); while( (newPos= str.find(separator,pos)) != string::npos) { // if not empty sub str. (skip repetition of separator ) if(newPos-pos>0) retList.push_back(str.substr(pos, newPos-pos)); // skip token pos= newPos+separator.size(); } // copy the last substr if( pos &retList) { ucstring::size_type pos=0; ucstring::size_type newPos=0; retList.clear(); while( (newPos= ucstr.find(separator,pos)) != ucstring::npos) { // if not empty sub str. (skip repetition of separator ) if(newPos-pos>0) retList.push_back(ucstr.substr(pos, newPos-pos)); // skip token pos= newPos+separator.size(); } // copy the last substr if( pos > &result) { result.clear (); // x0 must be < x1 float dx = (float) fabs (x0-x1); float dy = (float) fabs (y0-y1); if ((dx == 0) && (dy == 0)) result.push_back (pair ((sint)floor (x0), (sint)floor (y0))); else if (dx > dy) { if (x0 > x1) { // Xchg 0 and 1 float temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } float deltaX = x1 - x0; const float deltaY = (y1-y0)/deltaX; // Current integer pixel sint currentX = (sint)floor (x0); sint currentY = (sint)floor (y0); while (deltaX >= 0) { // Next point sint previousY = currentY; // Next y0 if (deltaX > 1) y0 += deltaY; else y0 += deltaX * deltaY; deltaX -= 1; currentY = (sint)y0; // Add point if (currentY<=previousY) { do { result.push_back (pair (currentX, previousY)); previousY--; } while (currentY<=previousY); } else { do { result.push_back (pair (currentX, previousY)); previousY++; } while (currentY>=previousY); } // Next X currentX++; } } else { if (y0 > y1) { // Xchg 0 and 1 float temp = y0; y0 = y1; y1 = temp; temp = x0; x0 = x1; x1 = temp; } float deltaY = y1 - y0; const float deltaX = (x1-x0)/deltaY; // Current integer pixel sint currentY = (sint)floor (y0); sint currentX = (sint)floor (x0); while (deltaY >= 0) { // Next point sint previousX = currentX; // Next x0 if (deltaY > 1) x0 += deltaX; else x0 += deltaY * deltaX; deltaY -= 1; currentX = (sint)x0; // Add point if (currentX<=previousX) { do { result.push_back (pair (previousX, currentY)); previousX--; } while (currentX<=previousX); } else { do { result.push_back (pair (previousX, currentY)); previousX++; } while (currentX>=previousX); } // Next Y currentY++; } } } // *************************************************************************** void drawLine (float x0, float y0, float x1, float y1, vector > &result) { float dx = (float)(floor(x1+0.5) - floor(x0+0.5)); float dy = (float)(floor(y1+0.5) - floor(y0+0.5)); float rdx = x1-x0; float rdy = y1-y0; sint d = (sint)std::max(fabs(dx), fabs(dy)); float maxd = (float)(std::max(fabs(rdx), fabs(rdy))); rdx /= maxd; rdy /= maxd; for (; d>=0; --d) { result.push_back(make_pair((sint)floor(x0+0.5), (sint)floor(y0+0.5))); x0 += rdx; y0 += rdy; } } // *************************************************************************** } // NLMISC