LCOV - code coverage report
Current view: top level - zerobuf - Zerobuf.cpp (source / functions) Hit Total Coverage
Test: ZeroBuf Lines: 89 119 74.8 %
Date: 2018-01-09 16:38:26 Functions: 19 23 82.6 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2015-2016, Human Brain Project
       3             :  *                          Stefan.Eilemann@epfl.ch
       4             :  */
       5             : 
       6             : #include "Zerobuf.h"
       7             : 
       8             : #include "NonMovingAllocator.h"
       9             : #include "NonMovingSubAllocator.h"
      10             : #include "StaticSubAllocator.h"
      11             : #include "jsoncpp/json/json.h"
      12             : #include <zerobuf/version.h>
      13             : 
      14             : #include <cstring>
      15             : #include <iostream>
      16             : 
      17             : namespace zerobuf
      18             : {
      19         412 : Zerobuf::Zerobuf(AllocatorPtr alloc)
      20         412 :     : _allocator(std::move(alloc))
      21             : {
      22         821 :     if (_allocator &&
      23         409 :         ((const Allocator*)_allocator.get())->getItem<uint32_t>(0) !=
      24         412 :             ZEROBUF_VERSION_ABI)
      25             :     {
      26         322 :         _allocator->getItem<uint32_t>(0) = ZEROBUF_VERSION_ABI;
      27             :     }
      28         412 : }
      29             : 
      30         187 : Zerobuf::Zerobuf(Zerobuf&& rhs)
      31             : {
      32         187 :     _allocator = std::move(rhs._allocator);
      33         374 :     rhs._allocator.reset(new NonMovingAllocator(rhs.getZerobufStaticSize(),
      34         374 :                                                 rhs.getZerobufNumDynamics()));
      35         187 :     uint32_t& version = rhs._allocator->getItem<uint32_t>(0);
      36         187 :     version = ZEROBUF_VERSION_ABI;
      37         187 : }
      38             : 
      39         599 : Zerobuf::~Zerobuf()
      40             : {
      41         599 : }
      42             : 
      43          51 : Zerobuf& Zerobuf::operator=(const Zerobuf& rhs)
      44             : {
      45          51 :     if (this == &rhs || !_allocator || !rhs._allocator)
      46           0 :         return *this;
      47             : 
      48          51 :     if (getTypeIdentifier() != rhs.getTypeIdentifier())
      49           1 :         throw std::runtime_error("Can't assign Zerobuf of a different type");
      50             : 
      51         100 :     _allocator->copyBuffer(rhs._allocator->getData(),
      52         100 :                            rhs._allocator->getSize());
      53          50 :     notifyChanged();
      54          50 :     return *this;
      55             : }
      56             : 
      57           5 : Zerobuf& Zerobuf::operator=(Zerobuf&& rhs)
      58             : {
      59           5 :     if (this == &rhs || !rhs._allocator)
      60           1 :         return *this;
      61             : 
      62           4 :     if (getTypeIdentifier() != rhs.getTypeIdentifier())
      63           0 :         throw std::runtime_error("Can't assign Zerobuf of a different type");
      64             : 
      65           4 :     if (_allocator->isMovable() && rhs._allocator->isMovable())
      66           1 :         _allocator = std::move(rhs._allocator);
      67             :     else // Sub allocator data can't be moved - need to copy
      68           6 :         _allocator->copyBuffer(rhs._allocator->getData(),
      69           6 :                                rhs._allocator->getSize());
      70             : 
      71           8 :     rhs._allocator.reset(new NonMovingAllocator(rhs.getZerobufStaticSize(),
      72           8 :                                                 rhs.getZerobufNumDynamics()));
      73           4 :     notifyChanged();
      74           4 :     return *this;
      75             : }
      76             : 
      77          23 : void Zerobuf::compact(const float threshold)
      78             : {
      79          23 :     if (_allocator && getZerobufNumDynamics() > 0)
      80          22 :         _allocator->compact(threshold);
      81          23 : }
      82             : 
      83           1 : bool Zerobuf::_fromBinary(const void* data, const size_t size)
      84             : {
      85           1 :     if (!_allocator)
      86           1 :         throw std::runtime_error("Can't copy data into empty Zerobuf object");
      87             : 
      88           0 :     if (size < 4)
      89             :     {
      90           0 :         std::cerr << "zerobuf too small" << std::endl;
      91           0 :         return false;
      92             :     }
      93             : 
      94           0 :     const uint32_t version = *reinterpret_cast<const uint32_t*>(data);
      95           0 :     if (version != ZEROBUF_VERSION_ABI)
      96             :     {
      97           0 :         std::cerr << "Version mismatch, got zerobuf v" << version
      98           0 :                   << " running v" << ZEROBUF_VERSION_ABI << std::endl;
      99           0 :         return false;
     100             :     }
     101             : 
     102           0 :     _allocator->copyBuffer(data, size);
     103           0 :     notifyChanged();
     104           0 :     return true;
     105             : }
     106             : 
     107        1104 : Data Zerobuf::_toBinary() const
     108             : {
     109        1104 :     if (!_allocator)
     110           2 :         return Data();
     111             : 
     112        2204 :     Data data;
     113             :     data.ptr =
     114        2204 :         std::shared_ptr<const void>(_allocator->getData(), [](const void*) {});
     115        1102 :     data.size = _allocator->getSize();
     116        1102 :     return data;
     117             : }
     118             : 
     119           9 : bool Zerobuf::_fromJSON(const std::string& string)
     120             : {
     121           9 :     if (!_allocator)
     122           2 :         return true;
     123             : 
     124          14 :     Json::Value json;
     125          14 :     Json::Reader reader;
     126           7 :     if (!reader.parse(string, json))
     127             :     {
     128             :         std::cerr << "Error parsing JSON: "
     129           0 :                   << reader.getFormattedErrorMessages() << std::endl
     130           0 :                   << "  while parsing: " << string << std::endl;
     131           0 :         return false;
     132             :     }
     133             : 
     134             :     try
     135             :     {
     136           7 :         _parseJSON(json);
     137             :     }
     138           0 :     catch (const std::exception& e)
     139             :     {
     140           0 :         std::cerr << "Error applying JSON: " << e.what() << std::endl;
     141           0 :         return false;
     142             :     }
     143             : 
     144           7 :     compact();
     145           7 :     return true;
     146             : }
     147             : 
     148          52 : std::string Zerobuf::_toJSON() const
     149             : {
     150          52 :     if (!_allocator)
     151           2 :         return "{}";
     152             : 
     153         100 :     Json::Value json;
     154          50 :     _createJSON(json);
     155          50 :     return json.toStyledString();
     156             : }
     157             : 
     158           0 : void Zerobuf::_parseJSON(const Json::Value&)
     159             : {
     160           0 :     throw std::runtime_error(std::string("JSON parsing missing for ") +
     161           0 :                              typeid(*this).name());
     162             : }
     163             : 
     164           0 : void Zerobuf::_createJSON(Json::Value&) const
     165             : {
     166           0 :     throw std::runtime_error(std::string("JSON parsing missing for ") +
     167           0 :                              typeid(*this).name());
     168             : }
     169             : 
     170          24 : bool Zerobuf::operator==(const Zerobuf& rhs) const
     171             : {
     172          96 :     if (this == &rhs ||
     173          52 :         (!_allocator && getTypeIdentifier() == rhs.getTypeIdentifier()))
     174             :     {
     175           2 :         return true;
     176             :     }
     177          22 :     return toJSON() == rhs.toJSON();
     178             : }
     179             : 
     180           0 : bool Zerobuf::operator!=(const Zerobuf& rhs) const
     181             : {
     182           0 :     return !(*this == rhs);
     183             : }
     184             : 
     185          12 : void Zerobuf::reset(AllocatorPtr allocator)
     186             : {
     187          12 :     _allocator.swap(allocator);
     188          12 : }
     189             : 
     190        1420 : Allocator& Zerobuf::getAllocator()
     191             : {
     192        1420 :     if (!_allocator)
     193           0 :         throw std::runtime_error("Empty Zerobuf has no allocator");
     194             : 
     195        1420 :     return *_allocator;
     196             : }
     197             : 
     198        1073 : const Allocator& Zerobuf::getAllocator() const
     199             : {
     200        1073 :     if (!_allocator)
     201           0 :         throw std::runtime_error("Empty Zerobuf has no allocator");
     202             : 
     203        1073 :     return *_allocator;
     204             : }
     205             : 
     206        2147 : void Zerobuf::_copyZerobufArray(const void* data, const size_t size,
     207             :                                 const size_t arrayNum)
     208             : {
     209        2147 :     if (!_allocator)
     210           0 :         throw std::runtime_error("Can't copy data into empty Zerobuf object");
     211             : 
     212             :     void* array =
     213        2147 :         _allocator->updateAllocation(arrayNum, false /*no copy*/, size);
     214        2147 :     ::memcpy(array, data, size);
     215        2147 : }
     216             : 
     217         120 : void Zerobuf::check() const
     218             : {
     219         120 :     if (_allocator)
     220         120 :         getAllocator().check(getZerobufNumDynamics());
     221         120 : }
     222          21 : }

Generated by: LCOV version 1.11