LCOV - code coverage report
Current view: top level - home/snapwebsites/snapcpp/snapwebsites/snapdatabase/snapdatabase/database - row.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 339 0.0 %
Date: 2019-12-15 17:13:15 Functions: 0 12 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2019  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/snapdatabase
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software; you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation; either version 2 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License along
      17             : // with this program; if not, write to the Free Software Foundation, Inc.,
      18             : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             : 
      20             : 
      21             : /** \file
      22             :  * \brief Database file implementation.
      23             :  *
      24             :  * Each table uses one or more files. Each file is handled by a dbfile
      25             :  * object and a corresponding set of blocks.
      26             :  */
      27             : 
      28             : // self
      29             : //
      30             : #include    "snapdatabase/database/row.h"
      31             : 
      32             : 
      33             : // last include
      34             : //
      35             : #include    <snapdev/poison.h>
      36             : 
      37             : 
      38             : 
      39             : namespace snapdatabase
      40             : {
      41             : 
      42             : 
      43             : 
      44           0 : row::row(table::pointer_t t)
      45           0 :     : f_table(t)
      46             : {
      47           0 : }
      48             : 
      49             : 
      50           0 : buffer_t row::to_binary() const
      51             : {
      52           0 :     buffer_t result;
      53             : 
      54           0 :     auto push_uint8 = [&](uint8_t value)
      55             :         {
      56           0 :             result.push_back(value);
      57           0 :         };
      58             : 
      59           0 :     auto push_uint16 = [&](uint16_t value)
      60             :         {
      61           0 :             result.push_back(value >> 0);
      62           0 :             result.push_back(value >> 8);
      63           0 :         };
      64             : 
      65           0 :     auto push_uint32 = [&](uint32_t value)
      66             :         {
      67           0 :             result.push_back(value);
      68           0 :         };
      69             : 
      70           0 :     auto push_uint64 = [&](uint64_t value)
      71             :         {
      72           0 :             result.push_back(value);
      73           0 :         };
      74             : 
      75           0 :     table::pointer_t t(f_table.lock());
      76           0 :     schema_column::map_by_id_t columns(t->columns_by_id());
      77             : 
      78           0 :     for(auto const & c : f_cells)
      79             :     {
      80           0 :         schema_column::pointer_t schema(c.second->schema());
      81             : 
      82           0 :         column_id_t const id(schema->column_id());
      83           0 :         push_uint16(id);
      84             : 
      85           0 :         switch(schema->type())
      86             :         {
      87           0 :         case struct_type_t::STRUCT_TYPE_VOID:
      88           0 :             snap::NOTUSED(c.second->is_void());
      89           0 :             break;
      90             : 
      91           0 :         case struct_type_t::STRUCT_TYPE_BITS8:
      92             :         case struct_type_t::STRUCT_TYPE_UINT8:
      93           0 :             push_uint8(c.second->get_uint8());
      94           0 :             break;
      95             : 
      96           0 :         case struct_type_t::STRUCT_TYPE_INT8:
      97           0 :             push_uint8(c.second->get_int8());
      98           0 :             break;
      99             : 
     100           0 :         case struct_type_t::STRUCT_TYPE_BITS16:
     101             :         case struct_type_t::STRUCT_TYPE_UINT16:
     102           0 :             push_uint16(c.second->get_uint16());
     103           0 :             break;
     104             : 
     105           0 :         case struct_type_t::STRUCT_TYPE_INT16:
     106           0 :             push_uint16(c.second->get_int16());
     107           0 :             break;
     108             : 
     109           0 :         case struct_type_t::STRUCT_TYPE_BITS32:
     110             :         case struct_type_t::STRUCT_TYPE_UINT32:
     111             :         case struct_type_t::STRUCT_TYPE_VERSION:
     112           0 :             push_uint32(c.second->get_uint32());
     113           0 :             break;
     114             : 
     115           0 :         case struct_type_t::STRUCT_TYPE_INT32:
     116           0 :             push_uint32(c.second->get_int32());
     117           0 :             break;
     118             : 
     119           0 :         case struct_type_t::STRUCT_TYPE_BITS64:
     120             :         case struct_type_t::STRUCT_TYPE_UINT64:
     121             :         case struct_type_t::STRUCT_TYPE_REFERENCE:
     122             :         case struct_type_t::STRUCT_TYPE_OID:
     123             :         case struct_type_t::STRUCT_TYPE_TIME:
     124             :         case struct_type_t::STRUCT_TYPE_MSTIME:
     125             :         case struct_type_t::STRUCT_TYPE_USTIME:
     126           0 :             push_uint64(c.second->get_uint64());
     127           0 :             break;
     128             : 
     129           0 :         case struct_type_t::STRUCT_TYPE_INT64:
     130           0 :             push_uint64(c.second->get_int64());
     131           0 :             break;
     132             : 
     133           0 :         case struct_type_t::STRUCT_TYPE_BITS128:
     134             :         case struct_type_t::STRUCT_TYPE_UINT128:
     135             :             {
     136           0 :                 uint512_t const value(c.second->get_uint128());
     137           0 :                 push_uint64(value.f_value[0]);
     138           0 :                 push_uint64(value.f_value[1]);
     139             :             }
     140           0 :             break;
     141             : 
     142           0 :         case struct_type_t::STRUCT_TYPE_INT128:
     143             :             {
     144           0 :                 int512_t const value(c.second->get_int128());
     145           0 :                 push_uint64(value.f_value[0]);
     146           0 :                 push_uint64(value.f_value[1]);
     147             :             }
     148           0 :             break;
     149             : 
     150           0 :         case struct_type_t::STRUCT_TYPE_BITS256:
     151             :         case struct_type_t::STRUCT_TYPE_UINT256:
     152             :             {
     153           0 :                 uint512_t const value(c.second->get_uint256());
     154           0 :                 push_uint64(value.f_value[0]);
     155           0 :                 push_uint64(value.f_value[1]);
     156           0 :                 push_uint64(value.f_value[2]);
     157           0 :                 push_uint64(value.f_value[3]);
     158             :             }
     159           0 :             break;
     160             : 
     161           0 :         case struct_type_t::STRUCT_TYPE_INT256:
     162             :             {
     163           0 :                 int512_t const value(c.second->get_int256());
     164           0 :                 push_uint64(value.f_value[0]);
     165           0 :                 push_uint64(value.f_value[1]);
     166           0 :                 push_uint64(value.f_value[2]);
     167           0 :                 push_uint64(value.f_value[3]);
     168             :             }
     169           0 :             break;
     170             : 
     171           0 :         case struct_type_t::STRUCT_TYPE_BITS512:
     172             :         case struct_type_t::STRUCT_TYPE_UINT512:
     173             :             {
     174           0 :                 uint512_t const value(c.second->get_uint512());
     175           0 :                 push_uint64(value.f_value[0]);
     176           0 :                 push_uint64(value.f_value[1]);
     177           0 :                 push_uint64(value.f_value[2]);
     178           0 :                 push_uint64(value.f_value[3]);
     179           0 :                 push_uint64(value.f_value[4]);
     180           0 :                 push_uint64(value.f_value[5]);
     181           0 :                 push_uint64(value.f_value[6]);
     182           0 :                 push_uint64(value.f_value[7]);
     183             :             }
     184           0 :             break;
     185             : 
     186           0 :         case struct_type_t::STRUCT_TYPE_INT512:
     187             :             {
     188           0 :                 int512_t const value(c.second->get_int512());
     189           0 :                 push_uint64(value.f_value[0]);
     190           0 :                 push_uint64(value.f_value[1]);
     191           0 :                 push_uint64(value.f_value[2]);
     192           0 :                 push_uint64(value.f_value[3]);
     193           0 :                 push_uint64(value.f_value[4]);
     194           0 :                 push_uint64(value.f_value[5]);
     195           0 :                 push_uint64(value.f_value[6]);
     196           0 :                 push_uint64(value.f_value[7]);
     197             :             }
     198           0 :             break;
     199             : 
     200           0 :         case struct_type_t::STRUCT_TYPE_FLOAT32:
     201             :             {
     202             :                 union fi {
     203             :                     uint32_t    f_int = 0;
     204             :                     float       f_float;
     205             :                 };
     206           0 :                 fi value;
     207           0 :                 value.f_float = c.second->get_float32();
     208           0 :                 push_uint32(value.f_int);
     209             :             }
     210           0 :             break;
     211             : 
     212           0 :         case struct_type_t::STRUCT_TYPE_FLOAT64:
     213             :             {
     214             :                 union fi {
     215             :                     uint64_t    f_int = 0;
     216             :                     double      f_float;
     217             :                 };
     218           0 :                 fi value;
     219           0 :                 value.f_float = c.second->get_float64();
     220           0 :                 push_uint64(value.f_int);
     221             :             }
     222           0 :             break;
     223             : 
     224           0 :         case struct_type_t::STRUCT_TYPE_FLOAT128:
     225             :             {
     226             :                 union fi {
     227             :                     uint64_t        f_int[2] = { 0, 0 };
     228             :                     long double     f_float;
     229             :                 };
     230           0 :                 fi value;
     231           0 :                 value.f_float = c.second->get_float128();
     232           0 :                 push_uint64(value.f_int[0]);
     233           0 :                 push_uint64(value.f_int[1]);
     234             :             }
     235           0 :             break;
     236             : 
     237           0 :         case struct_type_t::STRUCT_TYPE_P8STRING:
     238             :             {
     239           0 :                 std::string const value(c.second->get_string());
     240           0 :                 if(value.length() > 255)
     241             :                 {
     242             :                     throw out_of_bounds(
     243             :                               "string to long for a P8STRING (max: 255, actually: "
     244           0 :                             + std::to_string(value.length())
     245           0 :                             + ").");
     246             :                 }
     247           0 :                 push_uint8(value.length());
     248           0 :                 if(!value.empty())
     249             :                 {
     250           0 :                     uint8_t const * s(reinterpret_cast<uint8_t const *>(value.c_str()));
     251           0 :                     result.insert(result.end(), s, s + value.length());
     252           0 :                 }
     253             :             }
     254           0 :             break;
     255             : 
     256           0 :         case struct_type_t::STRUCT_TYPE_P16STRING:
     257             :             {
     258           0 :                 std::string const value(c.second->get_string());
     259           0 :                 if(value.length() > 65535)
     260             :                 {
     261             :                     throw out_of_bounds(
     262             :                               "string to long for a P16STRING (max: 64Kb, actually: "
     263           0 :                             + std::to_string(value.length())
     264           0 :                             + ").");
     265             :                 }
     266           0 :                 uint16_t const size(static_cast<uint16_t>(value.length()));
     267           0 :                 push_uint16(size);
     268           0 :                 if(size > 0)
     269             :                 {
     270           0 :                     uint8_t const * s(reinterpret_cast<uint8_t const *>(value.c_str()));
     271           0 :                     result.insert(result.end(), s, s + size);
     272           0 :                 }
     273             :             }
     274           0 :             break;
     275             : 
     276           0 :         case struct_type_t::STRUCT_TYPE_P32STRING:
     277             :             {
     278           0 :                 std::string const value(c.second->get_string());
     279           0 :                 if(value.length() > 65535)
     280             :                 {
     281             :                     throw out_of_bounds(
     282             :                               "string to long for a P32STRING (max: 4Gb, actually: "
     283           0 :                             + std::to_string(value.length())
     284           0 :                             + ").");
     285             :                 }
     286           0 :                 uint32_t const size(static_cast<uint32_t>(value.length()));
     287           0 :                 push_uint32(size);
     288           0 :                 if(size > 0)
     289             :                 {
     290           0 :                     uint8_t const * s(reinterpret_cast<uint8_t const *>(value.c_str()));
     291           0 :                     result.insert(result.end(), s, s + size);
     292           0 :                 }
     293             :             }
     294           0 :             break;
     295             : 
     296           0 :         case struct_type_t::STRUCT_TYPE_STRUCTURE:
     297             :         case struct_type_t::STRUCT_TYPE_ARRAY8:
     298             :         case struct_type_t::STRUCT_TYPE_ARRAY16:
     299             :         case struct_type_t::STRUCT_TYPE_ARRAY32:
     300             :         case struct_type_t::STRUCT_TYPE_BUFFER8:
     301             :         case struct_type_t::STRUCT_TYPE_BUFFER16:
     302             :         case struct_type_t::STRUCT_TYPE_BUFFER32:
     303             :         case struct_type_t::STRUCT_TYPE_END:
     304             :         case struct_type_t::STRUCT_TYPE_RENAMED:
     305             :             throw type_mismatch(
     306             :                       "Unexpected type ("
     307           0 :                     + std::to_string(static_cast<int>(schema->type()))
     308           0 :                     + ") to convert a cell from binary.");
     309             : 
     310             :         }
     311             :     }
     312             : 
     313           0 :     return result;
     314             : }
     315             : 
     316             : 
     317           0 : void row::from_binary(buffer_t const & blob)
     318             : {
     319           0 :     table::pointer_t t(f_table.lock());
     320           0 :     schema_column::map_by_id_t columns(t->columns_by_id());
     321           0 :     size_t pos(0);
     322             : 
     323           0 :     auto get_uint8 = [&]()
     324             :         {
     325           0 :             if(pos + 1 > blob.size())
     326             :             {
     327           0 :                 throw unexpected_eof("blob too small for a [u]int8_t.");
     328             :             }
     329             : 
     330           0 :             uint8_t const value(blob[pos]);
     331           0 :             pos += 1;
     332           0 :             return value;
     333           0 :         };
     334             : 
     335           0 :     auto get_uint16 = [&]()
     336             :         {
     337           0 :             if(pos + 2 > blob.size())
     338             :             {
     339           0 :                 throw unexpected_eof("blob too small for a [u]int16_t.");
     340             :             }
     341             : 
     342           0 :             uint16_t const value((static_cast<uint16_t>(blob[pos + 0]) <<  0)
     343           0 :                                + (static_cast<uint16_t>(blob[pos + 1]) <<  8));
     344           0 :             pos += 2;
     345           0 :             return value;
     346           0 :         };
     347             : 
     348           0 :     auto get_uint32 = [&]()
     349             :         {
     350           0 :             if(pos + 4 > blob.size())
     351             :             {
     352           0 :                 throw unexpected_eof("blob too small for a [u]int32_t.");
     353             :             }
     354             : 
     355           0 :             uint32_t const value((static_cast<uint32_t>(blob[pos + 0]) <<  0)
     356           0 :                                + (static_cast<uint32_t>(blob[pos + 1]) <<  8)
     357           0 :                                + (static_cast<uint32_t>(blob[pos + 2]) << 16)
     358           0 :                                + (static_cast<uint32_t>(blob[pos + 3]) << 24));
     359           0 :             pos += 4;
     360           0 :             return value;
     361           0 :         };
     362             : 
     363           0 :     auto get_uint64 = [&]()
     364             :         {
     365           0 :             if(pos + 8 > blob.size())
     366             :             {
     367           0 :                 throw unexpected_eof("blob too small for a [u]int64_t.");
     368             :             }
     369             : 
     370           0 :             uint64_t const value((static_cast<uint64_t>(blob[pos + 0]) <<  0)
     371           0 :                                + (static_cast<uint64_t>(blob[pos + 1]) <<  8)
     372           0 :                                + (static_cast<uint64_t>(blob[pos + 2]) << 16)
     373           0 :                                + (static_cast<uint64_t>(blob[pos + 3]) << 24)
     374           0 :                                + (static_cast<uint64_t>(blob[pos + 4]) << 32)
     375           0 :                                + (static_cast<uint64_t>(blob[pos + 5]) << 40)
     376           0 :                                + (static_cast<uint64_t>(blob[pos + 6]) << 48)
     377           0 :                                + (static_cast<uint64_t>(blob[pos + 7]) << 56));
     378           0 :             pos += 8;
     379           0 :             return value;
     380           0 :         };
     381             : 
     382           0 :     while(pos < blob.size())
     383             :     {
     384           0 :         column_id_t const id(get_uint16());
     385           0 :         auto it(columns.find(id));
     386           0 :         if(it == columns.end())
     387             :         {
     388             :             throw column_not_found(
     389             :                     "column with identifier "
     390           0 :                     + std::to_string(static_cast<int>(id))
     391           0 :                     + " not found.");
     392             :         }
     393             : 
     394           0 :         cell::pointer_t v(std::make_shared<cell>(it->second));
     395           0 :         switch(it->second->type())
     396             :         {
     397           0 :         case struct_type_t::STRUCT_TYPE_VOID:
     398           0 :             v->set_void();
     399           0 :             break;
     400             : 
     401           0 :         case struct_type_t::STRUCT_TYPE_BITS8:
     402             :         case struct_type_t::STRUCT_TYPE_UINT8:
     403           0 :             v->set_uint8(get_uint8());
     404           0 :             break;
     405             : 
     406           0 :         case struct_type_t::STRUCT_TYPE_INT8:
     407           0 :             v->set_int8(get_uint8());
     408           0 :             break;
     409             : 
     410           0 :         case struct_type_t::STRUCT_TYPE_BITS16:
     411             :         case struct_type_t::STRUCT_TYPE_UINT16:
     412           0 :             v->set_uint16(get_uint16());
     413           0 :             break;
     414             : 
     415           0 :         case struct_type_t::STRUCT_TYPE_INT16:
     416           0 :             v->set_int16(get_uint16());
     417           0 :             break;
     418             : 
     419           0 :         case struct_type_t::STRUCT_TYPE_BITS32:
     420             :         case struct_type_t::STRUCT_TYPE_UINT32:
     421             :         case struct_type_t::STRUCT_TYPE_VERSION:
     422           0 :             v->set_uint32(get_uint32());
     423           0 :             break;
     424             : 
     425           0 :         case struct_type_t::STRUCT_TYPE_INT32:
     426           0 :             v->set_int32(get_uint32());
     427           0 :             break;
     428             : 
     429           0 :         case struct_type_t::STRUCT_TYPE_BITS64:
     430             :         case struct_type_t::STRUCT_TYPE_UINT64:
     431             :         case struct_type_t::STRUCT_TYPE_REFERENCE:
     432             :         case struct_type_t::STRUCT_TYPE_OID:
     433             :         case struct_type_t::STRUCT_TYPE_TIME:
     434             :         case struct_type_t::STRUCT_TYPE_MSTIME:
     435             :         case struct_type_t::STRUCT_TYPE_USTIME:
     436           0 :             v->set_uint64(get_uint64());
     437           0 :             break;
     438             : 
     439           0 :         case struct_type_t::STRUCT_TYPE_INT64:
     440           0 :             v->set_int64(get_uint64());
     441           0 :             break;
     442             : 
     443           0 :         case struct_type_t::STRUCT_TYPE_BITS128:
     444             :         case struct_type_t::STRUCT_TYPE_UINT128:
     445             :             {
     446           0 :                 uint512_t value;
     447           0 :                 value.f_value[0] = get_uint64();
     448           0 :                 value.f_value[1] = get_uint64();
     449           0 :                 v->set_uint128(value);
     450             :             }
     451           0 :             break;
     452             : 
     453           0 :         case struct_type_t::STRUCT_TYPE_INT128:
     454             :             {
     455           0 :                 int512_t value;
     456           0 :                 value.f_value[0] = get_uint64();
     457           0 :                 value.f_value[1] = get_uint64();
     458           0 :                 value.f_value[2] = static_cast<int64_t>(value.f_value[1]) < 0 ? -1 : 0;
     459           0 :                 value.f_value[3] = value.f_value[2];
     460           0 :                 value.f_value[4] = value.f_value[2];
     461           0 :                 value.f_value[5] = value.f_value[2];
     462           0 :                 value.f_value[6] = value.f_value[2];
     463           0 :                 value.f_high_value = value.f_value[2];
     464           0 :                 v->set_int128(value);
     465             :             }
     466           0 :             break;
     467             : 
     468           0 :         case struct_type_t::STRUCT_TYPE_BITS256:
     469             :         case struct_type_t::STRUCT_TYPE_UINT256:
     470             :             {
     471           0 :                 uint512_t value;
     472           0 :                 value.f_value[0] = get_uint64();
     473           0 :                 value.f_value[1] = get_uint64();
     474           0 :                 value.f_value[2] = get_uint64();
     475           0 :                 value.f_value[3] = get_uint64();
     476           0 :                 v->set_uint256(value);
     477             :             }
     478           0 :             break;
     479             : 
     480           0 :         case struct_type_t::STRUCT_TYPE_INT256:
     481             :             {
     482           0 :                 int512_t value;
     483           0 :                 value.f_value[0] = get_uint64();
     484           0 :                 value.f_value[1] = get_uint64();
     485           0 :                 value.f_value[2] = get_uint64();
     486           0 :                 value.f_value[3] = get_uint64();
     487           0 :                 value.f_value[4] = static_cast<int64_t>(value.f_value[3]) < 0 ? -1 : 0;
     488           0 :                 value.f_value[5] = value.f_value[4];
     489           0 :                 value.f_value[6] = value.f_value[4];
     490           0 :                 value.f_high_value = value.f_value[4];
     491           0 :                 v->set_int256(value);
     492             :             }
     493           0 :             break;
     494             : 
     495           0 :         case struct_type_t::STRUCT_TYPE_BITS512:
     496             :         case struct_type_t::STRUCT_TYPE_UINT512:
     497             :             {
     498           0 :                 uint512_t value;
     499           0 :                 value.f_value[0] = get_uint64();
     500           0 :                 value.f_value[1] = get_uint64();
     501           0 :                 value.f_value[2] = get_uint64();
     502           0 :                 value.f_value[3] = get_uint64();
     503           0 :                 value.f_value[4] = get_uint64();
     504           0 :                 value.f_value[5] = get_uint64();
     505           0 :                 value.f_value[6] = get_uint64();
     506           0 :                 value.f_value[7] = get_uint64();
     507           0 :                 v->set_uint512(value);
     508             :             }
     509           0 :             break;
     510             : 
     511           0 :         case struct_type_t::STRUCT_TYPE_INT512:
     512             :             {
     513           0 :                 int512_t value;
     514           0 :                 value.f_value[0] = get_uint64();
     515           0 :                 value.f_value[1] = get_uint64();
     516           0 :                 value.f_value[2] = get_uint64();
     517           0 :                 value.f_value[3] = get_uint64();
     518           0 :                 value.f_value[4] = get_uint64();
     519           0 :                 value.f_value[5] = get_uint64();
     520           0 :                 value.f_value[6] = get_uint64();
     521           0 :                 value.f_value[7] = get_uint64();
     522           0 :                 v->set_int512(value);
     523             :             }
     524           0 :             break;
     525             : 
     526           0 :         case struct_type_t::STRUCT_TYPE_FLOAT32:
     527             :             {
     528           0 :                 uint32_t const value(get_uint32());
     529           0 :                 v->set_float32(*reinterpret_cast<float const *>(&value));
     530             :             }
     531           0 :             break;
     532             : 
     533           0 :         case struct_type_t::STRUCT_TYPE_FLOAT64:
     534             :             {
     535           0 :                 uint64_t const value(get_uint64());
     536           0 :                 v->set_float64(*reinterpret_cast<double const *>(&value));
     537             :             }
     538           0 :             break;
     539             : 
     540           0 :         case struct_type_t::STRUCT_TYPE_FLOAT128:
     541             :             {
     542           0 :                 uint64_t const value[2] = { get_uint64(), get_uint64() };
     543           0 :                 v->set_float128(*reinterpret_cast<long double const *>(value));
     544             :             }
     545           0 :             break;
     546             : 
     547           0 :         case struct_type_t::STRUCT_TYPE_P8STRING:
     548             :             {
     549           0 :                 if(pos >= blob.size())
     550             :                 {
     551           0 :                     throw unexpected_eof("blob too small for this string.");
     552             :                 }
     553             : 
     554           0 :                 uint8_t const size(get_uint8());
     555             : 
     556           0 :                 if(pos + size > blob.size())
     557             :                 {
     558           0 :                     throw unexpected_eof("blob too small for this string.");
     559             :                 }
     560             : 
     561           0 :                 v->set_string(std::string(blob.data() + pos, blob.data() + pos + size));
     562           0 :                 pos += size;
     563             :             }
     564           0 :             break;
     565             : 
     566           0 :         case struct_type_t::STRUCT_TYPE_P16STRING:
     567             :             {
     568           0 :                 if(pos >= blob.size())
     569             :                 {
     570           0 :                     throw unexpected_eof("blob too small for this string.");
     571             :                 }
     572             : 
     573           0 :                 uint16_t const size(get_uint16());
     574             : 
     575           0 :                 if(pos + size > blob.size())
     576             :                 {
     577           0 :                     throw unexpected_eof("blob too small for this string.");
     578             :                 }
     579             : 
     580           0 :                 v->set_string(std::string(blob.data() + pos, blob.data() + pos + size));
     581           0 :                 pos += size;
     582             :             }
     583           0 :             break;
     584             : 
     585           0 :         case struct_type_t::STRUCT_TYPE_P32STRING:
     586             :             {
     587           0 :                 if(pos >= blob.size())
     588             :                 {
     589           0 :                     throw unexpected_eof("blob too small for this string.");
     590             :                 }
     591             : 
     592           0 :                 uint32_t const size(get_uint32());
     593             : 
     594           0 :                 if(pos + size > blob.size())
     595             :                 {
     596           0 :                     throw unexpected_eof("blob too small for this string.");
     597             :                 }
     598             : 
     599           0 :                 v->set_string(std::string(blob.data() + pos, blob.data() + pos + size));
     600           0 :                 pos += size;
     601             :             }
     602           0 :             break;
     603             : 
     604           0 :         case struct_type_t::STRUCT_TYPE_STRUCTURE:
     605             :         case struct_type_t::STRUCT_TYPE_ARRAY8:
     606             :         case struct_type_t::STRUCT_TYPE_ARRAY16:
     607             :         case struct_type_t::STRUCT_TYPE_ARRAY32:
     608             :         case struct_type_t::STRUCT_TYPE_BUFFER8:
     609             :         case struct_type_t::STRUCT_TYPE_BUFFER16:
     610             :         case struct_type_t::STRUCT_TYPE_BUFFER32:
     611             :         case struct_type_t::STRUCT_TYPE_END:
     612             :         case struct_type_t::STRUCT_TYPE_RENAMED:
     613             :             throw type_mismatch(
     614             :                       "Unexpected type ("
     615           0 :                     + std::to_string(static_cast<int>(it->second->type()))
     616           0 :                     + ") to convert a cell from binary.");
     617             : 
     618             :         }
     619             : 
     620           0 :         f_cells[it->second->name()] = v;
     621             :     }
     622           0 : }
     623             : 
     624             : 
     625           0 : cell::map_t row::cells() const
     626             : {
     627           0 :     return f_cells;
     628             : }
     629             : 
     630             : 
     631             : 
     632             : } // namespace snapdatabase
     633             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13