Lecture2

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: idea so long as used uniformly in a code base and all developers involved understand them Cons: no free lunch, s6ll need to understand underlying memory management concepts, plus smart pointers introduce their own complexi6es; bad idea to mix code that uses smart pointers with code that doesn’t (very confusing) Since this is a “DIY” class and you need to understand memory management anyway, we’ll forego smart pointers Serializa6on/Deserializa6on Serializa,on (aka marshalling): conversion of data structure or object into format that can be stored (e.g., in file or memory buffer, or transmiUed on network) and deserialized (or unmarshalled) later to recover data structure/object As with memory management and smart pointers, some standard facili6es (e.g., Boost serializa6on library) exist to help with this But in the spirit of DIY (and avoiding going deeply into Boost libraries), we’ll do it ourselves in this class Primi6ve for Serializa6on: memcpy Given a structure Foo, how to serialize Foo into a byte ­buffer? struct Foo { int x; float y; } f1 = {1, 0.5}; char buffer[128]; memcpy(buffer, &f1, sizeof(f1)); How to deserialize? Use memcpy again: struct Foo f2; memcpy(&f2, buffer, sizeof(f2)); Serializa6on Gotchas One problem with preceding approach: deserializing Foo on another machine may not work properly  ­ endianness issues  ­ size of data types (32 ­bit vs. 64 ­bit vs. ...) We’ll ignore this issue for DavisDB (single ­machine) Second problem: versioning. Suppose a later version of code adds a third field to Foo. What can go wrong? We’ll ignore this issue too for DavisDB (single ­version) Third problem, this one we do need to worry about for DavisDB: memcpy of the structure only works for “plain old data”... What’s Wrong Here? struct Bar { int x; char* str; }; char buffer[128]; char str = new char[64]; sprintf(str, “hello, world!”); struct Bar bar = {1, str}; memcpy(buffer, &bar, sizeof(bar)); delete str; ... memcpy(&bar, buffer, sizeof(bar)); What’s Wrong Here? struct Bar { int x; char* str; // structure is not “plain old data” }; char buffer[128]; char str = new char[64]; sprintf(str, “hello, world!”); struct Bar bar = {1, str}; memcpy(buffer, &bar, sizeof(bar)); delete str; ... memcpy(&bar, buffer, sizeof(bar)); // bar will have // bad str // pointer The Fix: Custom Serialize/Deserialize Methods class Bar { int x; char* str = 0; void serialize(char* buffer) { memcpy(buffer, &x, sizeof(x)); int len = strlen(str); memcpy(buffer+sizeof(x), &len, sizeof(len)); memcpy(buffer+sizeof(x)+sizeof(len), str, len*sizeof(char)); } static Bar* deserialize(char* buffer) { Bar* bar = new Bar(); memcpy(&(bar->x), buffer, sizeof(bar->x)); int len; memcpy(&len, buffer+sizeof(bar->x), sizeof(len)); bar->str = new char[len+1]; memcpy(bar->str, buffer+sizeof(bar->x)+sizeof(len), len*sizeof(char)); } ... }; The Fix: Custom Serialize/Deserialize Methods Usage: Bar b; b.x = 1; b.str = “hello, world!”; char buffer[128]; b.serialize(buffer); ... Bar* c = Bar::deserialize(buffer, &c); ... delete c; The Fix: Custom Serialize/Deserialize Methods Code can be greatly simplified using buffer that automa6cally keeps track of read/write posi6on: i.e., behaves like a stream void serialize(char* buffer) { memcpy(buffer, &x, sizeof(x)); int len = strlen(str); memcpy(buffer+sizeof(x), &len, sizeof(len)); memcpy(buffer+sizeof(x)+sizeof(len), str, len*sizeof(char)); } becomes void serialize(Bytestream* buffer) { buffer->write(&x, sizeof(x)); int len = strlen(str); buffer->write(&len, sizeof(len)); buffer->write(str, len*sizeof(char)); } part of homework will ask you to write such a Bytestream class...
View Full Document

This document was uploaded on 03/12/2014 for the course CSCI 165B at UC Davis.

Ask a homework question - tutors are online