Archived

This forum has been archived. Please start a new discussion on GitHub.

Chars to Ice::Byte

Hi!

Mark and Michi, thanks for the replies you gave on my other threads. I have a better understanding now, and it works.

I have another question, which I think is caused by my poor grasp of C++:

A declaration like sequence<byte> FileBlock; is mapped to typedef ::std::vector< ::Ice::Byte> FileBlock;

An operation like FileBlock getFile(string path, int pos, int size); will then have to return such a vector as mentioned above.

However, when implementing the operation I will call a fstream function like get(buffer, noOfBytes) to read a chunk of a file. buffer in this context is typically a char[bufferSize]. So I'll have my data in a char array, but I have to return a vector<Ice::Byte>.

I haven't tried yet, but I think I can iterate through the char array and copy each byte to the vector, but touching each byte like this will introduce an awfull delay for large files.

I'm sure there is a really smart way of doing this conversion (or even avoiding it), would you care to tell me how it can be done?

Thanks,
Catalin

Comments

  • Don't iterate, this would be very inefficient! With an ifstream, do:
    file.seekg(pos);
    if(!file)
    {
         // Error, cannot seek position...
    }
    bytes.resize(num);
    bytes.read(reinterpret_cast<char*>(&bytes[0]), bytes.size());
    
    This assumes that "file" is an ifstream, and "bytes" is a ByteSeq.
  • Thanks Marc!

    I looked into a lot of ICE source code, but I can not find what I have to #include in order to be allowed to use ByteSeq.

    Secondly, by looking how reinterpret_cast(...) is used, for instance in src/IcePatch/Util.cpp, I wonder whether ByteSeq is a typedef for 'vector<Ice::Byte>'.

    Can I return a ByteSeq in a function which is supposed to return a vector<Ice::Byte>?

    Thanks,
    Catalin
  • Yes, in my example, I assumed that ByteSeq is defined in slice as:
    sequence<byte> ByteSeq
    

    Which in C++ makes ByteSeq a typedef for vector<Ice::Byte>.

    Ice has one predefined ByteSeq in the namespace Ice, in case you don't want to define ByteSeq yourself. See slice/Ice/BuiltinSequences.ice.
  • My code

    #include <Ice/Ice.h>
    #include <dacapo.h>
    #include <FileTransfer.h>

    #include <fstream>
    #include <ios>
    #include <iostream>


    using namespace std;
    using namespace Ice;

    ....

    ByteSeq bytes;
    bytes.resize(blockSize);
    bytes.read(reinterpret_cast<char*>(&bytes[0]), bytes.size());


    does not compile because read is undefined. (Server.cpp:52: error: `read' undeclared (first use this function))

    Strangely enough resize is defined. I would expect these two functions to be declared and/or implemented in the same place.

    I see that resize and read are called together five times in src/IcePatch/Util.cpp, but I have no idea why they both are available there but not in my code? Missing #includes? Using other namespaces?

    Catalin
  • Sorry, I made a typo. It should of course be:
    bytes.resize(blockSize);
    file.read(reinterpret_cast<char*>(&bytes[0]), bytes.size()); 
    

    read() is a function on the ifstream.
  • Yea, I just realized that. (before realizing it I was really curious how on earth can we call methods on a ByteSeq, when it is not declared as an Slice interface, but only as a type.)

    resize is a vector function, and, as you said, read is a ifstream function.

    Sorry for bothering you so much.

    Catalin