What Time Is This Returning - windows

Deep in the sauce here. I haven't worked with time to much so I'm a little confused here. I know there is FILETIME and SYSTEMTIME. What I am trying to get at this point (because it might change) are file that are less than a 20 seconds old. This returning the files and their size and something in seconds, What I'd like to know is where it is filtering by time if it is, and how can I adjust it to suit my needs. Thank you.
using namespace std;
typedef vector<WIN32_FIND_DATA> tFoundFilesVector;
std::wstring LastWriteTime;
int getFileList(wstring filespec, tFoundFilesVector &foundFiles)
{
WIN32_FIND_DATA findData;
HANDLE h;
int validResult=true;
int numFoundFiles = 0;
h = FindFirstFile(filespec.c_str(), &findData);
if (h == INVALID_HANDLE_VALUE)
return 0;
while (validResult)
{
numFoundFiles++;
foundFiles.push_back(findData);
validResult = FindNextFile(h, &findData);
}
return numFoundFiles;
}
void showFileAge(tFoundFilesVector &fileList)
{
unsigned _int64 fileTime, curTime, age;
tFoundFilesVector::iterator iter;
FILETIME ftNow;
//__int64 nFileSize;
//LARGE_INTEGER li;
//li.LowPart = ftNow.dwLowDateTime;
//li.HighPart = ftNow.dwHighDateTime;
CoFileTimeNow(&ftNow);
curTime = ((_int64) ftNow.dwHighDateTime << 32) + ftNow.dwLowDateTime;
for (iter=fileList.begin(); iter<fileList.end(); iter++)
{
fileTime = ((_int64)iter->ftLastWriteTime.dwHighDateTime << 32) + iter->ftLastWriteTime.dwLowDateTime;
age = curTime - fileTime;
cout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << " seconds" << endl;
}
}
int main()
{
string fileSpec = "*.*";
tFoundFilesVector foundFiles;
tFoundFilesVector::iterator iter;
int foundCount = 0;
getFileList(L"c:\\Mapper\\*.txt", foundFiles);
getFileList(L"c:\\Mapper\\*.jpg", foundFiles);
foundCount = foundFiles.size();
if (foundCount)
{
cout << "Found "<<foundCount<<" matching files.\n";
showFileAge(foundFiles);
}
system("pause");
return 0;
}

I don't know what you've done to try to debug this but your code doesn't work at all. The reason is you're passing getFileList() a wstring but then passing that to the ANSI version of FindFirstFile(). Unless you #define UNICODE or use the appropriate compiler option, all system calls will expect char *, not UNICODE.
The easiest fix is to simply change the declaration of getFileList() to this:
int getFileList(const char * filespec, tFoundFilesVector &foundFiles)
Change the call to FindFirstFile() to this:
h = FindFirstFile((LPCSTR)filespec, &findData);
And then change the calls to it to this:
getFileList("c:\\Mapper\\*.txt", foundFiles);
getFileList("c:\\Mapper\\*.jpg", foundFiles);
Your other option is to switch all char strings to wide chars, but either way you need to be consistent throughout. Once you do that the program works as expected.
As for your final question, your program is not filtering by time at all.

Not quite an answer, but you might want to read about file system tunneling.
It may prevent you from what you're trying to do in some situations.

Related

Omnet++, A cRuntimeError exception is about to be thrown

