[Jahshaka-cvs] openlibraries/src/openassetlib/al binary_object_serializer.cpp, NONE, 1.1 binary_ob
Status: Beta
Brought to you by:
jahshaka
From: Julian N. <non...@us...> - 2006-07-17 15:49:58
|
Update of /cvsroot/openlibraries/openlibraries/src/openassetlib/al In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv6406/src/openassetlib/al Added Files: binary_object_serializer.cpp binary_object_serializer.hpp Log Message: Forgot to add these on the first checkin today! --- NEW FILE: binary_object_serializer.hpp --- #ifndef BINARY_OBJECT_SERIALIZER_INC_ #define BINARY_OBJECT_SERIALIZER_INC_ #include <openpluginlib/pl/utf8_utils.hpp> namespace opl = olib::openpluginlib; namespace olib { namespace openassetlib { class binary_object_serializer { public: static char* serialize(const unsigned char* object, size_t numbytes, size_t* numbytes_returned); static unsigned char* deserialize(const char* strobject, size_t* numbytes_returned); private: binary_object_serializer(void); ~binary_object_serializer(void); }; }} #endif --- NEW FILE: binary_object_serializer.cpp --- #include <openassetlib/al/binary_object_serializer.hpp> namespace olib { namespace openassetlib { #ifdef _MSC_VER #pragma warning ( push ) #pragma warning ( disable: 4244 ) #endif namespace { /* The following two routines are taken from the Postgres 7.4RC2 code */ /* base. Added here (a) since we want to build for versions prior to */ /* 7.3 and (b) there is a possible allocate/release problem on windows */ /* The license for this code is reproduced below. */ // PostgreSQL Database Management System // (formerly known as Postgres, then as Postgres95) // // Portions Copyright (c) 1996-2003, The PostgreSQL Global Development Group // // Portions Copyright (c) 1994, The Regents of the University of California // // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose, without fee, and without a written agreement // is hereby granted, provided that the above copyright notice and this // paragraph and the following two paragraphs appear in all copies. // // IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR // DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING // LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS // DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // // THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY // AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS // ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // /* * PQescapeBytea - converts from binary string to the * minimal encoding necessary to include the string in an SQL * INSERT statement with a bytea type column as the target. * * The following transformations are applied * '\0' == ASCII 0 == \\000 * '\'' == ASCII 39 == \' * '\\' == ASCII 92 == \\\\ * anything >= 0x80 ---> \\ooo (where ooo is an octal expression) */ unsigned char * escapeBinary(const unsigned char *bintext, size_t binlen, size_t *bytealen) { const unsigned char *vp; unsigned char *rp; unsigned char *result; size_t i; size_t len; /* * empty string has 1 char ('\0') */ len = 1; vp = bintext; for (i = binlen; i > 0; i--, vp++) { if (*vp == 0 || *vp >= 0x80) len += 5; /* '5' is for '\\ooo' */ else if (*vp == '\'') len += 2; else if (*vp == '\\') len += 4; else len++; } rp = result = (unsigned char *) malloc(len); if (rp == NULL) return NULL; vp = bintext; *bytealen = len; for (i = binlen; i > 0; i--, vp++) { if (*vp == 0 || *vp >= 0x80) { (void) sprintf((char *)rp, "\\\\%03o", *vp); rp += 5; } else if (*vp == '\'') { rp[0] = '\\'; rp[1] = '\''; rp += 2; } else if (*vp == '\\') { rp[0] = '\\'; rp[1] = '\\'; rp[2] = '\\'; rp[3] = '\\'; rp += 4; } else *rp++ = *vp; } *rp = '\0'; return result; } #define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3') #define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7') #define OCTVAL(CH) ((CH) - '0') /* * PQunescapeBytea - converts the null terminated string representation * of a bytea, strtext, into binary, filling a buffer. It returns a * pointer to the buffer (or NULL on error), and the size of the * buffer in retbuflen. The pointer may subsequently be used as an * argument to the function free(3). It is the reverse of PQescapeBytea. * * The following transformations are made: * \\ == ASCII 92 == \ * \ooo == a byte whose value = ooo (ooo is an octal number) * \x == x (x is any character not matched by the above transformations) */ unsigned char * unescapeBinary(const unsigned char *strtext, size_t *retbuflen) { size_t strtextlen, buflen; unsigned char *buffer, *tmpbuf; size_t i, j; if (strtext == NULL) return NULL; strtextlen = strlen((const char *)strtext); /* * Length of input is max length of output, but add one to avoid * unportable malloc(0) if input is zero-length. */ buffer = (unsigned char *) malloc(strtextlen + 1); if (buffer == NULL) return NULL; for (i = j = 0; i < strtextlen; ) { switch (strtext[i]) { case '\\': i++; if (strtext[i] == '\\') buffer[j++] = strtext[i++]; else { if ((ISFIRSTOCTDIGIT(strtext[i])) && (ISOCTDIGIT(strtext[i + 1])) && (ISOCTDIGIT(strtext[i + 2]))) { int byte; byte = OCTVAL(strtext[i++]); byte = (byte << 3) + OCTVAL(strtext[i++]); byte = (byte << 3) + OCTVAL(strtext[i++]); buffer[j++] = byte; } } /* * Note: if we see '\' followed by something that isn't * a recognized escape sequence, we loop around having * done nothing except advance i. Therefore the something * will be emitted as ordinary data on the next cycle. * Corner case: '\' at end of string will just be discarded. */ break; default: buffer[j++] = strtext[i++]; break; } } buflen = j; /* buflen is the length of the dequoted * data */ /* Shrink the buffer to be no larger than necessary */ /* +1 avoids unportable behavior when buflen==0 */ tmpbuf = (unsigned char *)realloc(buffer, buflen + 1); /* It would only be a very brain-dead realloc that could fail, but... */ if (!tmpbuf) { free(buffer); return NULL; } *retbuflen = buflen; return tmpbuf; } } #ifdef _MSC_VER #pragma warning ( pop ) #endif binary_object_serializer::binary_object_serializer(void) { } binary_object_serializer::~binary_object_serializer(void) { } char* binary_object_serializer::serialize(const unsigned char* object, size_t numbytes, size_t* numbytes_returned) { return (char*)escapeBinary(object, numbytes, numbytes_returned); } unsigned char* binary_object_serializer::deserialize(const char* strobject, size_t* numbytes_returned) { return unescapeBinary((const unsigned char*)strobject, numbytes_returned); } }} |