Temporären Binärstream schreiben/lesen



  • > Wer sagt, dass ich einen formatierten Stream benutzen möchte?

    Du, denn du willst operator <<() und operator >>() benutzen. Natürlich kann man auch unformatiert mit diesen Operatoren arbeiten, aber dafür wurden sie und das ganze Manipulator-Konzept nicht erfunden.
    Die ganze Geschichte kostet dich einfach nur eine Kopie mehr als ein gewöhnliches Copy. Wie auch immer, mit einigen Boost-Libraries kann man etwas vergleichbares ohne zusätzliche Kopien zaubern: http://stackoverflow.com/questions/2079912/simpler-way-to-create-a-c-memorystream-from-char-size-t-without-copying-t



  • drakon schrieb:

    Wer sagt, dass ich einen formatierten Stream benutzen möchte?

    Es geht darum Code zu testen, der die Streaming Operatoren dafür benutzt und jetzt brauche ich einen temporären binären Stream, wo ich die Objekte rein und wieder raus streamen kann. Ich habe schon meine Gründe, warum ich die Bedingungen oben hingeschrieben habe..

    Ein stringstream mit ios_base::bin tuts nicht (tuts bestimmt nicht, aber zur Sicherheit frage ich nach)?



  • ich glaub nicht das es bei stringstreams das binary flag gibt.
    was ich mir aber vorstellen koennte, ist das man eventuell ein eigenes facet erstellen koennte.



  • Meep Meep schrieb:

    ich glaub nicht das es bei stringstreams das binary flag gibt.

    Laut der C++-Referenz schon, und ich liefer auch hoffentlich gleich den Standard.



  • Sone schrieb:

    Meep Meep schrieb:

    ich glaub nicht das es bei stringstreams das binary flag gibt.

    Laut der C++-Referenz schon, und ich liefer auch hoffentlich gleich den Standard.

    Nope. Der Standard sagt dazu soweit ich sehen kann überhaupt nichts, also nehme ich zurecht an das es geht.

    Warten wir ab was Drakon dazu sagt.



  • hab mal getestet

    int i = 12;
       short z = 110;
       std::stringstream stream(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
       stream << i << z << "test";
    

    im speicher steht dann:

    12110test
    

    binary hat wohl nur den effekt das keine interne konvertierung statt findet.



  • Genau. Habe ich auch schon ausprobiert gehabt. Geht leider mit stringstream nicht.

    So wies aussieht könnte boost.serialization doch funktionieren, wenn man da den ganzen Overhead rausnehmen kann.

    Hatte eben noch im Kopf, dass es auch einfacher (mit reinen Standardmitteln) geht.
    Hat nicht mal sogar hier jemand so einen stream gebaut?



  • drakon schrieb:

    Hat nicht mal sogar hier jemand so einen stream gebaut?

    Gut möglich. Aber finde das erstmal wieder.



  • Ah. Habs gefunden. Der Beitrag ist mir noch irgendwie im Kopf rumgeschwebt:
    http://www.c-plusplus.net/forum/235776

    @Meep Meep: Dir hätte dein Code wohl doch auch irgendwie bekannt vorkommen sollen. ^^

    Oh, gerade gesehen, dass es anscheinend noch vor demjenigen Thread etwas gegeben hat. Naja, wie auch immer. Scheint ja so, dass man das selbst machen muss oder vielleicht bringt man ja boost.serialization dazu das zu machen.

    Danke auf jeden Fall für die Antworten!



  • also mit nem facet funktionierts. hab folgendes gemacht:

    struct binary_num_put : std::num_put<char> 
    {
       iter_type do_put(iter_type s, std::ios_base& f, char_type fill, long v) const 
       { 
          char *p = reinterpret_cast<char*>(&v);
          *s = p[0];
          ++s;
          *s = p[1];
          ++s;
          *s = p[2];
          ++s;
          *s = p[3];
          ++s;
          return s;
       } 
    
       iter_type do_put(iter_type s, std::ios_base& f, char_type fill, unsigned long v) const 
       { 
          char *p = reinterpret_cast<char*>(&v);
          *s = p[0];
          ++s;
          *s = p[1];
          ++s;
          *s = p[2];
          ++s;
          *s = p[3];
          ++s;
          return s;
       } 
    };
    
    int main(int param_count, const char **params)
    {
       long i = 12;
    
       std::stringstream stream(std::stringstream::in | std::stringstream::out | std::stringstream::binary);
    
       stream.imbue(std::locale(std::locale(),new binary_num_put));
    
       stream <<  i << "test";
    
       std::ofstream datei("test.bin");
       datei.write(stream.str().c_str(), stream.str().size());
    
       return 0;
    }
    

    in der datei hab ich dann

    0C 00 00 00 74 65 73 74
    

    drinnen (mit nem hexeditor angesehen).



  • leider zu frueh gefreut.
    wie es aussieht gibt esin der tsd::num_put keine uberladung fuer z.b short.
    da wird dann die ueberladung fuer long aufgeruden. dadurch stimmt dann aber die anzahl der geschriebenen bytes nicht mehr. short hat ja nur 2 bytes oder ? (32 bit).
    mal gucken ob man put_num komplett ersetzen kann.

    Meep Meep



  • Wieso klappt das jetzt nicht, indem man operator<<, operator>> für die eigenen Klasse mit write und read überlädt? Das habe ich nicht verstanden. Oder soll das Ding für alle, auch nativen Typen funktionieren?



  • Irgendwie blick ich deinen Code nicht durch. Für was brauchst du denn f und fill in do_put() ? Du reservierst Speicher für binary_num_put . Wo ist der dazugehörige delete ? Und warum nimmst du keine Templates?



  • [Rewind] schrieb:

    Irgendwie blick ich deinen Code nicht durch. Für was brauchst du denn f und fill in do_put() ?

    Damit er die Methode überschreibt.

    Du reservierst Speicher für binary_num_put. Wo ist der dazugehörige delete ?

    Wird vom locale übernommen.

    Und warum nimmst du keine Templates?

    Wofür?


Anmelden zum Antworten