I'm currently using Omnet++, and veins, and I have this runtime error appearing suddenly, and I am not able to understand it in order to fix it properly.
Error in module (TraCIDemoRSU11p) RSUExampleScenario.rsu[0].appl
(id=8) at event #6180, t=53.956510612297: Array of size 220 indexed by
220.
TRAPPING on the exception above, due to a debug-on-errors=true configuration option. Is your debugger ready?
I am assuming that it might be related to this message I am sending from the RSU to the vehicles with this code, but I am not sure how it's related.
cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"
}}
class WaveShortMessage;
message DelayedFromControllerMessage extends WaveShortMessage {
string vehiclesList [220] ;
}
I am using omnet++ Version: 5.0 and Veins 4.4
Edited, I'm using the array in these places:
1-
void TraCIDemoRSU11p::sendDelayedMessage(std::list<const char *> vehicleList) {
sentDelayedMessage = true;
//vehicleList = {};
t_channel channel = dataOnSch ? type_SCH : type_CCH;
DelayedFromControllerMessage* dsm = prepareDelayedSM("delayed",dataLengthBits, channel, dataPriority, -1,2,vehicleList);
std::list<const char *>::iterator it = vehicleList.begin();
//const char * v;
char* vx = new char [100];
vx[0] = '\0';
for(int i=0; i<vehicleList.size(); i++){
//v =*it;
strcpy(vx,*it);
//vx = *it;
++it;
dsm->setVehiclesList(i, vx);
}
if (sendDelayedEvt->isScheduled()) {
cancelAndDelete(sendDelayedEvt);
}else {
delete sendDelayedEvt;
}
sendDelayedEvt = new cMessage("delayed evt", SEND_DELAYED_EVT); // create event object to use it in timing
simtime_t offSet = dblrand() * (par("beaconInterval").doubleValue());
TimeStart = simTime() + offSet;
scheduleAt(TimeStart, sendDelayedEvt);
sendDelayedSM(dsm);
}
2-
DelayedFromControllerMessage* BaseWaveApplLayer:: prepareDelayedSM(const char * name, int lengthBits, t_channel channel, int priority, int rcvId,int serial,std::list<const char *>vehicleList ) {
DelayedFromControllerMessage* dsm = new DelayedFromControllerMessage(name);
dsm->addBitLength(headerLength);
dsm->addBitLength(lengthBits);
switch (channel) {
case type_SCH: dsm->setChannelNumber(Channels::SCH1); break; //will be rewritten at Mac1609_4 to actual Service Channel. This is just so no controlInfo is needed
case type_CCH: dsm->setChannelNumber(Channels::CCH); break;
}
dsm->setPsid(0);
dsm->setPriority(priority);
dsm->setWsmVersion(1);
dsm->setTimestamp(simTime());
dsm->setSenderAddress(myId);
dsm->setRecipientAddress(rcvId);
dsm->setSenderPos(curPosition);
dsm->setSerial(serial);
std::list<const char *>::iterator it = vehicleList.begin();
const char * v;
for(int i=0; i<vehicleList.size(); i++){
v =*it;
++it;
VLvar1.push_back(v);
dsm->setVehiclesList(i, v);
}
if ((std::string)name == "beacon") {
DBG << "Creating Beacon with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}
if ((std::string)name == "delayed") {
DBG << "Creating Data with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}
return dsm;
}
3-
void MyTraCIDemo11p::onDataDelayed(DelayedFromControllerMessage* dsm) {
int x = 0;
std::string vehichleId = mobility->getExternalId();
for (int i=0 ; i < dsm->getVehiclesListArraySize();i++)
{
vehicleList.push_back(std::string(dsm->getVehiclesList(i)));
}
ttry = std::find(vehicleList.begin(), vehicleList.end(), vehichleId);
if (vehichleId == *ttry){
x = 1;
}
if (state == QUEUING && x == 1){
findHost()->bubble("Received ");
state = WAITING;
stateToString(state);
}
}
The message should be sent from the RSU to the vehicles.
Even without seeing the actual code from the application (appl) or from the configuration file you are using, I am guessing you are trying to get the last element (element 220) from the array.
The error message already tells what the problem is. Your array has a size of 220 and you are trying to use the index 220 which is not possible, since array indexes start at 0. Therefore for addressing the last element in your array, you have to use index 221.
I am not sure if this is the reason for your error:
ttry = std::find(vehicleList.begin(), vehicleList.end(), vehichleId);
if (vehichleId == *ttry){
x = 1;
}
But, It is better to write it this way:
if (std::find(vehicleList.begin(), vehicleList.end(), vehichleId) != vehicleList.end()){
x = 1;
}
I don't recommend referencing thefind iterator (i.e., *ttry) if it is not found, it is like referencing *(vehicleList.end()).
it seems to me you have two veichleList variables, an array in the dsm and another one which is a vector. is this correct? if yes, you should make sure that the veichleList.size() is always less or equal 220.
Check this tutorial to learn how to debug your project in omnet++:
https://docs.omnetpp.org/tutorials/tictoc/part2/
So i ended up finding a solution for this issue just now.
it was by doing this:
cplusplus {{
#include "veins/modules/messages/WaveShortMessage_m.h"
}}
class WaveShortMessage;
message DelayedFromControllerMessage extends WaveShortMessage {
string vehiclesList [] ;
}
=====
DelayedFromControllerMessage* BaseWaveApplLayer:: prepareDelayedSM(const char * name, int lengthBits, t_channel channel, int priority, int rcvId,int serial,std::list<const char *>vehicleList ) {
DelayedFromControllerMessage* dsm = new DelayedFromControllerMessage(name);
dsm->addBitLength(headerLength);
dsm->addBitLength(lengthBits);
switch (channel) {
case type_SCH: dsm->setChannelNumber(Channels::SCH1); break; //will be rewritten at Mac1609_4 to actual Service Channel. This is just so no controlInfo is needed
case type_CCH: dsm->setChannelNumber(Channels::CCH); break;
}
dsm->setPsid(0);
dsm->setPriority(priority);
dsm->setWsmVersion(1);
dsm->setTimestamp(simTime());
dsm->setSenderAddress(myId);
dsm->setRecipientAddress(rcvId);
dsm->setSenderPos(curPosition);
dsm->setSerial(serial);
int NS = 0;
std::list<const char *>::iterator itPD = vehicleList.begin();
const char * vPD;
int i0 = 0;
while(itPD != vehicleList.end()){
vPD = *itPD;
++itPD;
++NS;
dsm->setVehiclesListArraySize(NS);
dsm->setVehiclesList(i0, vPD);
++i0;
VLvar1.push_back(vPD);
}
if ((std::string)name == "beacon") {
DBG << "Creating Beacon with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}
if ((std::string)name == "delayed") {
DBG << "Creating Data with Priority " << priority << " at Applayer at " << dsm->getTimestamp() << std::endl;
}
return dsm;
}
I removed the array size and placed with a manual counter in BaseWaveApplLayer:: prepareDelayedSM using a while loop. I thought about posting the solution to help others when facing a similar problem. :)

wcstombs & allocating memory for character array on heap

I'm reading a file with a single wide character line in it. But, I never know how long it is going to be. I've read this into a std::wstring, inString, and have managed to create the multi byte string out of thin air (Q1 - are these called r-values?). Q2 - Now, how do I allocate memory for this in the heap and obtain a smart pointer to it ? I do not want to use new or malloc (and call free or delete eventually) or any constant to store it on the stack (for I can never know the max length). Q3 - Can I make use of the make_shared or make_unique function templates here ? Q4 - To be specific, can I get a pointer like shared_ptr<char> pointing to the char array allocated on the heap ?
I tried something like the following,
std::shared_ptr<char> MBString(const_cast<char*>(std::string(inString.begin(), inString.end()).c_str()));
it did not work. I tried a few suggestions on the internet but I don't know how to do it yet.
Q5 - Let alone Wide char to multi -byte conversion, in general, how do I allocate an arbitrary length char string on the heap and get a smart pointer to it ?
std::wfstream inFile(L"lengthUnkown.txt", std::ios::in);
std::wstring inString;
inFile >> inString;
std::wcout << inString << std::endl; //prints correctly
std::cout << (const_cast<char*>(std::string(inString.begin(), inString.end()).c_str())) << std::endl; //this prints the line correctly as expected
//convert wide character string to multi-byte on the heap pointed, to by MBString
//std::cout << MBString << std::endl; //I want to print the multi-byte string like this
return 0;
Not resource optimal but reliable:
wchar_t* mb2wstr(const char* inval) {
size_t size = std::strlen(inval);
#define OUTSZ (size+1)*sizeof(wchar_t)
auto buf = (wchar_t*)std::malloc(OUTSZ);
std::memset(buf, 0, OUTSZ);
std::setlocale(LC_CTYPE,""); // необходима, чтобы отработала "mbstowcs"
size = std::mbstowcs(buf, inval, size);
if ( size == (size_t)(-1) ) {
std::free(buf);
buf = nullptr;
} else {
buf = (wchar_t*)std::realloc(buf,OUTSZ);
}
return buf;
#undef OUTSZ
}
char* wstr2mb(const wchar_t* inval) {
size_t size = std::wcslen(inval);
#define OUTSZ (size+1)*MB_CUR_MAX // Maximum length of a multibyte character in the current locale
auto buf = (char*)std::malloc(OUTSZ);
std::memset(buf, 0, OUTSZ);
std::setlocale(LC_CTYPE,""); // необходима, чтобы отработала "wcstombs"
size = std::wcstombs(buf, inval, size*sizeof(wchar_t));
if ( size == (size_t)(-1) ) {
std::free(buf);
buf = nullptr;
} else {
buf = (char*)std::realloc(buf,size+1);
}
return buf;
#undef OUTSZ
}
const std::string pwchar2string(const wchar_t* inval) {
char* tmp = wstr2mb(inval);
string out{tmp};
std::free(tmp);
return out;
}
const std::wstring pchar2wstring(const char* inval) {
wchar_t* tmp = mb2wstr(inval);
wstring out{tmp};
std::free(tmp);
return out;
}
const wstring string2wstring(const string& value) {
return pchar2wstring(value.c_str());
}
const string wstring2string(const wstring& value) {
return pwchar2string(value.c_str());
}
const wchar_t* char2wchar(const char* value) {
return pchar2wstring(value).c_str();
}
const char* wchar2char(const wchar_t* value) {
return pwchar2string(value).c_str();
}

feeding a stringstream to a class member function

I am a newbie trying to learn by doing. I want to feed a stringstream into a class member function called "print()" but I get errors. Once this works, I can proceed to write more class member functions that work with the data I feed them.
For now I have created a class that has a member function 'print'.
class Month
{
public:
string m_month;
void print()
{
cout << m_month << endl;
}
};
Next, I initialized 12 months:
Month month1 = { "January" };
Month month2 = { "February" };
Month month3 = { "March" };
etc.
When I call "month1.print();" it prints January which is correct.
I used stringstream and a for loop to concatenate month + 1 to 12 and I want to feed the stringstream to the print function.
stringstream os;
string mValue = "month";
int iValue = 1;
for(int i = 0; i < 12; ++i)
{
os << mValue << "" << iValue << "\n";
iValue += 1;
}
However, the stringstream can't be combined with the print function.
os.print(); and os.str().print();
result in "error: ‘std::stringstream {aka class std::__cxx11::basic_stringstream}’ has no member named ‘print’"
Converting the stringstream to char and then feeding it into the print function results in "error: request for member ‘print’ in ‘cstr’, which is of non-class type ‘const char*’"
const string tmp = os.str();
const char* cstr = tmp.c_str();
cstr.print();
Long story short: What I am trying to do is concatenate month + 1 to 12 and feed that to the class member function "print". This seems trivial but I can't get it to work. Any suggestions?
Edit: Full code:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class Month
{
public:
string m_month;
void print()
{
cout << m_month << endl;
}
};
int main()
{
Month month1 = { "January" };
Month month2 = { "February" };
Month month3 = { "March" };
Month month4 = { "April" };
Month month5 = { "May" };
Month month6 = { "June" };
Month month7 = { "July" };
Month month8 = { "August" };
Month month9 = { "September" };
Month month10 = { "October" };
Month month11 = { "November" };
Month month12 = { "December" };
stringstream os; // Initialize stringstream "os"
string mValue = "month"; // Initialize mValue "month"
int iValue = 1; // Initialize iValue "1"
for(int i = 0; i < 12; ++i)
{
os << mValue << "" << iValue << "\n"; // Glue mValue and iValue
// together
iValue += 1; // Increment iValue by one
}
send stringstream "os" to the print function // mock code: Here I want to send month1.print(); month2.print(); etc. to the print function. The output should be January, February etc.
return 0;
}
This doesn't do what you think it does:
for(int i = 0; i < 12; ++i)
{
// iValue is actually unnecessary. You could have just used (i + 1)
os << mValue << "" << iValue << "\n";
iValue += 1;
}
All this does is fill the stringstream with the string:
"month1\nmonth2\nmonth3\nmonth4\nmonth5\nmonth6\nmonth7\nmonth8\nmonth9\nmonth10\nmonth11\nmonth12"
Your intent seemed to be to concat a number to the end of a "month" string, and have them act as the month1, month2... variables that you defined above. That's not how it works. You can't (and shouldn't) try to "dynamically" reference variables like that. In os.print();, the stringstream doesn't act as Month simply because it contains a string with the same name as a Month variable.
Instead, add the variables to some kind of container (like a std::vector), and loop over it:
std::vector<Month> months{ month1, month2, month3, ..., month12 }
for (unsigned int i = 0; i < months.size(); i++)
{
months[i].print();
}
A stringstream should be thought of as a stream like any other, except that it happens to be text and held in memory. So it's cheap to convert it to a string, and in fact they are often used for building strings.
But a "Print" method of a class has no business knowing that a stream is a stringstream. All it should care is that it gets a stream which is text, and is input. In fact the former is a bit hard to enforce due to historical weaknesses stretching back a long way. If you just read the stream byte by byte, pass to std::cout, and terminate on EOF then that's probably OK.

How to get source location of #includes using clang libtooling?

Is there any way to get clang::SourceLocation for every #include in file by its clang::FileID or clang::FileEntry or something?
What about using source manager's GetIncludedLoc function which takes fileid as parameter.
SourceManager.GetIncludedLoc(fileid)
Thank's #Hemant for your answer, you're right
I Already found that by myself (in clang 3.8 it is called getIncludeLoc)
but forgot to write here.
I used this to find the location after all #includes where i can put my own.
Here's the function (For sure not the best way) I wrote for this, hope it helps someone
SourceLocation getIncludeLocation(FileID fileID, SourceManager &sm, unsigned carriages) {
return SourceLocation();
set<unsigned> lines;
if (fileID.isInvalid())
for (auto it = sm.fileinfo_begin(); it != sm.fileinfo_end(); it++) {
SourceLocation includeLoc = sm.getIncludeLoc(sm.translateFile(it->first));
if (includeLoc.isValid() && sm.isInFileID(includeLoc, fileID)) {
lines.insert(sm.getSpellingLineNumber(includeLoc));
}
}
unsigned pos(0);
if (!lines.empty()) {
bool first = true;
for (unsigned line :lines) {
if (first)
first = false;
else if ((line - pos) > carriages)
break;
pos = line;
//cout << "Include line:" << pos << endl;
}
//cout << console_hline('-') << endl;
}
cout << sm.getFileEntryForID(fileID)->getName() << endl;
return sm.translateFileLineCol(sm.getFileEntryForID(fileID), ++pos, 1);
}
Also some information about includes can be get by
Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
and
Lexer::ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines = 0)

File Isn't Deleting

I have a code that finds files that are less than 20 seconds old. It's finding them, but I can't get them deleted. I am using remove(). I've tried using remove with wildcards but no luck. It has to be something with the syntax. Any help is appreciated. Thank you.
using namespace std;
typedef vector<WIN32_FIND_DATA> tFoundFilesVector;
std::wstring LastWriteTime;
int getFileList(const char * filespec, tFoundFilesVector &foundFiles)
{
WIN32_FIND_DATA findData;
HANDLE h;
int validResult=true;
int numFoundFiles = 0;
h = FindFirstFile((LPCSTR)filespec, &findData);
if (h == INVALID_HANDLE_VALUE)
return 0;
while (validResult)
{
numFoundFiles++;
foundFiles.push_back(findData);
validResult = FindNextFile(h, &findData);
}
return numFoundFiles;
}
void showFileAge(tFoundFilesVector &fileList)
{
unsigned _int64 fileTime, curTime, age;
tFoundFilesVector::iterator iter;
FILETIME ftNow;
CoFileTimeNow(&ftNow);
curTime = ((_int64) ftNow.dwHighDateTime << 32) + ftNow.dwLowDateTime;
for (iter=fileList.begin(); iter<fileList.end(); iter++)
{
fileTime = ((_int64)iter->ftLastWriteTime.dwHighDateTime << 32) + iter- >ftLastWriteTime.dwLowDateTime;
age = curTime - fileTime;
if (age <= (_int64)200000000UL)
{
wcout << " Delete: '" <<endl;
wcout << "FILE: '" << iter->cFileName << "', AGE: " << (_int64)age/10000000UL << " seconds" << endl;
remove("C:\\mapper\\iter->cFileName");
}
else
{
//wcout << " Quit: '" <<endl;
//return;
}
}
}
int main()
{
string fileSpec = "*.*";
tFoundFilesVector foundFiles;
tFoundFilesVector::iterator iter;
int foundCount = 0;
getFileList("c:\\Mapper\\*.txt", foundFiles);
getFileList("c:\\Mapper\\*.jpg", foundFiles);
foundCount = foundFiles.size();
if (foundCount)
{
wcout << "Found "<<foundCount<<" matching files.\n";
showFileAge(foundFiles);
}
system("pause");
return 0;
}
You need to concatenate the strings "C:\mapper\" with whatever is in iter->cFileName. The most simple way of doing that would be to use the std::string class.
The result would look something like this:
remove(string("c:\\mapper\\").append(string(iter->cFileName)).c_str());
This assumes you do not use unicode encoding of your strings, otherwise you need to use std::wstring. To use these classes you will also need to include
#include <string>
in the top of your file.

Resources