# 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-2011, 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_data;
    00036         size_t m_bufsize;               //< size of m_data buffer allocated
    00037         size_t m_datasize;              //< number of bytes of actual data
    00038         int m_endpoint;
    00039
    00040         // copy on write feature
    00041         const unsigned char *m_externalData;
    00042         bool m_external;
    00043
    00044         // output format flags
    00045         static bool bPrintAscii;
    00046
    00047 protected:
    00048         void MakeSpace(size_t desiredsize);
    00049         void CopyOnWrite(size_t desiredsize);
    00050
    00051 public:
    00052         Data();
    00053         explicit Data(int endpoint, size_t startsize = 0x4000);
    00054         Data(const void *ValidData, size_t size);
    00055         Data(const Data &other);
    00056         ~Data();
    00057
    00058         void InputHexLine(std::istream &is);
    00059         void DumpHexLine(std::ostream &os, size_t index, size_t size) const;
    00060         void DumpHex(std::ostream &os) const;
    00061
    00062         int GetEndpoint() const { return m_endpoint; }
    00063
    00064         const unsigned char * GetData() const { return m_external ? m_externalData : m_data; }
    00065         size_t GetSize() const { return m_datasize; }
    00066
    00067         unsigned char * GetBuffer(size_t requiredsize = 0);
    00068         size_t GetBufSize() const { return m_bufsize; }
    00069         void ReleaseBuffer(int datasize = -1);
    00070
    00071         void AppendHexString(const char *str);
    00072
    00073         /// set buffer to 0 size, but don't bother overwriting memory with 0
    00074         void QuickZap() { m_datasize = 0; }
    00075         void Zap();     // does a memset too
    00076
    00077         Data& operator=(const Data &other);
    00078
    00079
    00080         //
    00081         // Utility functions
    00082         //
    00083         // Writing data... basically does a memcpy(dst,src,sizeof(src))
    00084         // for each type.  Does no endian conversions.
    00085         // dst is calculated as buffer + offset.
    00086         // The buffer is expanded automatically if needed.
    00087         // The offset is advanced by the size of the data.
    00088         //
    00089         void MemCpy(size_t &offset, const void *src, size_t size);
    00090         void Append(const void *buf, size_t size);
    00091         template <class ValueT>
    00092         void SetValue(size_t &offset, ValueT value)
    00093         {
    00094                 this->MemCpy(offset, &value, sizeof(value));
    00095         }
    00096
    00097
    00098         // static functions
    00099         static void PrintAscii(bool setting) { bPrintAscii = setting; }
    00100         static bool PrintAscii() { return bPrintAscii; }
    00101 };
    00102
    00103 BXEXPORT std::istream& operator>> (std::istream &is, Data &data);
    00104 BXEXPORT std::ostream& operator<< (std::ostream &os, const Data &data);
    00105
    00106
    00107 class BXEXPORT Diff
    00108 {
    00109         const Data &m_old, &m_new;
    00110
    00111         BXLOCAL void Compare(std::ostream &os, size_t index, size_t size) const;
    00112
    00113 public:
    00114         Diff(const Data &old, const Data &new_);
    00115
    00116         void Dump(std::ostream &os) const;
    00117 };
    00118
    00119 BXEXPORT std::ostream& operator<< (std::ostream &os, const Diff &diff);
    00120
    00121
    00122 // utility functions
    00123 BXEXPORT bool LoadDataArray(const std::string &filename, std::vector<Data> &array);
    00124 BXEXPORT bool ReadDataArray(std::istream &is, std::vector<Data> &array);
    00125
    00126
    00127 //
    00128 // DBData
    00129 //
    00130 /// Database record data class.  The purpose of this class is to contain
    00131 /// the raw data that flows between low level activity such as device
    00132 /// read/writes, backup read/writes, and record parsing.
    00133 ///
    00134 /// This class contains the low level record data block, unparsed, as well
    00135 /// as the surrounding meta data, such as the database name it belongs
    00136 /// to, the Unique ID, the Rec Type, and format version/type based on what
    00137 /// commands were used to extract the data from the device. (When using
    00138 /// newer commands, the format of the records, potentially including the
    00139 /// individual field type codes, are different.)
    00140 ///
    00141 /// Possible bi-directional data flow in all of Barry:
    00142 /// Note that this class, DBData, represents the data+meta stage.
    00143 ///
    00144 ///     data+meta <-> device
    00145 ///     data+meta <-> backup file
    00146 ///     data+meta <-> record object
    00147 ///     record object <-> boost serialization
    00148 ///     contact record object <-> ldif
    00149 ///
    00150 /// Possible uni-directional data flow in all of Barry:
    00151 ///
    00152 ///     record object -> text dump
    00153 ///
    00154 class BXEXPORT DBData
    00155 {
    00156 public:
    00157         enum RecordFormatVersion
    00158         {
    00159                 REC_VERSION_1,
    00160                 REC_VERSION_2
    00161         };
    00162
    00163 private:
    00164         // record meta data
    00165         RecordFormatVersion m_version;
    00166         std::string m_dbName;
    00167         uint8_t m_recType;
    00168         uint32_t m_uniqueId;
    00169         size_t m_offset;
    00170
    00171         // the raw data block, internal
    00172         Data *m_localData;
    00173
    00174         // the data block to use... could be external or internal,
    00175         // and does not change for the life of the object
    00176         Data &m_data;
    00177
    00178 public:
    00179         /// Default constructor, constructs an empty local Data object
    00180         DBData();
    00181
    00182         /// Constructs a local Data object that points to external memory
    00183         DBData(const void *ValidData, size_t size);
    00184         DBData(RecordFormatVersion ver, const std::string &dbName,
    00185                 uint8_t recType, uint32_t uniqueId, size_t offset,
    00186                 const void *ValidData, size_t size);
    00187
    00188         /// If copy == false, constructs an external Data object, no local.
    00189         /// If copy == true, constructs an internal Data object copy
    00190         /// For speed, set copy to false.
    00191         /// If you want Copy On Write behaviour, similar to Data(buf,size),
    00192         /// then use the above (buf, size) constructor, not this one,
    00193         /// since this constructor uses Data's copy constructor.
    00194         DBData(Data &externalData, bool copy);
    00195         DBData(RecordFormatVersion ver, const std::string &dbName,
    00196                 uint8_t recType, uint32_t uniqueId, size_t offset,
    00197                 Data &externalData, bool copy);
    00198
    00199         ~DBData();
    00200
    00201         // access meta data
    00202         RecordFormatVersion GetVersion() const { return m_version; }
    00203         const std::string& GetDBName() const { return m_dbName; }
    00204         uint8_t GetRecType() const { return m_recType; }
    00205         uint32_t GetUniqueId() const { return m_uniqueId; }
    00206         size_t GetOffset() const { return m_offset; }
    00207
    00208         const Data& GetData() const { return m_data; }
    00209         Data& UseData();
    00210
    00211         // operations
    00212         void SetVersion(RecordFormatVersion ver)
    00213         {
    00214                 m_version = ver;
    00215         }
    00216
    00217         void SetDBName(const std::string &dbName)
    00218         {
    00219                 m_dbName = dbName;
    00220         }
    00221
    00222         void SetIds(uint8_t recType, uint32_t uniqueId)
    00223         {
    00224                 m_recType = recType;
    00225                 m_uniqueId = uniqueId;
    00226         }
    00227
    00228         void SetOffset(size_t offset)
    00229         {
    00230                 m_offset = offset;
    00231         }
    00232
    00233         void CopyMeta(const DBData &src)
    00234         {
    00235                 m_version = src.m_version;
    00236                 m_dbName = src.m_dbName;
    00237                 m_recType = src.m_recType;
    00238                 m_uniqueId = src.m_uniqueId;
    00239                 m_offset = src.m_offset;
    00240         }
    00241
    00242         DBData& operator=(const DBData &other);
    00243 };
    00244
    00245 } // namespace Barry
    00246
    00247 #endif
    00248