Changeset 1366 for trunk


Ignore:
Timestamp:
Mar 27, 2009, 4:54:09 PM (15 years ago)
Author:
gah
Message:

Begin reorganizing Rappture C++ API, starting with the use of
Rappture::Outcome.

Instead of returning an Outcome and expecting every routine to
save it, pass it as a reference. Let's strip it down to what's
needed right now and add back functionality as required.

Right now too many return values are ignored in the rappture library.
We need to check all results and return the error messages via
the Outcome. At the topmost level where is touches the developer
API we can drop the error checking or turn it on via an environment
variable.

Example. Not enough checks are made for memory allocation failure.
If the application is running on an over-committed server memory
allocation errors will be silently passed on. It's okay to be
fault tolerant where possible, but if we fail to check in the internal
library functions, it's too late.

--gah

Location:
trunk/src/core
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/RpBuffer.cc

    r1051 r1366  
    1212 */
    1313
    14 #include "RpBuffer.h"
    15 
    16 #include "zlib.h"
     14#include <assert.h>
     15#include <errno.h>
     16#include <stdio.h>
     17#include <sys/types.h>
     18#include <sys/stat.h>
     19#include <unistd.h>
     20#include <fstream>
     21#include <zlib.h>
    1722#include "b64/encode.h"
    1823#include "b64/decode.h"
    19 #include <fstream>
    20 #include <assert.h>
    21 
    22 #ifdef __cplusplus
    23     extern "C" {
    24 #endif // ifdef __cplusplus
    25 
    26 using namespace Rappture;
     24#include "RpBuffer.h"
     25
     26namespace Rappture {
    2727
    2828/**
     
    110110
    111111
    112 Outcome
    113 Buffer::load (const char* filePath)
    114 {
    115     Outcome status;
    116     std::ifstream::pos_type size = 0;
    117     std::ifstream inFile;
    118     char* memblock = NULL;
    119 
    120 
    121     inFile.open(filePath, std::ios::in | std::ios::ate | std::ios::binary);
    122     if (!inFile.is_open()) {
    123         status.error("error while opening file");
    124         status.addContext("Rappture::Buffer::load()");
    125         return status;
    126     }
    127 
    128     size = inFile.tellg();
     112bool
     113Buffer::load (Outcome &status, const char* filePath)
     114{
     115    status.addContext("Rappture::Buffer::load()");
     116
     117    FILE *f;
     118    f = fopen(filePath, "rb");
     119    if (f == NULL) {
     120        status.addError("can't open \"%s\": %s", filePath, strerror(errno));
     121        return false;
     122    }
     123    struct stat stat;
     124    if (fstat(fileno(f), &stat) < 0) {
     125        status.addError("can't stat \"%s\": %s", filePath, strerror(errno));
     126        return false;
     127    }   
     128    off_t size;
     129    size = stat.st_size;
     130    char* memblock;
    129131    memblock = new char [size];
    130132    if (memblock == NULL) {
    131         status.error("error while allocating memory");
    132         status.addContext("Rappture::Buffer::load()");
    133         inFile.close();
    134         return status;
    135     }
    136 
    137     inFile.seekg(0,std::ios::beg);
    138     inFile.read(memblock,size);
    139 
    140     // save data in buffer object.
    141     append(memblock,size);
    142 
    143     // close files, free memory
    144     inFile.close();
     133        status.addError("can't allocate %d bytes for file \"%s\": %s",
     134                        size, filePath, strerror(errno));
     135        fclose(f);
     136        return false;
     137    }
     138
     139    // FIXME: better yet, create an "extend" method in the buffer and returns
     140    //       the address of the char buffer so I can read the data directly
     141    //       into the buffer.  This eliminates memory new/copy/delete ops.
     142
     143    size_t nRead;
     144    nRead = fread(memblock, sizeof(char), size, f);
     145    fclose(f);                  // Close the file.
     146
     147    if (nRead != (size_t)size) {
     148        status.addError("can't read %d bytes from \"%s\": %s", size, filePath,
     149                        strerror(errno));
     150        return false;
     151    }   
     152
     153    int nBytes;
     154    nBytes = append(memblock, size);
    145155    delete [] memblock;
    146     memblock = NULL;
    147 
    148     // exit nicely
    149     return status;
    150 }
    151 
    152 
    153 Outcome
    154 Buffer::dump (const char* filePath)
    155 {
    156     Outcome status;
    157     std::ofstream outFile;
    158 
    159     outFile.open(filePath, std::ios::out|std::ios::trunc|std::ios::binary);
    160     if (!outFile.is_open()) {
    161         status.error("error while opening file");
    162         status.addContext("Rappture::Buffer::dump()");
    163         return status;
    164     }
    165 
    166     outFile.write(bytes(),size());
    167     outFile.close();
    168 
    169     // exit nicely
    170     return status;
    171 }
    172 
    173 
    174 Outcome
    175 Buffer::encode (unsigned int compress, unsigned int base64)
    176 {
    177     Outcome err;
     156
     157    if (nBytes != size) {
     158        status.addError("can't append %d bytes from \"%s\" to buffer: %s",
     159                size, filePath, strerror(errno));
     160        return false;
     161    }   
     162    return true;
     163}
     164
     165
     166bool
     167Buffer::dump (Outcome &status, const char* filePath)
     168{
     169    status.addContext("Rappture::Buffer::dump()");
     170
     171    FILE *f;
     172    f = fopen(filePath, "wb");
     173    if (f != NULL) {
     174        status.addError("can't open \"%s\": %s\n", filePath, strerror(errno));
     175        return false;
     176    }
     177    ssize_t nWritten;
     178    nWritten = fwrite(bytes(), size(), sizeof(char), f);
     179    fclose(f);                  // Close the file.
     180   
     181    if (nWritten != (ssize_t)size()) {
     182        status.addError("can't write %d bytes to \"%s\": %s\n", size(),
     183                        filePath, strerror(errno));
     184        return false;
     185    }
     186    return true;
     187}
     188
     189
     190bool
     191Buffer::encode (Outcome &err, bool compress, bool base64)
     192{
    178193    SimpleCharBuffer bin;
    179194    SimpleCharBuffer bout;
    180195
    181     if ((base64 == 0) && (compress == 0)) {
    182         return err;
    183     }
    184 
    185196    err.addContext("Rappture::Buffer::encode()");
     197    if ((!base64) && (!compress)) {
     198        err.addError("invalid parameters: both base64 and compress are false");
     199        return false;
     200    }
     201
    186202    rewind();
    187203
    188     if (compress != 0) {
    189         do_compress(err,*this,bout);
    190         if (err) {
    191             return err;
    192         }
    193     }
    194 
    195     if (base64 != 0) {
    196         if (compress != 0) {
     204    if (compress) {
     205        if (!do_compress(err, *this, bout)) {
     206            return false;
     207        }
     208    }
     209
     210    if (base64) {
     211        if (compress) {
    197212            bin.move(bout);
    198             do_base64_enc(err,bin,bout);
     213            if (!do_base64_enc(err, bin, bout)) {
     214                return false;
     215            }
    199216        }
    200217        else {
    201             do_base64_enc(err,*this,bout);
    202         }
    203     }
    204 
    205     if (!err) {
    206         // write the encoded data to the internal buffer
    207         move(bout);
    208     }
    209 
    210     return err;
    211 }
    212 
    213 
    214 Outcome
    215 Buffer::decode (unsigned int decompress, unsigned int base64)
    216 {
    217     Outcome err;
     218            if (!do_base64_enc(err, *this, bout)) {
     219                return false;
     220            }
     221        }
     222    }
     223    // write the encoded data to the internal buffer
     224    move(bout);
     225    return true;
     226}
     227
     228
     229bool
     230Buffer::decode (Outcome &err, bool decompress, bool base64)
     231{
    218232    SimpleCharBuffer bin;
    219233    SimpleCharBuffer bout;
    220234
    221     if ((base64 == 0) && (decompress == 0)) {
    222         return err;
    223     }
    224 
    225235    err.addContext("Rappture::Buffer::decode()");
     236    if ((!base64) && (!decompress)) {
     237        err.addError("invalid parameters: both base64 and compress are false");
     238        return false;
     239    }
     240
    226241    rewind();
    227242
    228     if (base64 != 0) {
    229         do_base64_dec(err,*this,bout);
    230         if (err) {
    231             return err;
    232         }
    233     }
    234 
    235     if (decompress != 0) {
     243    if (base64) {
     244        if (!do_base64_dec(err,*this, bout)) {
     245            return false;
     246        }
     247    }
     248    if (decompress) {
    236249        if (base64) {
    237250            bin.move(bout);
    238             do_decompress(err,bin,bout);
    239         }
    240         else {
    241             do_decompress(err,*this,bout);
    242         }
    243     }
    244 
    245     if (!err) {
    246         // write the decoded data to the internal buffer
    247         move(bout);
    248     }
    249 
    250     return err;
    251 }
    252 
    253 
    254 void
    255 Buffer::do_compress(    Outcome& status,
    256                         SimpleCharBuffer& bin,
    257                         SimpleCharBuffer& bout  )
     251            if (!do_decompress(err, bin, bout)) {
     252                return false;
     253            }
     254        } else {
     255            if (!do_decompress(err, *this, bout)) {
     256                return false;
     257            }
     258        }
     259    }
     260    move(bout);
     261    return true;
     262}
     263
     264
     265bool
     266Buffer::do_compress(Outcome& status, SimpleCharBuffer& bin,
     267                    SimpleCharBuffer& bout)
    258268{
    259269    int ret=0, flush=0;
     
    271281    strm.opaque = Z_NULL;
    272282
     283    status.addContext("Rappture::Buffer::do_compress()");
     284
    273285    ret = deflateInit2( &strm, _level, Z_DEFLATED,
    274286                        _windowBits+_compressionType,
     
    276288
    277289    if (ret != Z_OK) {
    278         status.error("error while initializing zlib stream object");
    279         status.addContext("Rappture::Buffer::do_compress()");
    280         return;
     290        status.addError("error while initializing zlib stream object");
     291        return false;
    281292    }
    282293
     
    287298            (void)deflateEnd(&strm);
    288299            // return Z_ERRNO;
    289             status.error("error while compressing");
    290             status.addContext("Rappture::Buffer::do_compress()");
    291             return;
     300            status.addError("error while compressing");
     301            return false;
    292302        }
    293303        flush = bin.eof() ? Z_FINISH : Z_NO_FLUSH;
     
    307317                bout.clear();
    308318                // return Z_ERRNO;
    309                 status.error("error writing compressed data to temp buffer");
    310                 status.addContext("Rappture::Buffer::do_compress()");
    311                 return;
     319                status.addError("error writing compressed data to temp buffer");
     320                return false;
    312321            }
    313322
     
    323332    (void)deflateEnd(&strm);
    324333    // return Z_OK;
    325     return;
    326 }
    327 
    328 void
    329 Buffer::do_decompress(  Outcome& status,
    330                         SimpleCharBuffer& bin,
    331                         SimpleCharBuffer& bout  )
     334    return true;
     335}
     336
     337bool
     338Buffer::do_decompress(Outcome& status, SimpleCharBuffer& bin,
     339                      SimpleCharBuffer& bout)
    332340{
    333341    int ret;
     
    339347
    340348    int bytesWritten = 0;
     349
     350    status.addContext("Rappture::Buffer::do_decompress()");
    341351
    342352    /* allocate inflate state */
     
    348358    ret = inflateInit2(&strm,_windowBits+_compressionType);
    349359    if (ret != Z_OK) {
    350         status.error("error while initializing zlib stream object");
    351         status.addContext("Rappture::Buffer::do_decompress()");
    352         // return status;
    353         return;
     360        status.addError("error while initializing zlib stream object");
     361        return false;
    354362    }
    355363
     
    360368            (void)inflateEnd(&strm);
    361369            // return Z_ERRNO;
    362             status.error("error while compressing");
    363             status.addContext("Rappture::Buffer::do_decompress()");
    364             // return status;
    365             return;
     370            status.addError("error while compressing");
     371            return false;
    366372        }
    367373        if (strm.avail_in == 0)
     
    381387                (void)inflateEnd(&strm);
    382388                bout.clear();
    383                 status.error("memory error while inflating data");
    384                 status.addContext("Rappture::Buffer::do_decompress()");
    385                 return;
     389                status.addError("memory error while inflating data");
     390                return false;
    386391            }
    387392            have = CHUNK - strm.avail_out;
     
    391396                bout.clear();
    392397                // return Z_ERRNO;
    393                 status.error("error writing compressed data to temp buffer");
    394                 status.addContext("Rappture::Buffer::do_decompress()");
    395                 return;
     398                status.addError("error writing compressed data to temp buffer");
     399                return false;
    396400            }
    397401        } while (strm.avail_out == 0);
     
    403407    (void)inflateEnd(&strm);
    404408    // return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
    405     return;
    406 }
    407 
    408 
    409 void
    410 Buffer::do_base64_enc(  Outcome& status,
    411                         const SimpleCharBuffer& bin,
    412                         SimpleCharBuffer& bout )
     409    return true;
     410}
     411
     412
     413bool
     414Buffer::do_base64_enc(Outcome& status, const SimpleCharBuffer& bin,
     415                      SimpleCharBuffer& bout )
    413416{
    414417    int tBufSize = 0;
     
    424427    delete [] tBuf;
    425428
    426     return;
    427 }
    428 
    429 
    430 void
    431 Buffer::do_base64_dec(  Outcome& status,
    432                         const SimpleCharBuffer& bin,
    433                         SimpleCharBuffer& bout )
     429    return true;
     430}
     431
     432
     433bool
     434Buffer::do_base64_dec(Outcome& status, const SimpleCharBuffer& bin,
     435                      SimpleCharBuffer& bout )
    434436{
    435437    int tBufSize = 0;
     
    444446    delete [] tBuf;
    445447
    446     return;
    447 }
    448 
    449 #ifdef __cplusplus
    450     }
    451 #endif // ifdef __cplusplus
    452 
     448    return true;
     449}
     450
     451
     452}
     453
     454
     455
  • trunk/src/core/RpBuffer.h

    r1051 r1366  
    4848    virtual ~Buffer();
    4949
    50     Outcome load(const char* filePath);
    51     Outcome dump(const char* filePath);
    52     Outcome encode(unsigned int compress=1, unsigned int base64=1);
    53     Outcome decode(unsigned int decompress=1, unsigned int base64=1);
     50    bool load(Outcome &result, const char* filePath);
     51    bool dump(Outcome &result, const char* filePath);
     52    bool encode(Outcome &result, bool compress=true, bool base64=true);
     53    bool decode(Outcome &result, bool decompress=true, bool base64=true);
    5454
    5555protected:
     
    6565
    6666    enum { CHUNK = 4096 };
    67 
    68     void do_compress(   Outcome& status,
    69                         SimpleCharBuffer& bin,
     67   
     68    bool do_compress(Outcome& status, SimpleCharBuffer& bin,
     69                     SimpleCharBuffer& bout  );
     70    bool do_decompress( Outcome& status, SimpleCharBuffer& bin,
    7071                        SimpleCharBuffer& bout  );
    71     void do_decompress( Outcome& status,
    72                         SimpleCharBuffer& bin,
    73                         SimpleCharBuffer& bout  );
    74     void do_base64_enc( Outcome& status,
    75                         const SimpleCharBuffer& bin,
    76                         SimpleCharBuffer& bout  );
    77     void do_base64_dec( Outcome& status,
    78                         const SimpleCharBuffer& bin,
    79                         SimpleCharBuffer& bout  );
     72    bool do_base64_enc(Outcome& status, const SimpleCharBuffer& bin,
     73                       SimpleCharBuffer& bout  );
     74    bool do_base64_dec(Outcome& status, const SimpleCharBuffer& bin,
     75                       SimpleCharBuffer& bout  );
    8076};
    8177
  • trunk/src/core/RpBufferCInterface.cc

    r1018 r1366  
    191191    }
    192192
    193     s = ((Rappture::Buffer*)buf->_buf)->load(filename);
     193    ((Rappture::Buffer*)buf->_buf)->load(s, filename);
    194194    RpOutcomeToCOutcome(&s,&status);
    195195    return status;
     
    202202    RapptureOutcome status;
    203203
    204     RapptureOutcomeInit(&status);
    205 
    206     if (buf == NULL) {
    207         s.error("invalid parameter: buf == NULL");
    208         s.addContext("while in RapptureBufferLoad()");
    209         RpOutcomeToCOutcome(&s,&status);
    210         return status;
    211     }
    212 
    213     if (buf->_buf == NULL) {
    214         s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
    215         s.addContext("while in RapptureBufferLoad()");
    216         RpOutcomeToCOutcome(&s,&status);
    217         return status;
    218     }
    219 
    220     s = ((Rappture::Buffer*)buf->_buf)->dump(filename);
    221     RpOutcomeToCOutcome(&s,&status);
    222     return status;
    223 }
    224 
    225 RapptureOutcome
    226 RapptureBufferEncode(   RapptureBuffer* buf,
    227                         unsigned int compress,
    228                         unsigned int base64 )
    229 {
    230     Rappture::Outcome s;
    231     RapptureOutcome status;
    232 
    233     RapptureOutcomeInit(&status);
    234 
    235     if (buf == NULL) {
    236         s.error("invalid parameter: buf == NULL");
    237         s.addContext("while in RapptureBufferLoad()");
    238         RpOutcomeToCOutcome(&s,&status);
    239         return status;
    240     }
    241 
    242     if (buf->_buf == NULL) {
    243         s.addContext("while in RapptureBufferLoad()");
    244         s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
    245         RpOutcomeToCOutcome(&s,&status);
    246         return status;
    247     }
    248 
    249     s = ((Rappture::Buffer*)buf->_buf)->encode(compress,base64);
    250     RpOutcomeToCOutcome(&s,&status);
    251     return status;
    252 }
    253 
    254 RapptureOutcome
    255 RapptureBufferDecode(   RapptureBuffer* buf,
    256                         unsigned int decompress,
    257                         unsigned int base64 )
    258 {
    259     Rappture::Outcome s;
    260     RapptureOutcome status;
    261 
    262     RapptureOutcomeInit(&status);
    263 
    264     if (buf == NULL) {
    265         s.error("invalid parameter: buf == NULL");
    266         s.addContext("while in RapptureBufferLoad()");
    267         RpOutcomeToCOutcome(&s,&status);
    268         return status;
    269     }
    270 
    271     if (buf->_buf == NULL) {
    272         s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
    273         s.addContext("while in RapptureBufferLoad()");
    274         RpOutcomeToCOutcome(&s,&status);
    275         return status;
    276     }
    277 
    278     s = ((Rappture::Buffer*)buf->_buf)->decode(decompress,base64);
     204    s.addContext("while in RapptureBufferLoad()");
     205    RapptureOutcomeInit(&status);
     206
     207    if (buf == NULL) {
     208        s.error("invalid parameter: buf == NULL");
     209        RpOutcomeToCOutcome(&s,&status);
     210        return status;
     211    }
     212
     213    if (buf->_buf == NULL) {
     214        s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
     215        RpOutcomeToCOutcome(&s,&status);
     216        return status;
     217    }
     218
     219    ((Rappture::Buffer*)buf->_buf)->dump(s, filename);
     220    RpOutcomeToCOutcome(&s,&status);
     221    return status;
     222}
     223
     224RapptureOutcome
     225RapptureBufferEncode(RapptureBuffer* buf, int compress, int base64)
     226{
     227    Rappture::Outcome s;
     228    RapptureOutcome status;
     229
     230    RapptureOutcomeInit(&status);
     231    s.addContext("while in RapptureBufferLoad()");
     232    if (buf == NULL) {
     233        s.error("invalid parameter: buf == NULL");
     234        RpOutcomeToCOutcome(&s,&status);
     235        return status;
     236    }
     237
     238    if (buf->_buf == NULL) {
     239        s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
     240        RpOutcomeToCOutcome(&s, &status);
     241        return status;
     242    }
     243    ((Rappture::Buffer*)buf->_buf)->encode(s, compress, base64);
     244    RpOutcomeToCOutcome(&s,&status);
     245    return status;
     246}
     247
     248RapptureOutcome
     249RapptureBufferDecode(RapptureBuffer* buf, int decompress, int base64 )
     250{
     251    Rappture::Outcome s;
     252    RapptureOutcome status;
     253
     254    RapptureOutcomeInit(&status);
     255
     256    if (buf == NULL) {
     257        s.error("invalid parameter: buf == NULL");
     258        s.addContext("while in RapptureBufferLoad()");
     259        RpOutcomeToCOutcome(&s,&status);
     260        return status;
     261    }
     262
     263    if (buf->_buf == NULL) {
     264        s.error("uninitialized parameter: buf, did you call RapptureBufferInit()?");
     265        s.addContext("while in RapptureBufferLoad()");
     266        RpOutcomeToCOutcome(&s,&status);
     267        return status;
     268    }
     269
     270    ((Rappture::Buffer*)buf->_buf)->decode(s, decompress, base64);
    279271    RpOutcomeToCOutcome(&s,&status);
    280272    return status;
  • trunk/src/core/RpBufferCInterface.h

    r1018 r1366  
     1
    12/*
    23 * ----------------------------------------------------------------------
     
    3334    int (*tell)();
    3435    // void (*rewind);
    35     Outcome (*load)(const char*);
    36     Outcome (*dump)(const char*);
    37     Outcome (*encode)(unsigned int, unsigned int);
    38     Outcome (*decode)(unsigned int, unsigned int);
     36    bool (*load)(Outcome &result, const char*);
     37    bool (*dump)(Outcome &result, const char*);
     38    bool (*encode)(Outcome &result, bool, bool);
     39    bool (*decode)(Outcome &result, bool, bool);
    3940    */
    4041}RapptureBuffer;
     
    5152RapptureOutcome RapptureBufferLoad(RapptureBuffer* buf, const char* filename);
    5253RapptureOutcome RapptureBufferDump(RapptureBuffer* buf, const char* filename);
    53 RapptureOutcome RapptureBufferEncode(   RapptureBuffer* buf,
    54                                         unsigned int compress,
    55                                         unsigned int base64 );
    56 RapptureOutcome RapptureBufferDecode(   RapptureBuffer* buf,
    57                                         unsigned int decompress,
    58                                         unsigned int base64 );
     54RapptureOutcome RapptureBufferEncode(RapptureBuffer* buf, int compress,
     55        int base64 );
     56RapptureOutcome RapptureBufferDecode(RapptureBuffer* buf,
     57        int decompress, int base64 );
    5958
    6059#ifdef __cplusplus
  • trunk/src/core/RpBuffer_test.cc

    r1018 r1366  
    207207    Rappture::Outcome status1;
    208208    buffer1.append("abcdefghijklmnopqrstuvwxyz",26);
    209     status1 = buffer1.encode(true,false);
     209    buffer1.encode(status1, true, false);
    210210    bytesRead = buffer1.size();
    211211
     
    226226    Rappture::Outcome status2;
    227227    buffer2.append("abcdefghijklmnopqrstuvwxyz",26);
    228     status2 = buffer2.encode(false,true);
     228    buffer2.encode(status2, false, true);
    229229    bytesRead = buffer2.size();
    230230
     
    245245    Rappture::Outcome status3;
    246246    buffer3.append("abcdefghijklmnopqrstuvwxyz",26);
    247     status2 = buffer3.encode(true,true);
     247    buffer3.encode(status3, true, true);
    248248    bytesRead = buffer3.size();
    249249
     
    274274    Rappture::Outcome status1;
    275275    buffer1.append("abcdefghijklmnopqrstuvwxyz",26);
    276     status1 = buffer1.encode(true,false);
    277     status1 = buffer1.decode(true,false);
     276    buffer1.encode(status1, true, false);
     277    buffer1.decode(status1, true, false);
    278278    bytesRead = buffer1.size();
    279279
     
    294294    Rappture::Outcome status2;
    295295    buffer2.append("abcdefghijklmnopqrstuvwxyz",26);
    296     status2 = buffer2.encode(false,true);
    297     status2 = buffer2.decode(false,true);
     296    buffer2.encode(status2, false, true);
     297    buffer2.decode(status2, false, true);
    298298    bytesRead = buffer2.size();
    299299
     
    314314    Rappture::Outcome status3;
    315315    buffer3.append("abcdefghijklmnopqrstuvwxyz",26);
    316     status3 = buffer3.encode(true,true);
    317     status3 = buffer3.decode(true,true);
     316    buffer3.encode(status3, true, true);
     317    buffer3.decode(status3, true, true);
    318318    bytesRead = buffer3.size();
    319319
     
    338338    int tests = 0;
    339339
    340 
    341340    /* =========================================================== */
    342341    tests++;
     
    344343    Rappture::Buffer buffer1;
    345344    buffer1.append("abcdefghijklmnopqrstuvwxyz",26);
    346     buffer1.dump(filePath);
     345    Rappture::Outcome status1;
     346    buffer1.dump(status1, filePath);
    347347
    348348    std::ifstream inFile;
     
    391391    int tests = 0;
    392392
    393 
    394393    /* =========================================================== */
    395394    tests++;
     
    397396    Rappture::Buffer buffer1;
    398397    Rappture::Buffer buffer1out;
     398    Rappture::Outcome status1;
    399399    buffer1.append("abcdefghijklmnopqrstuvwxyz",26);
    400     buffer1.dump(filePath);
    401     buffer1out.load(filePath);
     400    buffer1.dump(status1, filePath);
     401    buffer1out.load(status1, filePath);
    402402    int size = buffer1out.size();
    403403    const char* b1bytes = buffer1.bytes();
     
    429429    Rappture::Buffer buffer2;
    430430    Rappture::Buffer buffer2out;
    431 
    432     buffer2.load(filePath1);
    433     buffer2.encode();
    434     buffer2.dump(filePath2);
    435 
    436     buffer2out.load(filePath2);
    437     buffer2out.decode();
    438     buffer2out.dump(filePath3);
     431    Rappture::Outcome status2;
     432    buffer2.load(status2, filePath1);
     433    buffer2.encode(status2);
     434    buffer2.dump(status2, filePath2);
     435
     436    buffer2out.load(status2, filePath2);
     437    buffer2out.decode(status2);
     438    buffer2out.dump(status2, filePath3);
    439439
    440440    buffer2.clear();
     
    483483    int tests = 0;
    484484
    485 
    486485    /* =========================================================== */
    487486    tests++;
     
    489488    const char* outFile = "out.dx.gz";
    490489    Rappture::Buffer buffer1;
    491     buffer1.load(inFile);
     490    Rappture::Outcome status1;
     491    buffer1.load(status1, inFile);
    492492
    493493    // compress, dont encode
    494     buffer1.encode(true,false);
     494    buffer1.encode(status1, true, false);
    495495    std::remove(outFile);
    496     buffer1.dump(outFile);
    497     buffer1.decode(true,false);
     496    buffer1.dump(status1, outFile);
     497    buffer1.decode(status1, true, false);
    498498
    499499    /*
  • trunk/src/core/RpEncode.cc

    r1264 r1366  
    1515#include <cstring>
    1616
    17 #ifdef __cplusplus
    18 extern "C" {
    19 #endif // ifdef __cplusplus
    20 
    21 using namespace Rappture::encoding;
    22 
    2317/**********************************************************************/
    2418// FUNCTION: Rappture::encoding::isbinary()
     
    3226
    3327int
    34 isbinary(const char* buf, int size)
     28Rappture::encoding::isbinary(const char* buf, int size)
    3529{
    3630    if (buf == NULL) {
     
    7064
    7165size_t
    72 isencoded(const char* buf, int size)
     66Rappture::encoding::isencoded(const char* buf, int size)
    7367{
    7468    size_t flags = 0;
     
    117111        }
    118112    }
    119 
    120113    return flags;
    121114}
     
    131124 */
    132125
    133 Rappture::Outcome
    134 encode (Rappture::Buffer& buf, size_t flags)
    135 {
    136 
    137     int compress              = 0;
    138     int base64                = 0;
    139     int addHeader             = 0;
    140     Rappture::Outcome err;
     126bool
     127Rappture::encoding::encode(Rappture::Outcome &err, Rappture::Buffer& buf,
     128        size_t flags)
     129{
    141130    Rappture::Buffer outData;
    142131
    143     if ((flags & RPENC_Z) == RPENC_Z ) {
    144         compress = 1;
    145     }
    146     if ((flags & RPENC_B64) == RPENC_B64 ) {
    147         base64 = 1;
    148     }
    149     if ((flags & RPENC_HDR) == RPENC_HDR ) {
    150         addHeader = 1;
    151     }
    152 
    153     outData.append(buf.bytes(),buf.size());
    154     err = outData.encode(compress,base64);
    155     if (!err) {
     132    bool compress, base64, addHeader;
     133    compress  = (flags & RPENC_Z);
     134    base64    = (flags & RPENC_B64);
     135    addHeader = (flags & RPENC_HDR);
     136
     137    if (outData.append(buf.bytes(), buf.size()) != (int)buf.size()) {
     138        err.addError("can't append %d bytes", buf.size());
     139        return false;
     140    }
     141    if (outData.encode(err, compress, base64)) {
    156142        buf.clear();
    157         if (addHeader == 1) {
    158             if ((compress == 1) && (base64 == 0)) {
    159                 buf.append("@@RP-ENC:z\n",11);
    160             }
    161             else if ((compress == 0) && (base64 == 1)) {
    162                 buf.append("@@RP-ENC:b64\n",13);
    163             }
    164             else if ((compress == 1) && (base64 == 1)) {
    165                 buf.append("@@RP-ENC:zb64\n",14);
    166             }
    167             else {
     143        if (addHeader) {
     144            if ((compress) && (!base64)) {
     145                buf.append("@@RP-ENC:z\n", 11);
     146            } else if ((!compress) && (base64)) {
     147                buf.append("@@RP-ENC:b64\n", 13);
     148            } else if ((compress) && (base64)) {
     149                buf.append("@@RP-ENC:zb64\n", 14);
     150            } else {
    168151                // do nothing
    169152            }
    170         }
    171         else {
     153        } else {
    172154            // do nothing
    173155        }
    174         buf.append(outData.bytes(),outData.size());
    175     }
    176 
    177     return err;
     156        if (buf.append(outData.bytes(),outData.size()) != (int)outData.size()) {
     157            err.addError("can't append %d bytes", outData.size());
     158            return false;
     159        }
     160    }
     161    return true;
    178162}
    179163
     
    190174 */
    191175
    192 Rappture::Outcome
    193 decode (Rappture::Buffer& buf, size_t flags)
    194 {
    195 
    196     int decompress            = 0;
    197     int base64                = 0;
    198     int checkHDR              = 0;
    199     Rappture::Outcome err;
     176bool
     177Rappture::encoding::decode(Rappture::Outcome &err, Rappture::Buffer& buf,
     178                           size_t flags)
     179{
    200180    Rappture::Buffer outData;
    201181
    202     if ((flags & RPENC_Z) == RPENC_Z ) {
    203         decompress = 1;
    204     }
    205     if ((flags & RPENC_B64) == RPENC_B64 ) {
    206         base64 = 1;
    207     }
    208     if ((flags & RPENC_HDR) == RPENC_HDR ) {
    209         checkHDR = 1;
    210     }
    211 
    212     if ((buf.size() > 11) && (strncmp(buf.bytes(),"@@RP-ENC:z\n",11) == 0)) {
    213         outData.append(buf.bytes()+11,buf.size()-11);
    214         if ( (checkHDR == 1) || ( (decompress == 0) && (base64 == 0) ) ) {
    215             decompress = 1;
    216             base64 = 0;
    217         }
    218     }
    219     else if ((buf.size() > 13) && (strncmp(buf.bytes(),"@@RP-ENC:b64\n",13) == 0)) {
    220         outData.append(buf.bytes()+13,buf.size()-13);
    221         if ( (checkHDR == 1) || ( (decompress == 0) && (base64 == 0) ) ) {
    222             decompress = 0;
    223             base64 = 1;
    224         }
    225     }
    226     else if ((buf.size() > 14) && (strncmp(buf.bytes(),"@@RP-ENC:zb64\n",14) == 0)) {
    227         outData.append(buf.bytes()+14,buf.size()-14);
    228         if ( (checkHDR == 1) || ( (decompress == 0) && (base64 == 0) ) ) {
    229             decompress = 1;
    230             base64 = 1;
    231         }
    232     }
    233     else {
    234         // no special recognized tags
    235         outData.append(buf.bytes(),buf.size());
    236     }
    237 
    238     err = outData.decode(decompress,base64);
    239     if (!err) {
    240         buf.move(outData);
    241     }
    242 
    243     return err;
    244 }
    245 
    246 #ifdef __cplusplus
    247 }
    248 #endif // ifdef __cplusplus
     182    bool decompress, base64, checkHDR;
     183    decompress = (flags & RPENC_Z);
     184    base64     = (flags & RPENC_B64);
     185    checkHDR   = (flags & RPENC_HDR);
     186
     187    off_t offset;
     188    if ((buf.size() > 11) && (strncmp(buf.bytes(),"@@RP-ENC:z\n", 11) == 0)) {
     189        offset = 11;
     190        if ((checkHDR) || ((!decompress) && (!base64))) {
     191            decompress = true;
     192            base64 = false;
     193        }
     194    } else if ((buf.size() > 13) &&
     195               (strncmp(buf.bytes(),"@@RP-ENC:b64\n",13) == 0)) {
     196        offset = 13;
     197        if ((checkHDR) || ((!decompress) && (!base64) )) {
     198            decompress = false;
     199            base64 = true;
     200        }
     201    } else if ((buf.size() > 14) &&
     202               (strncmp(buf.bytes(), "@@RP-ENC:zb64\n",14) == 0)) {
     203        offset = 14;
     204        if ((checkHDR) || ((!decompress) && (!base64))) {
     205            decompress = true;
     206            base64 = true;
     207        }
     208    } else {
     209        offset = 0;
     210    }
     211    int nBytes = buf.size() - offset;
     212    if (outData.append(buf.bytes() + offset, nBytes) != nBytes) {
     213        err.addError("can't append %d bytes to buffer", nBytes);
     214        return false;
     215    }
     216    if (!outData.decode(err, decompress, base64)) {
     217        return false;
     218    }
     219    buf.move(outData);
     220    return true;
     221}
     222
  • trunk/src/core/RpEncode.h

    r1264 r1366  
    1515#define RAPPTURE_ENCODE_H
    1616
     17#include <RpOutcome.h>
    1718#include <RpBuffer.h>
    18 #include <RpOutcome.h>
    1919
    20 #define RPENC_Z      1
    21 #define RPENC_B64    2
    22 #define RPENC_HDR    4
     20namespace Rappture {
     21namespace encoding {
    2322
    24 #ifdef __cplusplus
    25 extern "C" {
    26 namespace Rappture {
    27     namespace encoding {
    28 #endif // ifdef __cplusplus
     23#define RPENC_Z      (1<<0)
     24#define RPENC_B64    (1<<1)
     25#define RPENC_HDR    (1<<2)
    2926
    3027int isbinary(const char* buf, int size);
    3128size_t isencoded(const char* buf, int size);
    32 Rappture::Outcome encode (Rappture::Buffer& buf, size_t flags);
    33 Rappture::Outcome decode (Rappture::Buffer& buf, size_t flags);
     29bool encode(Rappture::Outcome &err, Rappture::Buffer& buf, size_t flags);
     30bool decode(Rappture::Outcome &err, Rappture::Buffer& buf, size_t flags);
    3431
    35 #ifdef __cplusplus
    36     } // namespace encoding
    37 } // namespace Rappture
    38 } // extern C
    39 #endif // ifdef __cplusplus
    40 
     32}
     33}
    4134#endif // RAPPTURE_ENCODE_H
  • trunk/src/core/RpEntityRef.cc

    r788 r1366  
    3939
    4040const char*
    41 EntityRef::decode (
    42     const char* value,
    43     unsigned int len
    44 )
     41EntityRef::decode (const char* value, unsigned int len)
    4542{
    4643    unsigned int pos = 0;
  • trunk/src/core/RpLibrary.cc

    r1264 r1366  
    15201520    Rappture::Buffer inData;
    15211521
     1522    status.addContext("RpLibrary::getString");
    15221523    if (!this->root) {
    15231524        // library doesn't exist, do nothing;
     
    15331534
    15341535    retCStr = scew_element_contents(retNode);
    1535 
    15361536    if (!retCStr) {
    15371537        return retStr;
    15381538    }
    1539 
    15401539    inData = Rappture::Buffer(retCStr);
    15411540
     
    15451544        // there is no reason to do entity translation
    15461545        // because base64 character set does not include xml entity chars
    1547         status &= Rappture::encoding::decode(inData,0);
    1548         status.addContext("RpLibrary::getSting");
     1546        if (!Rappture::encoding::decode(status, inData, 0)) {
     1547            return retStr;
     1548        }
    15491549        retStr = std::string(inData.bytes(),inData.size());
    15501550    } else {
    15511551        // check translateFlag to see if we need to translate entity refs
    15521552        if (translateFlag == RPLIB_TRANSLATE) {
    1553             translatedContents = ERTranslator.decode(inData.bytes(),inData.size());
     1553            translatedContents = ERTranslator.decode(inData.bytes(),
     1554                                                     inData.size());
    15541555            if (translatedContents == NULL) {
    15551556                // translation failed
    15561557                if (!status) {
    15571558                    status.error("Error while translating entity references");
    1558                     status.addContext("RpLibrary::getSting");
     1559                    return retStr;
    15591560                }
    15601561            } else {
     
    15651566        }
    15661567    }
    1567 
    15681568    inData.clear();
    1569 
    15701569    return retStr;
    15711570}
     
    17381737
    17391738RpLibrary&
    1740 RpLibrary::put (    std::string path,
    1741                     std::string value,
    1742                     std::string id,
    1743                     unsigned int append,
    1744                     unsigned int translateFlag)
     1739RpLibrary::put (std::string path, std::string value, std::string id,
     1740                unsigned int append, unsigned int translateFlag)
    17451741{
    17461742    Rappture::EntityRef ERTranslator;
     
    17501746    const char* translatedContents = NULL;
    17511747
     1748    status.addContext("RpLibrary::put() - putString");
     1749
    17521750    if (!this->root) {
    17531751        // library doesn't exist, do nothing;
    17541752        status.error("invalid library object");
    1755         status.addContext("RpLibrary::put() - putString");
    17561753        return *this;
    17571754    }
    17581755
    17591756    // check for binary data
    1760     if (Rappture::encoding::isbinary(value.c_str(),value.length()) != 0) {
    1761         putData(path,value.c_str(),value.length(),append);
    1762         status.addContext("RpLibrary::put() - putString");
     1757    // FIXME: I've already appended a NUL-byte of this assuming that
     1758    //        it's a ASCII string. This test must come before.
     1759    if (Rappture::encoding::isbinary(value.c_str(), value.length()) != 0) {
     1760        putData(path, value.c_str(), value.length(), append);
    17631761        return *this;
    17641762    }
    17651763
    1766     retNode = _find(path,CREATE_PATH);
    1767 
     1764    retNode = _find(path, CREATE_PATH);
    17681765    if (retNode == NULL) {
    17691766        // node not found, set error
    17701767        status.error("Error while searching for node: node not found");
    1771         status.addContext("RpLibrary::put() - putString");
    17721768        return *this;
    17731769    }
     
    17791775            if (!status) {
    17801776                status.error("Error while translating entity references");
     1777                return *this;
    17811778            }
    17821779        }
     
    17861783        }
    17871784    }
    1788 
    17891785    if (append == RPLIB_APPEND) {
    17901786        contents = scew_element_contents(retNode);
     
    17941790        }
    17951791    }
    1796 
    17971792    scew_element_set_contents(retNode,value.c_str());
    1798 
    1799     status.addContext("RpLibrary::put() - putString");
    18001793    return *this;
    18011794}
     
    18081801
    18091802RpLibrary&
    1810 RpLibrary::put (    std::string path,
    1811                     double value,
    1812                     std::string id,
    1813                     unsigned int append )
     1803RpLibrary::put (std::string path, double value, std::string id,
     1804                unsigned int append)
    18141805{
    18151806    std::stringstream valStr;
     
    19631954    size_t flags = 0;
    19641955
     1956    status.addContext("RpLibrary::putData()");
    19651957    if (!this->root) {
    19661958        // library doesn't exist, do nothing;
    19671959        return *this;
    19681960    }
    1969 
    19701961    retNode = _find(path,CREATE_PATH);
    19711962
    1972     if (retNode) {
    1973 
    1974         if (append == RPLIB_APPEND) {
    1975             if ( (contents = scew_element_contents(retNode)) ) {
    1976                 inData.append(contents);
    1977                 // base64 decode and un-gzip the data
    1978                 status &= Rappture::encoding::decode(inData,0);
    1979                 if (int(status) != 0) {
    1980                     status.addContext("RpLibrary::putData()");
    1981                     return *this;
    1982                 }
    1983             }
    1984         }
    1985 
    1986         inData.append(bytes,nbytes);
    1987         // gzip and base64 encode the data
    1988         flags = RPENC_Z|RPENC_B64|RPENC_HDR;
    1989         status &= Rappture::encoding::encode(inData,flags);
    1990 
    1991         bytesWritten = (unsigned int) inData.size();
    1992         scew_element_set_contents_binary(retNode,inData.bytes(),&bytesWritten);
    1993     }
    1994     else {
    1995         // node not found, set error
    1996         if (!status) {
    1997             status.error("Error while searching for node: node not found");
    1998         }
    1999     }
    2000 
    2001     status.addContext("RpLibrary::putData()");
     1963    if (retNode == NULL) {
     1964        status.addError("can't create node from path \"%s\"", path.c_str());
     1965        return *this;
     1966    }
     1967    if (append == RPLIB_APPEND) {
     1968        if ( (contents = scew_element_contents(retNode)) ) {
     1969            inData.append(contents);
     1970            // base64 decode and un-gzip the data
     1971            if (!Rappture::encoding::decode(status, inData, 0)) {
     1972                return *this;
     1973            }
     1974        }
     1975    }
     1976    if (inData.append(bytes, nbytes) != nbytes) {
     1977        status.addError("can't append %d bytes", nbytes);
     1978        return *this;
     1979    }   
     1980    // gzip and base64 encode the data
     1981    flags = RPENC_Z|RPENC_B64|RPENC_HDR;
     1982    if (!Rappture::encoding::encode(status, inData,flags)) {
     1983        return *this;
     1984    }
     1985    bytesWritten = (unsigned int) inData.size();
     1986    scew_element_set_contents_binary(retNode,inData.bytes(),&bytesWritten);
    20021987    return *this;
    20031988}
     
    20131998
    20141999RpLibrary&
    2015 RpLibrary::putFile (std::string path,
    2016                     std::string fileName,
    2017                     unsigned int compress,
    2018                     unsigned int append  )
     2000RpLibrary::putFile(std::string path, std::string fileName,
     2001                   unsigned int compress, unsigned int append)
    20192002{
    20202003    Rappture::Buffer buf;
     
    20272010    }
    20282011
    2029     fileBuf.load(fileName.c_str());
     2012    if (!fileBuf.load(err, fileName.c_str())) {
     2013        fprintf(stderr, "error loading file: %s\n", err.remark());
     2014        return *this;
     2015    }
    20302016    if (compress == RPLIB_COMPRESS) {
    2031         putData(path,fileBuf.bytes(),fileBuf.size(),append);
    2032     }
    2033     else {
    2034         fileBuf.append("\0",1);
    2035         put(path,fileBuf.bytes(),"",append,RPLIB_TRANSLATE);
     2017        putData(path, fileBuf.bytes(), fileBuf.size(), append);
     2018    } else {
     2019        /* Always append a NUL-byte to the end of ASCII strings. */
     2020        fileBuf.append("\0", 1);
     2021        put(path, fileBuf.bytes(), "", append, RPLIB_TRANSLATE);
    20362022    }
    20372023    status.addContext("RpLibrary::putFile()");
  • trunk/src/core/RpOutcome.cc

    r1352 r1366  
    1919 */
    2020Outcome::Outcome(const char *errmsg) :
    21     _status(0),
    22     _remarkPtr(NULL),
    23     _contextPtr(NULL)
     21    _status(0)
    2422{
    2523    if (errmsg) {
     
    3129Outcome::Outcome(const Outcome& oc) :
    3230    _status(oc._status),
    33     _remarkPtr(oc._remarkPtr),
    34     _contextPtr(oc._contextPtr)
     31    _remark(oc._remark),
     32    _context(oc._context)
    3533{
    3634}
     
    4139{
    4240    _status = oc._status;
    43     _remarkPtr = oc._remarkPtr;
    44     _contextPtr = oc._contextPtr;
     41    _remark = oc._remark;
     42    _context = oc._context;
    4543    return *this;
    4644}
     
    5755{
    5856    _status = status;
    59     _remarkPtr = Ptr<std::string>(new std::string(errmsg));
    60     _contextPtr.clear();
     57    _remark = errmsg;
    6158    return *this;
    6259}
     
    7774        vsnprintf(bufPtr, n, format, lst);
    7875    }
    79     if (_remarkPtr.isNull()) {
    80         _remarkPtr = Ptr<std::string>(new std::string(bufPtr));
     76    if (_remark == "") {
     77        _remark = _context;
     78        _remark.append(":\n");
     79        _remark.append(bufPtr);
    8180    } else {
    82         _remarkPtr->append("\n");
    83         _remarkPtr->append(bufPtr);
    84     }
    85     _contextPtr.clear();
     81        _remark.append("\n");
     82        _remark.append(bufPtr);
     83    }
    8684    _status = 1;                /* Set to error */
    8785    if (bufPtr != stackSpace) {
     
    9896{
    9997    _status = 0;
    100     _remarkPtr.clear();
    101     _contextPtr.clear();
     98    _remark.clear();
     99    _context.clear();
    102100    return *this;
    103101}
     
    128126{
    129127    _status &= oc._status;
    130     if (!oc._contextPtr.isNull()) {
    131         _remarkPtr = oc._remarkPtr;
    132         _contextPtr = oc._contextPtr;
    133     }
     128    _remark = oc._remark;
     129    _context = oc._context;
    134130    return *this;
    135131}
     
    141137Outcome::remark() const
    142138{
    143     return (!_remarkPtr.isNull()) ? _remarkPtr->data() : "";
     139    return _remark.c_str();
    144140}
    145141
     
    151147{
    152148    // FIXME: There should be a stack of contexts
    153     if (_contextPtr.isNull()) {
    154         _contextPtr = new std::string();
    155     }
    156     _contextPtr->append(rem);
    157     _contextPtr->append("\n");
     149    _context = rem;
     150    _context.append("\n");
    158151    return *this;
    159152}
     
    209202Outcome::context() const
    210203{
    211     return (!_contextPtr.isNull()) ? _contextPtr->data() : "";
    212 }
     204    return _context.c_str();
     205}
  • trunk/src/core/RpOutcome.h

    r1325 r1366  
    4848
    4949    /// error message
    50     Ptr<std::string>_remarkPtr;
     50    std::string _remark;
    5151
    5252    /// stack trace
    53     Ptr<std::string>_contextPtr;
     53    std::string _context;
    5454};
    5555
Note: See TracChangeset for help on using the changeset viewer.