From: José Fonseca Date: Fri, 7 Dec 2012 07:33:17 +0000 (+0000) Subject: cli: Move pickle.hpp in. X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;ds=sidebyside;h=e6891fcf1538562a33ab071d8aec705d27bd2ffd;p=apitrace cli: Move pickle.hpp in. Only used by cli module. --- diff --git a/cli/pickle.hpp b/cli/pickle.hpp new file mode 100644 index 0000000..84b643a --- /dev/null +++ b/cli/pickle.hpp @@ -0,0 +1,331 @@ +/************************************************************************** + * + * Copyright 2012 Jose Fonseca + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + **************************************************************************/ + +/* + * Python pickle writer + */ + +#ifndef _PICKLE_HPP_ +#define _PICKLE_HPP_ + +#include +#include +#include + +#include +#include +#include + + +class PickleWriter +{ +private: + std::ostream &os; + + /* + * Python pickle opcodes. See pickle.py and pickletools.py from Python + * standard library for details. + */ + enum Opcode { + MARK = '(', + STOP = '.', + POP = '0', + POP_MARK = '1', + DUP = '2', + FLOAT = 'F', + INT = 'I', + BININT = 'J', + BININT1 = 'K', + LONG = 'L', + BININT2 = 'M', + NONE = 'N', + PERSID = 'P', + BINPERSID = 'Q', + REDUCE = 'R', + STRING = 'S', + BINSTRING = 'T', + SHORT_BINSTRING = 'U', + UNICODE = 'V', + BINUNICODE = 'X', + APPEND = 'a', + BUILD = 'b', + GLOBAL = 'c', + DICT = 'd', + EMPTY_DICT = '}', + APPENDS = 'e', + GET = 'g', + BINGET = 'h', + INST = 'i', + LONG_BINGET = 'j', + LIST = 'l', + EMPTY_LIST = ']', + OBJ = 'o', + PUT = 'p', + BINPUT = 'q', + LONG_BINPUT = 'r', + SETITEM = 's', + TUPLE = 't', + EMPTY_TUPLE = ')', + SETITEMS = 'u', + BINFLOAT = 'G', + + PROTO = '\x80', + NEWOBJ = '\x81', + EXT1 = '\x82', + EXT2 = '\x83', + EXT4 = '\x84', + TUPLE1 = '\x85', + TUPLE2 = '\x86', + TUPLE3 = '\x87', + NEWTRUE = '\x88', + NEWFALSE = '\x89', + LONG1 = '\x8a', + LONG4 = '\x8b', + }; + +public: + PickleWriter(std::ostream &_os) : + os(_os) { + } + + inline void begin() { + os.put(PROTO); + os.put(2); + } + + inline void end() { + os.put(STOP); + } + + inline void beginDict() { + os.put(EMPTY_DICT); + os.put(BINPUT); + os.put(1); + } + + inline void endDict() { + } + + inline void beginItem() { + } + + inline void beginItem(const char * name) { + writeString(name); + } + + inline void beginItem(const std::string &name) { + beginItem(name.c_str()); + } + + inline void endItem(void) { + os.put(SETITEM); + } + + inline void beginList() { + os.put(EMPTY_LIST); + os.put(BINPUT); + os.put(1); + os.put(MARK); + } + + inline void endList(void) { + os.put(APPENDS); + } + + inline void beginTuple() { + os.put(MARK); + } + + inline void endTuple(void) { + os.put(TUPLE); + } + + inline void writeString(const char *s, size_t length) { + if (!s) { + writeNone(); + return; + } + + if (length < 256) { + os.put(SHORT_BINSTRING); + os.put(length); + } else { + os.put(BINSTRING); + putInt32(length); + } + os.write(s, length); + + os.put(BINPUT); + os.put(1); + } + + inline void writeString(const char *s) { + if (!s) { + writeNone(); + return; + } + + writeString(s, strlen(s)); + } + + inline void writeString(const std::string &s) { + writeString(s.c_str(), s.size()); + } + + inline void writeNone(void) { + os.put(NONE); + } + + inline void writeBool(bool b) { + os.put(b ? NEWTRUE : NEWFALSE); + } + + inline void writeInt(uint8_t i) { + os.put(BININT1); + os.put(i); + } + + inline void writeInt(uint16_t i) { + if (i < 0x100) { + writeInt((uint8_t)i); + } else { + os.put(BININT2); + putInt16(i); + } + } + + inline void writeInt(int32_t i) { + if (0 <= i && i < 0x10000) { + writeInt((uint16_t)i); + } else { + os.put(BININT); + putInt32(i); + } + } + + inline void writeInt(uint32_t i) { + if (i < 0x8000000) { + writeInt((int32_t)i); + } else { + writeLong(i); + } + } + + inline void writeInt(long long i) { + if (-0x8000000 <= i && i < 0x8000000) { + writeInt((int32_t)i); + } else { + writeLong(i); + } + } + + inline void writeInt(unsigned long long i) { + if (i < 0x8000000) { + writeInt((int32_t)i); + } else { + writeLong(i); + } + } + + inline void writeFloat(double f) { + union { + double f; + char c[8]; + } u; + + assert(sizeof u.f == sizeof u.c); + u.f = f; + + os.put(BINFLOAT); + os.put(u.c[7]); + os.put(u.c[6]); + os.put(u.c[5]); + os.put(u.c[4]); + os.put(u.c[3]); + os.put(u.c[2]); + os.put(u.c[1]); + os.put(u.c[0]); + } + + inline void writeByteArray(const void *buf, size_t length) { + os.put(GLOBAL); + os << "__builtin__\nbytearray\n"; + os.put(BINPUT); + os.put(1); + writeString(static_cast(buf), length); + os.put(TUPLE1); + os.put(REDUCE); + } + +protected: + inline void putInt16(uint16_t i) { + os.put( i & 0xff); + os.put( i >> 8 ); + } + + inline void putInt32(uint32_t i) { + os.put( i & 0xff); + os.put((i >> 8) & 0xff); + os.put((i >> 16) & 0xff); + os.put( i >> 24 ); + } + + template< class T > + inline void writeLong(T l) { + os.put(LONG1); + + if (l == 0) { + os.put(0); + return; + } + + // Same as l >> (8 * sizeof l), but without the warnings + T sign; + if (std::numeric_limits::is_signed) { + sign = l < 0 ? ~0 : 0; + } else { + sign = 0; + } + + T sl = l; + unsigned c = 0; + do { + ++c; + } while (sl >>= 8 != sign); + + // Add an extra byte if sign bit doesn't match + if (((l >> (8 * c - 1)) & 1) != ((l >> (8 * sizeof l - 1)) & 1)) { + ++c; + } + os.put(c); + + for (unsigned i = 0; i < c; ++ i) { + os.put(l & 0xff); + l >>= 8; + } + } +}; + +#endif /* _Pickle_HPP_ */ diff --git a/common/pickle.hpp b/common/pickle.hpp deleted file mode 100644 index 84b643a..0000000 --- a/common/pickle.hpp +++ /dev/null @@ -1,331 +0,0 @@ -/************************************************************************** - * - * Copyright 2012 Jose Fonseca - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - **************************************************************************/ - -/* - * Python pickle writer - */ - -#ifndef _PICKLE_HPP_ -#define _PICKLE_HPP_ - -#include -#include -#include - -#include -#include -#include - - -class PickleWriter -{ -private: - std::ostream &os; - - /* - * Python pickle opcodes. See pickle.py and pickletools.py from Python - * standard library for details. - */ - enum Opcode { - MARK = '(', - STOP = '.', - POP = '0', - POP_MARK = '1', - DUP = '2', - FLOAT = 'F', - INT = 'I', - BININT = 'J', - BININT1 = 'K', - LONG = 'L', - BININT2 = 'M', - NONE = 'N', - PERSID = 'P', - BINPERSID = 'Q', - REDUCE = 'R', - STRING = 'S', - BINSTRING = 'T', - SHORT_BINSTRING = 'U', - UNICODE = 'V', - BINUNICODE = 'X', - APPEND = 'a', - BUILD = 'b', - GLOBAL = 'c', - DICT = 'd', - EMPTY_DICT = '}', - APPENDS = 'e', - GET = 'g', - BINGET = 'h', - INST = 'i', - LONG_BINGET = 'j', - LIST = 'l', - EMPTY_LIST = ']', - OBJ = 'o', - PUT = 'p', - BINPUT = 'q', - LONG_BINPUT = 'r', - SETITEM = 's', - TUPLE = 't', - EMPTY_TUPLE = ')', - SETITEMS = 'u', - BINFLOAT = 'G', - - PROTO = '\x80', - NEWOBJ = '\x81', - EXT1 = '\x82', - EXT2 = '\x83', - EXT4 = '\x84', - TUPLE1 = '\x85', - TUPLE2 = '\x86', - TUPLE3 = '\x87', - NEWTRUE = '\x88', - NEWFALSE = '\x89', - LONG1 = '\x8a', - LONG4 = '\x8b', - }; - -public: - PickleWriter(std::ostream &_os) : - os(_os) { - } - - inline void begin() { - os.put(PROTO); - os.put(2); - } - - inline void end() { - os.put(STOP); - } - - inline void beginDict() { - os.put(EMPTY_DICT); - os.put(BINPUT); - os.put(1); - } - - inline void endDict() { - } - - inline void beginItem() { - } - - inline void beginItem(const char * name) { - writeString(name); - } - - inline void beginItem(const std::string &name) { - beginItem(name.c_str()); - } - - inline void endItem(void) { - os.put(SETITEM); - } - - inline void beginList() { - os.put(EMPTY_LIST); - os.put(BINPUT); - os.put(1); - os.put(MARK); - } - - inline void endList(void) { - os.put(APPENDS); - } - - inline void beginTuple() { - os.put(MARK); - } - - inline void endTuple(void) { - os.put(TUPLE); - } - - inline void writeString(const char *s, size_t length) { - if (!s) { - writeNone(); - return; - } - - if (length < 256) { - os.put(SHORT_BINSTRING); - os.put(length); - } else { - os.put(BINSTRING); - putInt32(length); - } - os.write(s, length); - - os.put(BINPUT); - os.put(1); - } - - inline void writeString(const char *s) { - if (!s) { - writeNone(); - return; - } - - writeString(s, strlen(s)); - } - - inline void writeString(const std::string &s) { - writeString(s.c_str(), s.size()); - } - - inline void writeNone(void) { - os.put(NONE); - } - - inline void writeBool(bool b) { - os.put(b ? NEWTRUE : NEWFALSE); - } - - inline void writeInt(uint8_t i) { - os.put(BININT1); - os.put(i); - } - - inline void writeInt(uint16_t i) { - if (i < 0x100) { - writeInt((uint8_t)i); - } else { - os.put(BININT2); - putInt16(i); - } - } - - inline void writeInt(int32_t i) { - if (0 <= i && i < 0x10000) { - writeInt((uint16_t)i); - } else { - os.put(BININT); - putInt32(i); - } - } - - inline void writeInt(uint32_t i) { - if (i < 0x8000000) { - writeInt((int32_t)i); - } else { - writeLong(i); - } - } - - inline void writeInt(long long i) { - if (-0x8000000 <= i && i < 0x8000000) { - writeInt((int32_t)i); - } else { - writeLong(i); - } - } - - inline void writeInt(unsigned long long i) { - if (i < 0x8000000) { - writeInt((int32_t)i); - } else { - writeLong(i); - } - } - - inline void writeFloat(double f) { - union { - double f; - char c[8]; - } u; - - assert(sizeof u.f == sizeof u.c); - u.f = f; - - os.put(BINFLOAT); - os.put(u.c[7]); - os.put(u.c[6]); - os.put(u.c[5]); - os.put(u.c[4]); - os.put(u.c[3]); - os.put(u.c[2]); - os.put(u.c[1]); - os.put(u.c[0]); - } - - inline void writeByteArray(const void *buf, size_t length) { - os.put(GLOBAL); - os << "__builtin__\nbytearray\n"; - os.put(BINPUT); - os.put(1); - writeString(static_cast(buf), length); - os.put(TUPLE1); - os.put(REDUCE); - } - -protected: - inline void putInt16(uint16_t i) { - os.put( i & 0xff); - os.put( i >> 8 ); - } - - inline void putInt32(uint32_t i) { - os.put( i & 0xff); - os.put((i >> 8) & 0xff); - os.put((i >> 16) & 0xff); - os.put( i >> 24 ); - } - - template< class T > - inline void writeLong(T l) { - os.put(LONG1); - - if (l == 0) { - os.put(0); - return; - } - - // Same as l >> (8 * sizeof l), but without the warnings - T sign; - if (std::numeric_limits::is_signed) { - sign = l < 0 ? ~0 : 0; - } else { - sign = 0; - } - - T sl = l; - unsigned c = 0; - do { - ++c; - } while (sl >>= 8 != sign); - - // Add an extra byte if sign bit doesn't match - if (((l >> (8 * c - 1)) & 1) != ((l >> (8 * sizeof l - 1)) & 1)) { - ++c; - } - os.put(c); - - for (unsigned i = 0; i < c; ++ i) { - os.put(l & 0xff); - l >>= 8; - } - } -}; - -#endif /* _Pickle_HPP_ */