19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is part of the ustl library, an STL implementation. 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net> 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// This file is free software, distributed under the MIT License. 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \file uctrstrm.h 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Serialization templates for standard containers. 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Because containers are templates, a single operator>> is impossible. 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Making virtual read/write is also impossible because not all containers 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// contain serializable elements. Therefore, use the macros in this file. 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifndef UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define UCTRSTRM_H_75B2C3EA4980DDDC6B6DFFF767A3B7AC 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "mistream.h" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "sostream.h" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "uiosfunc.h" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace ustl { 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Macros for easily declaring a container streamable. 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Declares container template \p type streamable. 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Use TEMPLATE_TYPE and TEMPLATE_DECL macros to pass in templated 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// type with commas and the template declaration. 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define STD_TEMPLATE_CTR_STREAMABLE(type, template_decl) \ 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline istream& operator>> (istream& is, type& v) \ 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (container_read (is, v)); } \ 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline ostream& operator<< (ostream& os, const type& v) \ 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (container_write (os, v)); } \ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline ostringstream& operator<< (ostringstream& os, const type& v) \ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (container_text_write (os, v)); } \ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline size_t stream_size_of (const type& v) \ 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (container_stream_size (v)); } 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Declares non-resizable container template \p type streamable. 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define STD_TEMPLATE_NR_CTR_STREAMABLE(type, template_decl) \ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline istream& operator>> (istream& is, type& v) \ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (nr_container_read (is, v)); } \ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline ostream& operator<< (ostream& os, const type& v) \ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (nr_container_write (os, v)); } \ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline ostringstream& operator<< (ostringstream& os, const type& v) \ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (container_text_write (os, v)); } \ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project template_decl \ 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inline size_t stream_size_of (const type& v) \ 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { return (nr_container_stream_size (v)); } 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Fixed size container serialization. 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads fixed size container \p v from stream \p is. 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline istream& nr_container_read (istream& is, Container& v) 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foreach (typename Container::iterator, i, v) 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project is >> *i; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (is); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes fixed size container \p v into stream \p os. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ostream& nr_container_write (ostream& os, const Container& v) 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foreach (typename Container::const_iterator, i, v) 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << *i; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (os); 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Computes the stream size of a fixed size standard container. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t nr_container_stream_size (const Container& v) 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::const_iterator vciter_t; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename iterator_traits<vciter_t>::value_type value_type; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t s = 0; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (numeric_limits<value_type>::is_integral) 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s += v.size() * stream_size_of(value_type()); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project foreach (vciter_t, i, v) 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s += stream_size_of(*i); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (s); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Resizable container serialization. 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Reads container \p v from stream \p is. 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectistream& container_read (istream& is, Container& v) 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::value_type value_type; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::iterator iterator; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::written_size_type written_size_type; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project written_size_type n; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project is >> n; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t expectedSize = n * stream_size_of(value_type()); 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !PLATFORM_ANDROID 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project is.verify_remaining ("read", typeid(v).name(), expectedSize); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alignof(value_type()) > alignof(n)) 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project is >> ios::talign<value_type>(); 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project v.resize (n); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nr_container_read (is, v); 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project is >> ios::talign<written_size_type>(); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (is); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes the vector to stream \p os. 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectostream& container_write (ostream& os, const Container& v) 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::value_type value_type; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::written_size_type written_size_type; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const written_size_type sz (v.size()); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << sz; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alignof(value_type()) > alignof(sz)) 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << ios::talign<value_type>(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project nr_container_write (os, v); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << ios::talign<written_size_type>(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (os); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Computes the stream size of a standard container. 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsize_t container_stream_size (const Container& v) 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::value_type value_type; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typedef typename Container::written_size_type written_size_type; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const written_size_type sz (v.size()); 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size_t sizeSize = stream_size_of (sz); 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (alignof(value_type()) > alignof(sz)) 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sizeSize = Align (sizeSize, alignof(value_type())); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (Align (sizeSize + nr_container_stream_size (v), alignof(sz))); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// \brief Writes element \p v into stream \p os as text. 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Specialize to custom print elements. 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename T> 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectinline ostringstream& container_element_text_write (ostringstream& os, const T& v) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ return (os << v); } 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/// Writes container \p v into stream \p os as text. 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttemplate <typename Container> 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectostringstream& container_text_write (ostringstream& os, const Container& v) 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project typename Container::const_iterator i = v.begin(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << '('; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (i < v.end()) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project container_element_text_write (os, *i); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (++i >= v.end()) break; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << ','; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project os << ')'; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (os); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//---------------------------------------------------------------------- 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} // namespace ustl 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 178