Assert a BSTR with string - c++

I have a test function as follow:
[TestMethod]
void RipMichaelJacksonTest()
{
string expected = "Hello";
BSTR actual = SysAllocString(L"Hello");
Assert::AreEqual(expected, actual);
}
The assert part will of course fail.
Is there any Assert function that i can use?
Im new to VC++.

The problem is that you are doing a AreEqual. Passing in two parameters will force AreEqual(Object^, Object^) which:
Verifies that two specified objects are equal. The assertion fails if the objects are not equal.
What you are actually looking for is the comparison of a wchar* and a char*. There is not a direct comparison function between the two so it will be necessary to convert from a string to a wstring. There are lots of examples of how to do that, such as: https://stackoverflow.com/a/7159944/2642059 and you'll need to do something similar, for example:
wstring get_wstring(const string& s) {
wstring buf;
const char* cs = s.c_str();
const size_t wn = mbsrtowcs(nullptr, &cs, 0, nullptr);
if (wn == string::npos) {
cout << "Error in mbsrtowcs(): " << errno << endl;
} else {
buf.resize(wn + 1);
if(mbsrtowcs(&*buf.begin(), &cs, wn + 1, nullptr) == string::npos) {
cout << "Error in mbsrtowcs(): " << errno << endl;
buf.resize(0);
}
}
return buf;
}
The return of get_wstring(expected) and actual will now both be wchars and can thereby be compared in the using AreEqual(String^, String^, bool)

Related

C++ String to byte

so i have a string like this:std::string MyString = "\\xce\\xc6";
where when i print it like this:std::cout << MyString.c_str()[0] << std::endl;
as output i get:\
and i want it to be like this:std::string MyDesiredString = "\xce\xc6";
so when i do:
std::cout << MyDesiredString.c_str()[0] << std::endl;
// OUTPUT: \xce (the whole byte)
so basically i want to identify the string(that represents bytes) and convert it to an array of real bytes
i came up with a function like this:
// this is a pseudo code i'm sure it has a lot of bugs and may not even work
// just for example for what i think
char str_to_bytes(const char* MyStr) { // MyStr length == 4 (\\xc6)
std::map<char*, char> MyMap = { {"\\xce", '\xce'}, {"\\xc6", 'xc6'} } // and so on
return MyMap[MyStr]
}
//if the provided char* is "\\xc6" it should return the char '\xc6'
but i believe there must be a better way to do it.
as much as i have searched i haven't found anything useful
thanks in advance
Try something like this:
std::string teststr = "\\xce\\xc6";
std::string delimiter = "\\x";
size_t pos = 0;
std::string token;
std::string res;
while ((pos = teststr.find(delimiter)) != std::string::npos) {
token = teststr.substr(pos + delimiter.length(), 2);
res.push_back((char)stol(token, nullptr, 16));
std::cout << stol(token, nullptr, 16) << std::endl;
teststr.erase(pos, pos + delimiter.length() + 2);
}
std::cout << res << std::endl;
Take your string, split it up by the literals indicating a hex. value is provided (\x) and then parse the two hex. characters with the stol function as Igor Tandetnik mentioned. You can then of course add those byte values to a string.

passing array as return from function in multi threaded app

