Properties.hpp 6.76 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef PROPERTIES_HPP
#define PROPERTIES_HPP

20
#include <ndb_global.h>
21 22 23 24
#include <BaseString.hpp>
#include <UtilBuffer.hpp>

enum PropertiesType {
25 26 27 28
  PropertiesType_Uint32 = 0,
  PropertiesType_char = 1,
  PropertiesType_Properties = 2,
  PropertiesType_Uint64 = 3
29 30 31 32 33 34 35 36 37 38 39
};

/**
 * @struct  Property
 * @brief   Stores one (name, value)-pair
 * 
 * Value can be of type Properties, i.e. a Property may contain 
 * a Properties object.
 */
struct Property {
  Property(const char* name, Uint32 val);
40
  Property(const char* name, Uint64 val);
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
  Property(const char* name, const char * value);
  Property(const char* name, const class Properties * value);
  ~Property();
private:
  friend class Properties;
  struct PropertyImpl * impl;
};

/**
 * @class  Properties
 * @brief  Stores information in (name, value)-pairs
 */
class Properties {
public:
  static const char delimiter = ':';
  static const char version[];

58
  Properties(bool case_insensitive= false);
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
  Properties(const Properties &);
  Properties(const Property *, int len);
  virtual ~Properties();

  /**
   * Set/Get wheather names in the Properties should be compared 
   * w/o case.
   * NOTE: The property is automatically applied to all propoerties put
   *       into this after a called to setCaseInsensitiveNames has been made
   *       But properties already in when calling setCaseInsensitiveNames will
   *       not be affected
   */
  void setCaseInsensitiveNames(bool value);
  bool getCaseInsensitiveNames() const;

  /**
   * Insert an array of value(s)
   */
  void put(const Property *, int len);

  bool put(const char * name, Uint32 value, bool replace = false);
80
  bool put64(const char * name, Uint64 value, bool replace = false);
81 82 83 84 85 86 87 88 89
  bool put(const char * name, const char * value, bool replace = false);
  bool put(const char * name, const Properties * value, bool replace = false);

  /**
   * Same as put above,
   *   except that _%d (where %d is a number) is added to the name
   * Compare get(name, no)
   */
  bool put(const char *, Uint32 no, Uint32, bool replace = false);
90
  bool put64(const char *, Uint32 no, Uint64, bool replace = false);
91 92 93 94 95 96 97 98 99 100
  bool put(const char *, Uint32 no, const char *, bool replace = false);
  bool put(const char *, Uint32 no, const Properties *, bool replace = false);


  bool getTypeOf(const char * name, PropertiesType * type) const;

  /** @return true if Properties object contains name */
  bool contains(const char * name) const;

  bool get(const char * name, Uint32 * value) const;
101
  bool get(const char * name, Uint64 * value) const;
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
  bool get(const char * name, const char ** value) const;
  bool get(const char * name, BaseString & value) const;
  bool get(const char * name, const Properties ** value) const;
  
  bool getCopy(const char * name, char ** value) const;
  bool getCopy(const char * name, Properties ** value) const;

  /**
   * Same as get above
   *   except that _%d (where %d = no) is added to the name
   */
  bool getTypeOf(const char * name, Uint32 no, PropertiesType * type) const;
  bool contains(const char * name, Uint32 no) const;

  bool get(const char * name, Uint32 no, Uint32 * value) const;
117
  bool get(const char * name, Uint32 no, Uint64 * value) const;
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
  bool get(const char * name, Uint32 no, const char ** value) const;
  bool get(const char * name, Uint32 no, const Properties ** value) const;
  
  bool getCopy(const char * name, Uint32 no, char ** value) const;
  bool getCopy(const char * name, Uint32 no, Properties ** value) const;

  void clear();

  void remove(const char * name);
  
  void print(FILE * file = stdout, const char * prefix = 0) const;
  /**
   *  Iterator over names 
   */
  class Iterator { 
  public:
    Iterator(const Properties* prop);

    const char* first();
    const char* next();
  private:
    const Properties*  m_prop;
    Uint32 m_iterator;
  };
  friend class Properties::Iterator;

  Uint32 getPackedSize() const;
  bool pack(Uint32 * buf) const;
  bool pack(UtilBuffer &buf) const;
  bool unpack(const Uint32 * buf, Uint32 bufLen);
  bool unpack(UtilBuffer &buf);
  
  Uint32 getPropertiesErrno() const { return propErrno; }
  Uint32 getOSErrno() const { return osErrno; }
private:
  Uint32 propErrno;
  Uint32 osErrno;

  friend class PropertiesImpl;
  class PropertiesImpl * impl;
  class Properties * parent;

  void setErrno(Uint32 pErr, Uint32 osErr = 0) const ;
};

/**
 * Error code for properties
 */

/**
 * No error
 */
extern const Uint32 E_PROPERTIES_OK;

/**
 * Invalid name in put, names can not contain Properties::delimiter
 */
extern const Uint32 E_PROPERTIES_INVALID_NAME;

/**
 * Element did not exist when using get
 */
extern const Uint32 E_PROPERTIES_NO_SUCH_ELEMENT;

/**
 * Element had wrong type when using get
 */
extern const Uint32 E_PROPERTIES_INVALID_TYPE;

/**
 * Element already existed when using put, and replace was not specified
 */
extern const Uint32 E_PROPERTIES_ELEMENT_ALREADY_EXISTS;

/**
 * Invalid version on properties file you are trying to read
 */
extern const Uint32 E_PROPERTIES_INVALID_VERSION_WHILE_UNPACKING;

/**
 * When unpacking an buffer
 *  found that buffer is to short
 *
 * Probably an invlaid buffer
 */
extern const Uint32 E_PROPERTIES_INVALID_BUFFER_TO_SHORT;

/**
 * Error when packing, can not allocate working buffer
 *   
 * Note: OS error is set
 */
extern const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_PACKING;

/**
 * Error when unpacking, can not allocate working buffer
 *   
 * Note: OS error is set
 */
extern const Uint32 E_PROPERTIES_ERROR_MALLOC_WHILE_UNPACKING;

/**
 * Error when unpacking, invalid checksum
 *   
 */
extern const Uint32 E_PROPERTIES_INVALID_CHECKSUM;

/**
 * Error when unpacking
 *   No of items > 0 while size of buffer (left) <= 0
 */
extern const Uint32 E_PROPERTIES_BUFFER_TO_SMALL_WHILE_UNPACKING;

inline bool
Properties::unpack(UtilBuffer &buf) {
  return unpack((const Uint32 *)buf.get_data(), buf.length());
}

inline bool
Properties::pack(UtilBuffer &buf) const {
  Uint32 size = getPackedSize();
239 240 241
  void *tmp_buf = buf.append(size);
  if(tmp_buf == 0)
    return false;
242 243 244 245 246 247 248 249 250
  bool ret = pack((Uint32 *)tmp_buf);
  if(ret == false)
    return false;
  return true;
}



#endif