Changeset 18657 for lang/c/msgpack

Show
Ignore:
Timestamp:
09/02/08 20:35:48 (6 years ago)
Author:
frsyuki
Message:

lang/c/msgpack: C++ binding: implemented built-in buffer.

Location:
lang/c/msgpack/trunk/cpp
Files:
9 modified

Legend:

Unmodified
Added
Removed
  • lang/c/msgpack/trunk/cpp/Makefile

    r18610 r18657  
    11 
    2 CXXFLAGS = -I.. -I. -Wall -g -O4 
     2CXXFLAGS = -I.. -I. -Wall -g 
     3#CXXFLAGS = -I.. -I. -Wall -g -O4 
    34LDFLAGS = -L. 
    45 
  • lang/c/msgpack/trunk/cpp/object.cpp

    r18610 r18657  
    321321 
    322322 
    323 RAW_OBJECT(raw, 
    324         raw object_raw::xraw() { return raw(ptr, len); } 
    325         const_raw object_raw::xraw() const { return const_raw(ptr, len); } ) 
    326  
    327 RAW_OBJECT(const_raw, 
    328         const_raw object_const_raw::xraw() const { return const_raw(ptr, len); } ) 
     323RAW_OBJECT(raw_ref, 
     324        raw object_raw_ref::xraw() { return raw(ptr, len); } 
     325        const_raw object_raw_ref::xraw() const { return const_raw(ptr, len); } ) 
     326 
     327RAW_OBJECT(const_raw_ref, 
     328        const_raw object_const_raw_ref::xraw() const { return const_raw(ptr, len); } ) 
    329329 
    330330#undef RAW_OBJECT(NAME, EXTRA) 
  • lang/c/msgpack/trunk/cpp/object.hpp

    r18610 r18657  
    3232 
    3333struct const_raw { 
    34         const_raw() : ptr(NULL), len(0) {} 
    35         const_raw(const void* p, size_t l) : ptr(p), len(l) {} 
     34        explicit const_raw() : ptr(NULL), len(0) {} 
     35        explicit const_raw(const void* p, size_t l) : ptr(p), len(l) {} 
     36        const_raw(const raw& m) : ptr(m.ptr), len(m.len) {} 
    3637public: 
    3738        const void* ptr; 
     
    258259}; 
    259260 
    260 RAW_CLASS(raw, void*, raw xraw(); const_raw xraw() const; ) 
    261 RAW_CLASS(const_raw, const void*, const_raw xraw() const; ) 
     261RAW_CLASS(raw_ref, void*, raw xraw(); const_raw xraw() const; ) 
     262RAW_CLASS(const_raw_ref, const void*, const_raw xraw() const; ) 
    262263 
    263264#undef RAW_CLASS(NAME, TYPE, EXTRA) 
  • lang/c/msgpack/trunk/cpp/test.cpp

    r18610 r18657  
    33#include <msgpack/unpack.hpp> 
    44#include <msgpack/pack.hpp> 
     5#include <sstream> 
     6#include <boost/scoped_ptr.hpp> 
    57 
    68class checker { 
     
    115117                c.check(d, sizeof(d), 
    116118                        z.narray( 
    117                                 z.nraw("", 0), 
    118                                 z.nraw("a", 1), 
    119                                 z.nraw("bc", 2), 
    120                                 z.nraw("def", 3) 
    121                         ) 
    122                 ); 
     119                                z.nraw_ref("", 0), 
     120                                z.nraw_ref("a", 1), 
     121                                z.nraw_ref("bc", 2), 
     122                                z.nraw_ref("def", 3) 
     123                        ) 
     124                ); 
     125        } 
     126 
     127        static const uint16_t TASK_ARRAY = 100; 
     128        static char tarray[3]; 
     129        static char traw[64]; 
     130 
     131        { 
     132                memset(traw, 'a', sizeof(traw)); 
     133                traw[0] = 0xda; 
     134                uint16_t n = htons(sizeof(traw)-3); 
     135                traw[1] = ((char*)&n)[0]; 
     136                traw[2] = ((char*)&n)[1]; 
     137 
     138                msgpack::zone z; 
     139                std::cout << msgpack::unpack(traw, sizeof(traw), z) << std::endl;; 
     140        } 
     141 
     142        { 
     143                tarray[0] = 0xdc; 
     144                uint16_t n = htons(TASK_ARRAY); 
     145                tarray[1] = ((char*)&n)[0]; 
     146                tarray[2] = ((char*)&n)[1]; 
     147        } 
     148 
     149        { 
     150                // write message 
     151                ssize_t total_bytes = 0; 
     152                std::stringstream stream; 
     153                for(unsigned q=0; q < 10; ++q) { 
     154                        stream.write(tarray, sizeof(tarray)); 
     155                        total_bytes += sizeof(tarray); 
     156                        for(uint16_t i=0; i < TASK_ARRAY; ++i) { 
     157                                stream.write(traw, sizeof(traw)); 
     158                                total_bytes += sizeof(traw); 
     159                        } 
     160                } 
     161 
     162                stream.seekg(0); 
     163 
     164                // reserive message 
     165                unsigned num_msg = 0; 
     166 
     167                static const size_t RESERVE_SIZE = 32;//*1024; 
     168 
     169                msgpack::unpacker upk; 
     170                while(stream.good() && total_bytes > 0) { 
     171 
     172                        upk.reserve_buffer(RESERVE_SIZE); 
     173                        size_t sz = stream.readsome( 
     174                                        (char*)upk.buffer(), 
     175                                        upk.buffer_capacity()); 
     176 
     177                        total_bytes -= sz; 
     178                        std::cout << "read " << sz << " bytes to capacity " 
     179                                        << upk.buffer_capacity() << " bytes" 
     180                                        << std::endl; 
     181 
     182                        upk.buffer_consumed(sz); 
     183                        while( upk.execute() ) { 
     184                                std::cout << "message parsed" << std::endl; 
     185                                boost::scoped_ptr<msgpack::zone> pz(upk.release_zone()); 
     186                                msgpack::object o = upk.data(); 
     187                                upk.reset(); 
     188                                std::cout << o << std::endl; 
     189                                ++num_msg; 
     190                        } 
     191 
     192                } 
     193 
     194                std::cout << "stream finished" << std::endl; 
     195                std::cout << num_msg << " messages reached" << std::endl; 
    123196        } 
    124197 
  • lang/c/msgpack/trunk/cpp/unpack.cpp

    r18599 r18657  
    66 
    77struct unpacker::context { 
    8         context(zone& z) 
     8        context(zone* z) 
    99        { 
    1010                msgpack_unpacker_init(&m_ctx); 
    11                 m_ctx.user = &z; 
     11                m_ctx.user = z; 
    1212        } 
    1313 
     
    3131        } 
    3232 
     33        void reset(zone* z) 
     34        { 
     35                msgpack_unpacker_init(&m_ctx); 
     36                m_ctx.user = z; 
     37        } 
     38 
     39        zone* user() 
     40        { 
     41                return m_ctx.user; 
     42        } 
     43 
     44        void user(zone* z) 
     45        { 
     46                m_ctx.user = z; 
     47        } 
     48 
    3349private: 
    3450        msgpack_unpacker m_ctx; 
     
    4056 
    4157 
    42 unpacker::unpacker(zone& z) : 
    43         m_ctx(new context(z)), 
    44         m_zone(z), 
    45         m_finished(false) 
     58unpacker::unpacker() : 
     59        m_zone(new zone()), 
     60        m_ctx(new context(m_zone)), 
     61        m_buffer(NULL), 
     62        m_used(0), 
     63        m_free(0), 
     64        m_off(0) 
    4665{ } 
    4766 
    4867 
    49 unpacker::~unpacker() { delete m_ctx; } 
     68unpacker::~unpacker() 
     69{ 
     70        free(m_buffer); 
     71        delete m_ctx; 
     72        delete m_zone; 
     73} 
    5074 
    5175 
    52 size_t unpacker::execute(const void* data, size_t len, size_t off) 
     76void unpacker::expand_buffer(size_t len) 
    5377{ 
    54         int ret = m_ctx->execute(data, len, &off); 
    55         if(ret < 0) { 
    56                 throw unpack_error("parse error"); 
    57         } else if(ret > 0) { 
    58                 m_finished = true; 
    59                 return off; 
     78        if(m_off == 0) { 
     79                size_t next_size; 
     80                if(m_free != 0) { next_size = m_free * 2; } 
     81                else { next_size = MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE; } 
     82                while(next_size < len + m_used) { next_size *= 2; } 
     83 
     84                // FIXME realloc? 
     85 
     86                void* tmp = malloc(next_size); 
     87                if(!tmp) { throw std::bad_alloc(); } 
     88                memcpy(tmp, m_buffer, m_used); 
     89 
     90                free(m_buffer); 
     91                m_buffer = tmp; 
     92                m_free = next_size - m_used; 
     93 
    6094        } else { 
    61                 m_finished = false; 
    62                 return off; 
     95                size_t next_size = MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE; 
     96                while(next_size < len + m_used - m_off) { next_size *= 2; } 
     97 
     98                void* tmp = malloc(next_size); 
     99                if(!tmp) { throw std::bad_alloc(); } 
     100                memcpy(tmp, ((char*)m_buffer)+m_off, m_used-m_off); 
     101 
     102                try { 
     103                        m_zone->push_finalizer<void>(&zone::finalize_free, NULL, m_buffer); 
     104                } catch (...) { 
     105                        free(tmp); 
     106                        throw; 
     107                } 
     108 
     109                m_buffer = tmp; 
     110                m_used = m_used - m_off; 
     111                m_free = next_size - m_used; 
     112                m_off = 0; 
    63113        } 
    64114} 
    65115 
     116bool unpacker::execute() 
     117{ 
     118        int ret = m_ctx->execute(m_buffer, m_used, &m_off); 
     119        if(ret < 0) { 
     120                throw unpack_error("parse error"); 
     121        } else if(ret == 0) { 
     122                return false; 
     123        } else { 
     124                return true; 
     125        } 
     126} 
     127 
     128zone* unpacker::release_zone() 
     129{ 
     130        zone* z = m_zone; 
     131        m_zone = NULL; 
     132        m_zone = new zone(); 
     133        m_ctx->user(m_zone); 
     134        return z; 
     135} 
    66136 
    67137object unpacker::data() 
     
    70140} 
    71141 
    72  
    73142void unpacker::reset() 
    74143{ 
     144        if(!m_zone->empty()) { 
     145                delete m_zone; 
     146                m_zone = NULL; 
     147                m_zone = new zone(); 
     148        } 
     149        expand_buffer(0); 
    75150        m_ctx->reset(); 
    76151} 
     
    79154object unpacker::unpack(const void* data, size_t len, zone& z) 
    80155{ 
    81         context ctx(z); 
     156        context ctx(&z); 
    82157        size_t off = 0; 
    83158        int ret = ctx.execute(data, len, &off); 
  • lang/c/msgpack/trunk/cpp/unpack.hpp

    r18599 r18657  
    55#include "msgpack/zone.hpp" 
    66#include <stdexcept> 
     7 
     8#ifndef MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE 
     9#define MSGPACK_UNPACKER_INITIAL_BUFFER_SIZE 8*1024 
     10#endif 
    711 
    812namespace msgpack { 
     
    1721class unpacker { 
    1822public: 
    19         unpacker(zone& z); 
     23        unpacker(); 
    2024        ~unpacker(); 
     25 
    2126public: 
    22         size_t execute(const void* data, size_t len, size_t off); 
    23         bool is_finished() { return m_finished; } 
     27        void reserve_buffer(size_t len); 
     28        void* buffer(); 
     29        size_t buffer_capacity() const; 
     30        void buffer_consumed(size_t len); 
     31        bool execute(); 
     32        zone* release_zone();  // never throw 
    2433        object data(); 
    2534        void reset(); 
     35 
    2636private: 
     37        zone* m_zone; 
     38 
    2739        struct context; 
    2840        context* m_ctx; 
    29         zone& m_zone; 
    30         bool m_finished; 
     41 
     42        void* m_buffer; 
     43        size_t m_used; 
     44        size_t m_free; 
     45        size_t m_off; 
     46        void expand_buffer(size_t len); 
     47 
    3148private: 
    32         unpacker(); 
    3349        unpacker(const unpacker&); 
     50 
    3451public: 
    3552        static object unpack(const void* data, size_t len, zone& z); 
    3653}; 
     54 
     55 
     56inline void unpacker::reserve_buffer(size_t len) 
     57{ 
     58        if(m_free >= len) { return; } 
     59        expand_buffer(len); 
     60} 
     61 
     62inline void* unpacker::buffer() 
     63        { return (void*)(((char*)m_buffer)+m_used); } 
     64 
     65inline size_t unpacker::buffer_capacity() const 
     66        { return m_free; } 
     67 
     68inline void unpacker::buffer_consumed(size_t len) 
     69{ 
     70        m_used += len; 
     71        m_free -= len; 
     72} 
    3773 
    3874 
  • lang/c/msgpack/trunk/cpp/unpack_inline.cpp

    r18599 r18657  
    6060{ reinterpret_cast<object_map*>(c)->store(k, v); } 
    6161 
    62 static inline object_class* msgpack_unpack_string(zone** z, const void* b, size_t l) 
    63 { return (*z)->nraw(b, l); } 
    64  
    65 static inline object_class* msgpack_unpack_raw(zone** z, const void* b, size_t l) 
    66 { return (*z)->nraw(b, l); } 
     62static inline object_class* msgpack_unpack_raw(zone** z, const void* b, const void* p, size_t l) 
     63{ return (*z)->nraw_ref(p, l); } 
    6764 
    6865 
  • lang/c/msgpack/trunk/cpp/zone.cpp

    r18599 r18657  
    77{ 
    88        if(m_used >= m_pool.size()*MSGPACK_ZONE_CHUNK_SIZE) { 
    9                 m_pool.push_back(chunk_t()); 
     9                m_pool.push_back(new chunk_t()); 
    1010        } 
    11         void* data = m_pool[m_used/MSGPACK_ZONE_CHUNK_SIZE].cells[m_used%MSGPACK_ZONE_CHUNK_SIZE].data; 
     11        void* data = m_pool[m_used/MSGPACK_ZONE_CHUNK_SIZE]->cells[m_used%MSGPACK_ZONE_CHUNK_SIZE].data; 
    1212        ++m_used; 
    1313        return data; 
     
    1616void zone::clear() 
    1717{ 
    18         for(size_t b=0; b < m_used/MSGPACK_ZONE_CHUNK_SIZE; ++b) { 
    19                 cell_t* c(m_pool[b].cells); 
    20                 for(size_t e=0; e < MSGPACK_ZONE_CHUNK_SIZE; ++e) { 
     18        if(!m_pool.empty()) { 
     19                for(size_t b=0; b < m_used/MSGPACK_ZONE_CHUNK_SIZE; ++b) { 
     20                        cell_t* c(m_pool[b]->cells); 
     21                        for(size_t e=0; e < MSGPACK_ZONE_CHUNK_SIZE; ++e) { 
     22                                reinterpret_cast<object_class*>(c[e].data)->~object_class(); 
     23                        } 
     24                } 
     25                cell_t* c(m_pool.back()->cells); 
     26                for(size_t e=0; e < m_used%MSGPACK_ZONE_CHUNK_SIZE; ++e) { 
    2127                        reinterpret_cast<object_class*>(c[e].data)->~object_class(); 
    2228                } 
    23         } 
    24         cell_t* c(m_pool.back().cells); 
    25         for(size_t e=0; e < m_used%MSGPACK_ZONE_CHUNK_SIZE; ++e) { 
    26                 reinterpret_cast<object_class*>(c[e].data)->~object_class(); 
     29 
     30                for(pool_t::iterator it(m_pool.begin()), it_end(m_pool.end()); 
     31                                it != it_end; 
     32                                ++it) { 
     33                        delete *it; 
     34                } 
     35                m_pool.clear(); 
    2736        } 
    2837        m_used = 0; 
    29         m_pool.resize(1); 
     38 
    3039        for(user_finalizer_t::reverse_iterator it(m_user_finalizer.rbegin()), it_end(m_user_finalizer.rend()); 
    3140                        it != it_end; 
  • lang/c/msgpack/trunk/cpp/zone.hpp.erb

    r18599 r18657  
    11#ifndef MSGPACK_ZONE_HPP__ 
    22#define MSGPACK_ZONE_HPP__ 
     3#include <iostream> 
    34 
    45#include "msgpack/object.hpp" 
    5 #include <iostream> 
     6#include <string.h> 
     7#include <stdlib.h> 
     8#include <stdexcept> 
    69 
    710#ifndef MSGPACK_ZONE_CHUNK_SIZE 
     
    1417class zone { 
    1518public: 
    16 zone() : m_used(0), m_pool(1) { } 
    17 ~zone() { clear(); } 
     19        zone() : m_used(0) { } 
     20        ~zone() { clear(); } 
    1821 
    1922public: 
     
    3639        object_double* ndouble(  double v) { return new (alloc()) object_double(v); } 
    3740 
    38         object_raw* nraw(void* ptr, uint32_t len) 
    39                 { return new (alloc()) object_raw(ptr, len); } 
     41        object_raw_ref* nraw_ref(void* ptr, uint32_t len) 
     42                { return new (alloc()) object_raw_ref(ptr, len); } 
    4043 
    41         object_const_raw* nraw(const void* ptr, uint32_t len) 
    42                 { return new (alloc()) object_const_raw(ptr, len); } 
     44        object_const_raw_ref* nraw_ref(const void* ptr, uint32_t len) 
     45                { return new (alloc()) object_const_raw_ref(ptr, len); } 
     46 
     47        object_raw_ref* nraw_copy(const void* ptr, uint32_t len) 
     48                { 
     49                        void* copy = malloc(len); 
     50                        if(!copy) { throw std::bad_alloc(); } 
     51                        object_raw_ref* o; 
     52                        try { 
     53                                o = new (alloc()) object_raw_ref(copy, len); 
     54                                push_finalizer<void>(&zone::finalize_free, NULL, copy); 
     55                        } catch (...) { 
     56                                free(copy); 
     57                                throw; 
     58                        } 
     59                        memcpy(copy, ptr, len); 
     60                        return o; 
     61                } 
    4362 
    4463        object_array* narray() 
     
    6887public: 
    6988        void clear(); 
     89        bool empty() const; 
    7090 
    7191private: 
     
    7696 
    7797        static const size_t MAX_OBJECT_SIZE = 
    78                 sizeof(object_raw) > sizeof(object_array) 
    79                         ? ( sizeof(object_raw) > sizeof(object_map) 
    80                                         ? sizeof(object_raw) 
     98                sizeof(object_raw_ref) > sizeof(object_array) 
     99                        ? ( sizeof(object_raw_ref) > sizeof(object_map) 
     100                                        ? sizeof(object_raw_ref) 
    81101                                        : sizeof(object_map) 
    82102                          ) 
     
    95115        }; 
    96116 
    97         typedef std::vector<chunk_t> pool_t; 
     117        typedef std::vector<chunk_t*> pool_t; 
    98118        pool_t m_pool; 
    99119 
     
    114134 
    115135private: 
     136        void resize_pool(size_t n); 
     137 
     138public: 
     139        static void finalize_free(void* obj, void* user) 
     140                { free(user); } 
     141 
     142private: 
    116143        zone(const zone&); 
    117144}; 
     145 
     146 
     147template <typename T> 
     148inline void zone::push_finalizer(void (*func)(void* obj, void* user), T* obj, void* user) 
     149{ 
     150        m_user_finalizer.push_back( finalizer( 
     151                        func, reinterpret_cast<void*>(obj), 
     152                        user) ); 
     153} 
     154 
     155inline bool zone::empty() const 
     156{ 
     157        return m_used == 0 && m_user_finalizer.empty(); 
     158} 
    118159 
    119160