i try to make code which is multithreaded and at certain step i have to retrieve array made on heap.
this is the code:
the following function will call another function called read_bi5_to_bin and it will pass to it unsigned char* initialized as nullptr data_bin_buffer
int HTTPRequest::read_bi5_main(boost::filesystem::path p, ptime epoch)
{
boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex,boost::defer_lock);
unsigned char *buffer;
size_t buffer_size;
int counter;
size_t raw_size = 0;
std::string filename_string = p.generic_string();
path p2 = p;
p2.replace_extension(".bin");
std::string filename_string_2_bin =p2.generic_string() ;
path p3 = p;
p3.replace_extension(".csv");
std::string filename_string_2_csv = p3.generic_string();
const char *filename = filename_string.c_str();
const char *filename_2_bin = filename_string_2_bin.c_str();
const char *filename_2_csv = filename_string_2_csv.c_str();
if (fs::exists(p) && fs::is_regular(p))
{
buffer_size = fs::file_size(p);
buffer = new unsigned char[buffer_size];
}
else {
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data file. |"
<< filename << "|" << std::endl;
read_bi5_to_bin_lock.unlock();
return 2;
}
std::ifstream fin(filename, std::ifstream::binary);
//fin.open(filename, std::ifstream::binary);
fin.read(reinterpret_cast<char*>(buffer), buffer_size);
fin.close();
//5-11-2020 the next line will be commented and put in HTTPCLIent constructor
//mHTTPRequest_Symbol_str= mHTTPRequest_HTTPClient_shared_pointer->Get_mHttpClient_HttpSymbolPrepareGet_shared_pointer()->mSymbol_strGet() ;
std::size_t pos = mHTTPRequest_Symbol_str.find("JPY");// position of "h_ticks.bi5" in str
double PV;
if (pos != std::string::npos)
{
PV = PV_YEN_PAIR;
}
else
{
PV = PV_DOLLAR_PAIR;
}
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
//5-20-2020
//boost::shared_ptr<unsigned char> data_bin_buffer = boost::make_shared<unsigned char>() ;
//n47::tick_data *data = n47::read_bi5_to_bin(
// buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer.get());
unsigned char* data_bin_buffer = nullptr;
n47::tick_data *data = n47::read_bi5_to_bin(
buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer);
//5-11-2020 here i will save binary file
//boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex);
std::string file_name_path_string=output_compressed_file_2(data_bin_buffer, raw_size, filename_2_bin);
read_bi5_to_bin_lock.unlock();
path file_name_path_2{ file_name_path_string };
buffer_size = 0;
if (fs::exists(file_name_path_2) && fs::is_regular(file_name_path_2))
{
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << boost::this_thread::get_id() <<"\t we can access the data .bin file. |"
<< filename_2_bin << "| with size ="<< fs::file_size(file_name_path_2) << std::endl;
read_bi5_to_bin_lock.unlock();
}
else {
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data .bin file. |"
<< filename_2_bin << "|" << std::endl;
read_bi5_to_bin_lock.unlock();
return 2;
}
n47::tick_data_iterator iter;
//5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks
if (data == 0) {
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Failed to load the data!" << std::endl;
read_bi5_to_bin_lock.unlock();
//5-14-2020 file is empty
//return 0;
}
//5-15-2020 take care that without else ,error happens with empty files because data is pointer to vector of pointers to ticks .so when data is made inside read_bi5 ,it is made as null pointer and later it is assigned to vector if file has ticks.if file does not have ticks ,then it is just returned as null pointer .so when dereferencing null pointer we got error
else if (data->size() != (raw_size / n47::ROW_SIZE)) {
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Loaded " << data->size()
<< " ticks but file size indicates we should have loaded "
<< (raw_size / n47::ROW_SIZE) << std::endl;
read_bi5_to_bin_lock.unlock();
//5-14-2020 file is empty
//return 0;
}
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "time, bid, bid_vol, ask, ask_vol" << std::endl;
read_bi5_to_bin_lock.unlock();
counter = 0;
std::ofstream out_csv(filename_string_2_csv);
if (data == 0)
{
}
else if (data != 0)
{
////read_bi5_to_bin_lock.lock();
for (iter = data->begin(); iter != data->end(); iter++) {
//5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks>>>>>>>here i should open file stream for output and save data to it
out_csv << ((*iter)->epoch + (*iter)->td) << ", "
<< (*iter)->bid << ", " << (*iter)->bidv << ", "
<< (*iter)->ask << ", " << (*iter)->askv << std::endl;
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) <<
boost::this_thread::get_id() << "\t"<<((*iter)->epoch + (*iter)->td) << ", "
<< (*iter)->bid << ", " << (*iter)->bidv << ", "
<< (*iter)->ask << ", " << (*iter)->askv << std::endl;
read_bi5_to_bin_lock.unlock();
counter++;
}
////read_bi5_to_bin_lock.unlock();
}
out_csv.close();
//5-13-2020
//??5-17-2020 isolate multithreaded error
read_bi5_to_bin_lock.lock();
BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << ".end." << std::endl << std::endl
<< "From " << raw_size << " bytes we read " << counter
<< " records." << std::endl
<< raw_size << " / " << n47::ROW_SIZE << " = "
<< (raw_size / n47::ROW_SIZE) << std::endl;
read_bi5_to_bin_lock.unlock();
delete data;
delete[] buffer;
delete [] data_bin_buffer;
return 0;
}
then inside read_bi5_to_bin function ,there will be a call to another function n47::lzma::decompress . this is the code of read_bi5_to_bin:
tick_data* read_bi5_to_bin(
unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
float point_value, size_t *bytes_read, unsigned char* buffer_decompressed) {
tick_data *result = 0;
// decompress
int status;
buffer_decompressed = n47::lzma::decompress(lzma_buffer,
lzma_buffer_size, &status, bytes_read);
if (status != N47_E_OK)
{
bytes_read = 0;
}
else {
// convert to tick data (with read_bin).
result = read_bin(buffer_decompressed, *bytes_read, epoch, point_value);
//delete[] buffer;
}
return result;
}
then inside n47::lzma::decompress there will be making an array on heap called outBuffer .this buffer i need to retrieve at read_bi5_main in data_bin_buffer
this is code for n47::lzma::decompress
unsigned char *decompress(
unsigned char *inBuffer, size_t inSize, int *status, size_t *outSize) {
unsigned char *outBuffer = 0;
elzma_file_format format = ELZMA_lzma;
elzma_decompress_handle handle;
handle = elzma_decompress_alloc();
if (handle == 0) {
*status = -1;
} else {
// decompression...
datastream ds(inBuffer, inSize);
*status = elzma_decompress_run(
handle,
inputCallback, static_cast<void*>(&ds),
outputCallback, static_cast <void*>(&ds),
format);
if (*status == ELZMA_E_OK) {
*outSize = ds.outData.size();
outBuffer = new unsigned char[ ds.outData.size() ];
std::copy(ds.outData.begin(), ds.outData.end(), outBuffer);
}
elzma_decompress_free(&handle);
}
return outBuffer;
}
when i run this it gives error.a very helpful one here told me that it is the data_bin_buffer which is the problem because it is just one byte.and advised me to avoid shared pointer.when i convert it to normal pointer it gives another error if initialzed it to nullptr.should i not initialize the pointer???
Your read_bi5_to_bin code is broken.
tick_data* read_bi5_to_bin(
unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
float point_value, size_t *bytes_read, unsigned char* buffer_decompressed) {
tick_data *result = 0;
The code receives a pointer called buffer_decompressed.
// decompress
int status;
buffer_decompressed = n47::lzma::decompress(lzma_buffer,
lzma_buffer_size, &status, bytes_read);
Then it throws away the value it received and gets some other value.
if (status != N47_E_OK)
{
bytes_read = 0;
}
else {
// convert to tick data (with read_bin).
result = read_bin(buffer_decompressed, *bytes_read, epoch, point_value);
//delete[] buffer;
}
return result;
}
And it never returns or frees the value it stored in buffer_decompressed.
Ooops.
I found the problem in my code.
it is the way i pass pointer to unsigned char to read_bi5_to_bin .
at first I thought passing the pointer variable is correct"as if i am passing lvalue reference" but i was so much wrong.reference is different than pointer.
pointer variable is lvalue variable of type pointer.so it is copied into function making new lvalue variable in function .the new variable has same value of pointer passed.this value is the address to first unsigned char in array.
but what i really need is to pass pointer to pointer to unsigned char.then pointer to pointer will be copied into function.the value of copied variable will be address of pointer to unsigned char.this is what i need retrieve from function.
I used & operator to get pointer to pointer .then I read very useful comment suggesting using ** so i changed the code to use **.voila,it works
this is the modified code:
read_bi5_to_bin_lock2.lock();
//5-20-2020
//boost::shared_ptr<unsigned char> data_bin_buffer = boost::make_shared<unsigned char>() ;
//n47::tick_data *data = n47::read_bi5_to_bin(
// buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer.get());
unsigned char *data_bin_buffer = 0 ;
n47::tick_data *data = n47::read_bi5_to_bin(
buffer, buffer_size, epoch, PV, &raw_size, &data_bin_buffer);
//5-11-2020 here i will save binary file
//boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex);
std::string file_name_path_string=output_compressed_file_2(&data_bin_buffer, raw_size, filename_2_bin);
read_bi5_to_bin_lock2.unlock();
and this is the modified code in read_bi5_to_bin:
tick_data* read_bi5_to_bin(
unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
float point_value, size_t *bytes_read, unsigned char** buffer_decompressed) {
tick_data *result = 0;
// decompress
int status;
*buffer_decompressed = n47::lzma::decompress(lzma_buffer,
lzma_buffer_size, &status, bytes_read);
thanks alot to DavidSchwartz for his very helpful comment.

Generate a random unicode string

In VS2010, this function below prints "stdout in error state", I'm unable to understand why. Any thoughts on what I'm doing wrong?
void printUnicodeChars()
{
const auto beg = 0x0030;
const auto end = 0x0039;
wchar_t uchars[end-beg+2];
for (auto i = beg; i <= end; i++) {
uchars[i-beg] = i; // I tried a static_cast<wchar_t>(i), still errors!
}
uchars[end+1] = L'\0';
std::wcout << uchars << std::endl;
if (!std::wcout) {
std::cerr << std::endl << "stdout in error state" << std::endl;
} else {
std::cerr << std::endl << "stdout is good" << std::endl;
}
}
Thanks to #0x499602D2, I found out I had an array out of bounds error in my functions. To be more clear, I wanted my function to construct an unicode string whose characters are in the range [start, end]. This was my final version:
// Generate an unicode string of length 'len' whose characters are in range [start, end]
wchar_t* generateRandomUnicodeString(size_t len, size_t start, size_t end)
{
wchar_t* ustr = new wchar_t[len+1]; // +1 for '\0'
size_t intervalLength = end - start + 1; // +1 for inclusive range
srand(time(NULL));
for (auto i = 0; i < len; i++) {
ustr[i] = (rand() % intervalLength) + start;
}
ustr[len] = L'\0';
return ustr;
}
When this function is called as follows, it generates an unicode string with 5 cyrillic characters.
int main()
{
_setmode(_fileno(stdout), _O_U16TEXT);
wchar_t* output = generateRandomUnicodeString(5, 0x0400, 0x04FF);
wcout << "Random Unicode String = " << output << endl;
delete[] output;
return 0;
}
PS: This function as weird and arbitrary as it may seem, serves a usual purpose for me, I need to generate sample strings for a unit-test case that checks to see if unicode strings are written and retrieved properly from a database, which is the backend of a c++ application. In the past we have seen failures with unicode strings that contain non-ASCII characters, we tracked that bug down and fixed it and this random unicode string logic serves to test that fix.

C++ String to byte error

So, I converted the string to byte in C++, but when it goes to add it into registry, it's stripping off the exe part but keeping the ., I have no idea what's wrong with it.
If you're wondering what NXS is, the value of it is "noerrorsplease.exe", type is char.
char szFinal[] = "";
strcat(szFinal, (const char *)ExtractDirectory(filepath).c_str());
//Not needed: strcat(szFinal, "");
strcat(szFinal, nxs);
strcat(szFinal, ".exe");
CString str;
str = szFinal;
str += ".exe";
cout << str.GetString() << endl;
const BYTE* pb = reinterpret_cast<const BYTE*>(str.GetString());
cout << pb << endl;
DWORD pathLenInBytes = *szFinal * sizeof(*szFinal);
if(RegSetValueEx(newValue, TEXT("Printing Device"), 0, REG_SZ, (LPBYTE)pb, pathLenInBytes) != ERROR_SUCCESS)
{
RegCloseKey(newValue);
cout << "error" << endl;
}
cout << "Possibly worked." << endl;
RegCloseKey(newValue);
This code
char szFinal[] = "";
strcat(szFinal, (const char *)ExtractDirectory(filepath).c_str());
is already invalid. You defined array szFina having only one character that is the terminating zero. You may not use it for copying in it any string. In these situations you should use an object of type std::string.

Case sensitive string comparison in C++

Can anyone pls let me know the exact c++ code of case sensitive comparison function of string class?
How about?
std::string str1, str2;
/* do stuff to str1 and str2 */
if (str1 == str2) { /* do something */ }
Or
if (str1.compare(str2) == 0) { /* the strings are the same */ }
std::string str1("A new String");
std::string str2("a new STring");
if(str1.compare(str2) == 0)
std::cout<<"Equal"; // str1("A new String") str2("A new String");
else
std::cout<<"unEqual"; //str1("A new String") str2("a new STring")
compare() returns an integral value rather than a boolean value. Return value has the following meaning: 0 means equal, a value less than zero means less than, and a value greater than zero means greater than
== is overloaded for string comparison in C++ AFAIK (unlike in Java, where u have to use myString.equals(..))
If you want to ignore case when comparing, just convert both strings to upper or lower case as explained here: Convert a String In C++ To Upper Case
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string str1 ("green apple");
string str2 ("red apple");
if (str1.compare(str2) != 0)
cout << str1 << " is not " << str2 << "\n";
if (str1.compare(6,5,"apple") == 0)
cout << "still, " << str1 << " is an apple\n";
if (str2.compare(str2.size()-5,5,"apple") == 0)
cout << "and " << str2 << " is also an apple\n";
if (str1.compare(6,5,str2,4,5) == 0)
cout << "therefore, both are apples\n";
return 0;
}
I got it from http://www.cplusplus.com/reference/string/string/compare/
Hope google work !!
But use == operator like
s1 == s2 would also work good