data.h

Go to the documentation of this file.
00001 ///
00002 /// \file       data.h
00003 ///             Class to deal with pre-saved data files
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #ifndef __SB_DATA_H__
00023 #define __SB_DATA_H__
00024 
00025 #include "dll.h"
00026 #include <iosfwd>
00027 #include <vector>
00028 #include <string>
00029 #include <stdint.h>
00030 
00031 namespace Barry {
00032 
00033 class BXEXPORT Data
00034 {
00035         unsigned char *m_memBlock;      //< pointer to full memory block
00036                                         //< can be null if external
00037         size_t m_blockSize;             //< size of m_memBlock buffer allocated
00038 
00039         unsigned char *m_dataStart;     //< pointer to start of internal data
00040                                         //< can be null if external, and can
00041                                         //< start somewhere in the middle of
00042                                         //< m_memBlock if internal with a
00043                                         //< prepend buffer
00044 
00045         size_t m_dataSize;              //< number of bytes of actual data
00046 
00047         // copy on write feature
00048         const unsigned char *m_externalData;
00049         bool m_external;
00050 
00051         // meta data
00052         int m_endpoint;
00053 
00054         // output format flags
00055         static bool bPrintAscii;
00056 
00057 protected:
00058         void MakeSpace(size_t desiredsize, size_t desiredprepend = 0);
00059         size_t AvailablePrependSpace() const;
00060 
00061 public:
00062         Data();
00063         explicit Data(int endpoint, size_t startsize = 0x4000, size_t prependsize = 0x100);
00064         Data(const void *ValidData, size_t size);
00065         Data(const Data &other);
00066         ~Data();
00067 
00068         void InputHexLine(std::istream &is);
00069         void DumpHexLine(std::ostream &os, size_t index, size_t size) const;
00070         void DumpHex(std::ostream &os) const;
00071 
00072         int GetEndpoint() const { return m_endpoint; }
00073 
00074         const unsigned char * GetData() const { return m_external ? m_externalData : m_dataStart; }
00075         size_t GetSize() const { return m_dataSize; }
00076 
00077         unsigned char * GetBuffer(size_t requiredsize = 0);
00078         /// Returns size of buffer returned by GetBuffer()
00079         size_t GetBufSize() const;
00080         void ReleaseBuffer(int datasize = -1);
00081 
00082         void AppendHexString(const char *str);
00083 
00084         /// set buffer to 0 size, but don't bother overwriting memory with 0
00085         void QuickZap() { m_dataSize = 0; }
00086         void Zap();     // does a memset too
00087 
00088         Data& operator=(const Data &other);
00089 
00090 
00091         //
00092         // Utility functions
00093         //
00094         // Writing data... basically does a memcpy(dst,src,sizeof(src))
00095         // for each type.  Does no endian conversions.
00096         // dst is calculated as buffer + offset.
00097         // The buffer is expanded automatically if needed.
00098         // The offset is advanced by the size of the data.
00099         // GetSize() will increase automatically if the result of
00100         // the MemCpy() goes beyond the existing data size.
00101         //
00102         void MemCpy(size_t &offset, const void *src, size_t size);
00103         void Append(const void *buf, size_t size);
00104         void Prepend(const void *buf, size_t size);
00105         void Prechop(size_t size);
00106         template <class ValueT>
00107         void SetValue(size_t &offset, ValueT value)
00108         {
00109                 this->MemCpy(offset, &value, sizeof(value));
00110         }
00111 
00112 
00113         // static functions
00114         static void PrintAscii(bool setting) { bPrintAscii = setting; }
00115         static bool PrintAscii() { return bPrintAscii; }
00116 };
00117 
00118 BXEXPORT std::istream& operator>> (std::istream &is, Data &data);
00119 BXEXPORT std::ostream& operator<< (std::ostream &os, const Data &data);
00120 
00121 
00122 class BXEXPORT Diff
00123 {
00124         const Data &m_old, &m_new;
00125 
00126         BXLOCAL void Compare(std::ostream &os, size_t index, size_t size) const;
00127 
00128 public:
00129         Diff(const Data &old, const Data &new_);
00130 
00131         void Dump(std::ostream &os) const;
00132 };
00133 
00134 BXEXPORT std::ostream& operator<< (std::ostream &os, const Diff &diff);
00135 
00136 
00137 // utility functions
00138 BXEXPORT bool LoadDataArray(const std::string &filename, std::vector<Data> &array);
00139 BXEXPORT bool ReadDataArray(std::istream &is, std::vector<Data> &array);
00140 
00141 
00142 //
00143 // DBData
00144 //
00145 /// Database record data class.  The purpose of this class is to contain
00146 /// the raw data that flows between low level activity such as device
00147 /// read/writes, backup read/writes, and record parsing.
00148 ///
00149 /// This class contains the low level record data block, unparsed, as well
00150 /// as the surrounding meta data, such as the database name it belongs
00151 /// to, the Unique ID, the Rec Type, and format version/type based on what
00152 /// commands were used to extract the data from the device. (When using
00153 /// newer commands, the format of the records, potentially including the
00154 /// individual field type codes, are different.)
00155 ///
00156 /// Possible bi-directional data flow in all of Barry:
00157 /// Note that this class, DBData, represents the data+meta stage.
00158 ///
00159 ///     data+meta <-> device
00160 ///     data+meta <-> backup file
00161 ///     data+meta <-> record object
00162 ///     record object <-> boost serialization
00163 ///     contact record object <-> ldif
00164 ///
00165 /// Possible uni-directional data flow in all of Barry:
00166 ///
00167 ///     record object -> text dump
00168 ///
00169 class BXEXPORT DBData
00170 {
00171 public:
00172         enum RecordFormatVersion
00173         {
00174                 REC_VERSION_1,
00175                 REC_VERSION_2
00176         };
00177 
00178 private:
00179         // record meta data
00180         RecordFormatVersion m_version;
00181         std::string m_dbName;
00182         uint8_t m_recType;
00183         uint32_t m_uniqueId;
00184         size_t m_offset;
00185 
00186         // the raw data block, internal
00187         Data *m_localData;
00188 
00189         // the data block to use... could be external or internal,
00190         // and does not change for the life of the object
00191         Data &m_data;
00192 
00193 public:
00194         /// Default constructor, constructs an empty local Data object
00195         DBData();
00196 
00197         /// Copy constructor - always creates an internal Data object, and
00198         /// uses Data object's copy constructor to make it.
00199         /// Copies all meta data as well.
00200         /// If you want to optimize the copy, use one of the constructors
00201         /// below.
00202         DBData(const DBData &other);
00203 
00204         /// Constructs a local Data object that points to external memory
00205         DBData(const void *ValidData, size_t size);
00206         DBData(RecordFormatVersion ver, const std::string &dbName,
00207                 uint8_t recType, uint32_t uniqueId, size_t offset,
00208                 const void *ValidData, size_t size);
00209 
00210         /// If copy == false, constructs an external Data object, no local.
00211         /// If copy == true, constructs an internal Data object copy
00212         /// For speed, set copy to false.
00213         /// If you want Copy On Write behaviour, similar to Data(buf,size),
00214         /// then use the above (buf, size) constructor, not this one,
00215         /// since this constructor uses Data's copy constructor.
00216         DBData(Data &externalData, bool copy);
00217         DBData(RecordFormatVersion ver, const std::string &dbName,
00218                 uint8_t recType, uint32_t uniqueId, size_t offset,
00219                 Data &externalData, bool copy);
00220 
00221         ~DBData();
00222 
00223         // access meta data
00224         RecordFormatVersion GetVersion() const { return m_version; }
00225         const std::string& GetDBName() const { return m_dbName; }
00226         uint8_t GetRecType() const { return m_recType; }
00227         uint32_t GetUniqueId() const { return m_uniqueId; }
00228         size_t GetOffset() const { return m_offset; }
00229 
00230         const Data& GetData() const { return m_data; }
00231         Data& UseData();
00232 
00233         // operations
00234         void SetVersion(RecordFormatVersion ver)
00235         {
00236                 m_version = ver;
00237         }
00238 
00239         void SetDBName(const std::string &dbName)
00240         {
00241                 m_dbName = dbName;
00242         }
00243 
00244         void SetIds(uint8_t recType, uint32_t uniqueId)
00245         {
00246                 m_recType = recType;
00247                 m_uniqueId = uniqueId;
00248         }
00249 
00250         void SetOffset(size_t offset)
00251         {
00252                 m_offset = offset;
00253         }
00254 
00255         void CopyMeta(const DBData &src)
00256         {
00257                 m_version = src.m_version;
00258                 m_dbName = src.m_dbName;
00259                 m_recType = src.m_recType;
00260                 m_uniqueId = src.m_uniqueId;
00261                 m_offset = src.m_offset;
00262         }
00263 
00264         DBData& operator=(const DBData &other);
00265 };
00266 
00267 } // namespace Barry
00268 
00269 #endif
00270