How can I read from memory just like from a file using wistream?
Asked Answered
M

3

3

In my previous question I asked how to read from a memory just as from a file. Because my whole file was in memory I wanted to read it similarly.

I found answer to my question but actually I need to read lines as a wstring. With file I can do this:

wifstream file;
wstring line2;

file.open("C:\\Users\\Mariusz\\Desktop\\zasoby.txt");
if(file.is_open())
{
    while(file.good())
    {
        getline(file,line2);
        wcout << line2 << endl;
    }
}   
file.close();

Even if the file is in ASCII.

Right now I'm simply changing my string line to wstring with a function from this answer. However, I think if there is a way to treat this chunk of memory just like a wistream it would be a faster solution to get this lines as wstrings. And I need this to be fast.

So anybody know how to treat this chunk of memory as a wistream?

Maladroit answered 4/12, 2010 at 14:9 Comment(0)
V
1

I assume that your data is already converted into the desired encoding (see @detunized answer).

Using my answer to your previous question the conversion is straight forward:

namespace io = boost::iostreams;

io::filtering_wistream in;
in.push(warray_source(array, arraySize));

If you insist on not using boost then the conversion goes as follows (still straight forward):

class membuf : public wstreambuf // <- !!!HERE!!!
{
public:
    membuf(wchar_t* p, size_t n) { // <- !!!HERE!!!
        setg(p, p, p + n);
    }
};

int main()
{
    wchar_t buffer[] = L"Hello World!\nThis is next line\nThe last line";  
    membuf mb(buffer, sizeof(buffer)/sizeof(buffer[0]));

    wistream istr(&mb);
    wstring line;
    while(getline(istr, line))
    {
        wcout << L"line:[" << line << L"]" << endl;
    }
}

Also consider this for why use plain char UTF-8 streams.

Vershen answered 10/12, 2010 at 9:55 Comment(0)
G
1

You cannot treat ASCII string as a UNICODE string, since the characters they contain have different sizes. So you would have to do some kind of conversion to a temporary buffer and then use that piece of memory as an input buffer for your stream. This is what you're doing right now.

Gusman answered 4/12, 2010 at 14:15 Comment(3)
But I can use wifstream on ASCII file and load lines in wstring. I would say it's a conversion 'on the fly'. I mean I could this read ASCII file with ifstream and then convert strings to wstrings but I guess it's faster and easier to simply use wifstream.Maladroit
wifstream uses codecvt behind the scenes to do the conversion. It seems stringstream doesn't know how to do that. That it does it for you on the fly doesn't mean that it's faster. It does it on character per character basis and there's probably some overhead involved. It should be faster to convert everything in bulk.Gusman
One note on performance. Don't guess it. If you think it might be slower then profile it. It's possible that the difference is negligible and it wasn't worth putting all that time into figuring out the most perfect solution. First settle for what works and then fix what causes problems.Gusman
V
1

I assume that your data is already converted into the desired encoding (see @detunized answer).

Using my answer to your previous question the conversion is straight forward:

namespace io = boost::iostreams;

io::filtering_wistream in;
in.push(warray_source(array, arraySize));

If you insist on not using boost then the conversion goes as follows (still straight forward):

class membuf : public wstreambuf // <- !!!HERE!!!
{
public:
    membuf(wchar_t* p, size_t n) { // <- !!!HERE!!!
        setg(p, p, p + n);
    }
};

int main()
{
    wchar_t buffer[] = L"Hello World!\nThis is next line\nThe last line";  
    membuf mb(buffer, sizeof(buffer)/sizeof(buffer[0]));

    wistream istr(&mb);
    wstring line;
    while(getline(istr, line))
    {
        wcout << L"line:[" << line << L"]" << endl;
    }
}

Also consider this for why use plain char UTF-8 streams.

Vershen answered 10/12, 2010 at 9:55 Comment(0)
C
0

It should be obvious that if you have string, istream, and istringstream, therefore you also have wstring, wistream, and wistringstream.

Both istringstream and wistringstream are just specialization of the template class basic_istringstream for char and wchar respectively.

Cambrian answered 4/12, 2010 at 14:27 Comment(1)
I know that but it gives me nothing. Putting 'w' in front of every istream, string in this (https://mcmap.net/q/57527/-how-can-i-read-from-memory-just-like-from-a-file-using-iostream) code. Doesn't work.Maladroit

© 2022 - 2024 — McMap. All rights reserved.