Search:
|
Access:
» Save Your Data: an introduction to libs11nRelated categories: C/C++ | Programming in generall | Frameworks Stephan BealViewed: 3685 | Article date: 2006-04-20 14:58:24 The s11n (serialization) framework empowers near-arbitrary C++ objects with serialization support for. Rather than repeat even a small fraction of the more than 150 pages of documentation which ships with s11n. In the article, Stephen will present a short introduction to what s11n is and what it can do for your C++ applications.
The s11n ("serialization") framework empowers near-arbitrary C++ objects with serialization support for. Rather than repeat even a small fraction of the more than 150 pages of documentation which ships with s11n, we're going to present a short introduction to what s11n is and what it can do for your C++ applications. Here we cover material applicable to both the 1.0.x "stable" releases and the newer (highly preferred) 1.1.x "development" releases. The 1.1 branch is expected to roll over to 1.2 "stable" in Q4/2005 or Q1/2006, and brings with it many improvements over 1.0.
About the authorStephan Beal has worked professionally with computers since 1994, and hobby-wise since Christmas of 1983. He typically spends all of his spare time developing software or reading about it, or designing boardgames and wargames for CounterMoves ("old-fashioned", pen-and-paper-and-dice games, not for the computer). To contact the author: http://s11n.net/home/stephan/ A common use case: STL containersEvery C++ developer out there has used the STL containers to hold objects. These core types are fundamental parts of many C++ projects, and the ability to save and load them generically is both very desirable and exceedingly tricky to achieve. Listing 1 shows an arbitrarily-chosen map type, a very common use case, which we will continue to use in later examples. Common use case: std::map<X,Y> typedef map<int,string> NumberMap; NumberMap numbers; numbers[0] = "zero"; numbers[1] = "one"; numbers[2] = "two"; ... How do we save and load such an object? In fact, we could write algorithms specifically for handling this map type. That would work, but would be inflexible: we would have to reimplement it for map<string,string>, even though it is "fundamentally" the same as map<int,string>. Rather than contemplate the thousands of ways to implement that, let's consider a much simpler solution: s11n. Here's how we would do it: s11nlite::save( numbers, "myfile.s11n" /* or an ostream */ ); Can't get much simpler than that. (In fact, i have left out some #includes, for the sake of saving space. The s11n documentation explains which headers you need.) On a technical level, loading is inherently much more difficult than saving. This is also the case in s11n, but only internally to s11n: for client code, loading is often a mirror-image of saving. In the case of our map, it's not quite mirror-image, but it's not far off: NumberMap * loaded = s11nlite::load_serializable<NumberMap>("myfile.s11n" /* or an istream */ ); We can also load data directly into an existing map, instead of creating a new one, but this requires another step: loading the data into an s11n-specific container, then into our map: auto_ptr<s11nlite::node_type> node( s11nlite::load_node( "myfile.s11n" ) ); if( ! node.get() ) { ... error ... } s11nlite::deserialize( *node, numbers ); Tip: the library manually demonstrates this in much more detail. When it comes to saving and loading STL containers, that's all there is to it. Some readers might be asking, though: what requirements are placed on the contained types? This is an excellent question. In short, the answer is: any type supported by s11n. What does that mean? It means: any type which we can tell s11n how to serialize. Teaching s11n how to serializeA little-known secret is that libs11n, which claims to be a master of serialization, doesn't actually know how to serialize anything. Instead, the library uses template-based techniques to register types with a serialization API, thereby promoting them to the status of Serializable. The registration process installs back-end types which provide, amongst other things two functors: serialize and a deserialize operators. The s11n core routes traffic through these functors to serialize any type which we register. That is how we define "any type which s11n knows how to handle." Polymorphism is supported for Serializables, but not required, and the de/serialize operators need not have any specific name, as long as their signatures are compatible. It is up to our functors to direct the core library to our client-side APIs. We won't show the full process of registering types here, because (a) it's explained in full detail in the library manual, (b) demonstrated many times over in the sample applications which come with the library, (c) the interest of space and brevity, and (d) the processes differ slightly between 1.0 and 1.1. We will say, however, that it is relatively painless, normally requiring a single call to a so-called "supermacro" - a header file which behaves like a macro (the library manual explains these in detail). The main implications of the functor/marshaler aspects of s11n's architecture is exemplified with another example: list<T> alist; ... populate alist ... s11nlite::save( alist, std::cout ); Your first question is certainly, "what is T?" That is indeed an important question, probably the most important question of this equation. Again, the answer is: any type which s11n knows how to handle. Thinking back to our first example, we then realize that T may be a NumberMap! Indeed, T may be an int, a char, a string... anything which we can tell s11n how to serialize, T may be. The library comes with support for all of the standard PODs and STL containers, so clients need to type in only a couple lines of code to work with those. Considering only the STL containers and common POD types (including std::string), the range of combinations which s11n handles is effectively unlimited. Consider the list type L, the map type M, and the arbitrary Serializable types A, B, and C. Given those, Listing 2 shows us just a tiny sample of types which s11n handle for us. Right out of the box, that's trillions, or more, combinations. Partial list of implied Serializable list/map types L<A> L<A*> L<L<B>> M<A,B> M<B,L<C>> M<C,L<M<A,B>>> M<C, M<A,L< M<A,B *> *> *>> Despite the breadth of possibilities, using s11n is child's play. What else can it do? When it comes to serializing data, s11n is specialized for the job, and can do quite a lot with quite little client-side effort. As we don't have space here to demonstrate more than the most high-level features of the library, we will instead summarize some of the library's main properties, features, and potential uses...
|
|
Copyright C 2006 by Software Developer's Journal. All rights reserved.





SDJ Users:
Shopping Cart









