"vscode:/vscode.git/clone" did not exist on "496203d8906c99cd40f6846adba77c9ffbbb691d"
serialize_pickle.h 2.32 KB
Newer Older
1
2
// Copyright (C) 2013  Davis E. King (davis@dlib.net)
// License: Boost Software License   See LICENSE.txt for the full license.
3
4
#ifndef DLIB_SERIALIZE_PiCKLE_Hh_
#define DLIB_SERIALIZE_PiCKLE_Hh_
5
6
7
8

#include <dlib/serialize.h>
#include <boost/python.hpp>
#include <sstream>
9
#include <dlib/vectorstream.h>
10
11
12
13
14
15
16
17
18

template <typename T>
struct serialize_pickle : boost::python::pickle_suite
{
    static boost::python::tuple getstate(
        const T& item 
    )
    {
        using namespace dlib;
19
20
21
        std::vector<char> buf;
        buf.reserve(5000);
        vectorstream sout(buf);
22
        serialize(item, sout);
23
24
        return boost::python::make_tuple(boost::python::handle<>(
                PyBytes_FromStringAndSize(buf.size()?&buf[0]:0, buf.size())));
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    }

    static void setstate(
        T& item, 
        boost::python::tuple state
    )
    {
        using namespace dlib;
        using namespace boost::python;
        if (len(state) != 1)
        {
            PyErr_SetObject(PyExc_ValueError,
                ("expected 1-item tuple in call to __setstate__; got %s"
                 % state).ptr()
            );
            throw_error_already_set();
        }

43
44
45
46
47
        // We used to serialize by converting to a str but the boost.python routines for
        // doing this don't work in Python 3.  You end up getting an error about invalid
        // UTF-8 encodings.  So instead we access the python C interface directly and use
        // bytes objects.  However, we keep the deserialization code that worked with str
        // for backwards compatibility with previously pickled files.
48
        if (boost::python::extract<str>(state[0]).check())
49
        {
50
51
            str data = boost::python::extract<str>(state[0]);
            std::string temp(boost::python::extract<const char*>(data), len(data));
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
            std::istringstream sin(temp);
            deserialize(item, sin);
        }
        else if(PyBytes_Check(object(state[0]).ptr()))
        {
            object obj = state[0];
            char* data = PyBytes_AsString(obj.ptr());
            unsigned long num = PyBytes_Size(obj.ptr());
            std::istringstream sin(std::string(data, num));
            deserialize(item, sin);
        }
        else
        {
            throw error("Unable to unpickle, error in input file.");
        }
67
68
69
    }
};

70
#endif // DLIB_SERIALIZE_PiCKLE_Hh_
71