main.cpp

 /* 
PT Extensions
    Copyright (C) 2004  Phyrstorm Technologies, Inc.
Copyright (C) 2004  Nate Davis <nate@phyrtech.com>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#define USING_ALL_EXTENSIONS //tell the PT extension module that we are using all extensions

#include <iostream>
#include "PT_Extension.h"

/*
stl_serialize/stl_unserialize

  This portion of PTExtensions library provides an efficient way to serialize
  and unserialize objects. Provided is an example of a proper and improper
  serialization method.

  NOTE: intuitive handling is required to allow structures with pointers in them
  to be serialized.  Essentially, each object within a structure that contains
  a pointer or is a pointer needs to be serialized seperately and then appended
  in a uniform way to the serial string.
*/

struct serializable {
int Integer;
double Double;
bool Bool;
long Long;
char Char;
};

struct erroneous {
int Integer;
double Double;
bool Bool;
long Long;
char *CharPointer; //when you serialize this, it places the memory address value into the serial, not the actual data
};

int main(int argc, char** argv) {
/*
stl_serialize
stl_unserialize

NOTE: this example will work because none of the data members contain pointers to data
*/

std::cout << "Testing serializable structure\n------------------------------" << std::endl;

serializable s;
s.Integer = 10;
s.Double = 14.2323;
s.Bool = false;
s.Long = 23892374;
s.Char = 'a';

std::string serial = stl_serialize<serializable>(&s);
std::cout << "serial: " << serial << std::endl;
//at this point, you could save this literal string to a text or binary file for later recovery
serializable new_s;
stl_unserialize(&new_s, serial);
if(s.Integer != new_s.Integer)
std::cout << "Error: member Integer was not correctly reinstated" << std::endl;
else if(s.Double != new_s.Double)
std::cout << "Error: member Double was not correctly reinstated" << std::endl;
else if(s.Bool != new_s.Bool)
std::cout << "Error: member Bool was not correctly reinstated" << std::endl;
else if(s.Long != new_s.Long)
std::cout << "Error: member Long was not correctly reinstated" << std::endl;
else if(s.Char != new_s.Char)
std::cout << "Error: member Char was not correctly reinstated" << std::endl;
else
std::cout << "Values copied to new structure correctly" << std::endl;

/*
NOTE: this example will invariably fail because the member CharPointer
will be recorded within the serial as the memory reference, not as the
actual data the char* points to.
*/

std::cout << std::endl << "Testing erroneous structure\n---------------------------" << std::endl;

erroneous e;
e.Integer = 10;
e.Double = 14.2323;
e.Bool = false;
e.Long = 23892374;
e.CharPointer = new char[7];

//copy the string "string" into the char pointer
memcpy(e.CharPointer, "string\0", 7);

serial = stl_serialize<erroneous>(&e);
std::cout << "serial: " << serial << std::endl;

//we delete the old char pointer so that it's obvious the memory is no longer there
//NOTE: if you do copy the serialized data back into an object, the object MAY act
// as you expect it to.  It WILL lead to data corruption if you use this method
// in practice.
delete []&e.CharPointer;

erroneous new_e;
stl_unserialize(&new_e, serial);

if(e.Integer != new_e.Integer)
std::cout << "Error: member Integer was not correctly reinstated" << std::endl;
else if(e.Double != new_e.Double)
std::cout << "Error: member Double was not correctly reinstated" << std::endl;
else if(e.Bool != new_e.Bool)
std::cout << "Error: member Bool was not correctly reinstated" << std::endl;
else if(e.Long != new_e.Long)
std::cout << "Error: member Long was not correctly reinstated" << std::endl;
else if(e.CharPointer != e.CharPointer) //notice, this works because technically, the pointers still point to the same place
std::cout << "Error: member CharPointer was not correctly reinstated" << std::endl;
else if(!strcmp(e.CharPointer, new_e.CharPointer)) //notice, this will most likely cause an illegal operation
std::cout << "strcmp() failed" << std::endl;
else
std::cout << "The impossible has occured, buy a new computer" << std::endl;
return 0;
}

Project Homepage: