OpenDAFF C++ API  v1.7
Directional Audio File Format
DAFFMetadataImpl.cpp
Go to the documentation of this file.
1 #include "DAFFMetadataImpl.h"
2 
3 #include "Utils.h"
4 
5 #include <algorithm>
6 #include <cassert>
7 #include <iomanip>
8 #include <sstream>
9 
11 {
12 public:
13  int m_iType;
14 
15  inline DAFFMetadataKey(int iType) : m_iType(iType)
16  {};
17 
18  inline virtual ~DAFFMetadataKey() {};
19 };
20 
22 {
23 public:
24  bool m_bValue;
25 
26  inline DAFFMetadataKeyBool(bool bValue)
27  : DAFFMetadataKey(DAFFMetadata::DAFF_BOOL), m_bValue(bValue) {};
28 };
29 
31 {
32 public:
33  int m_iValue;
34 
35  inline DAFFMetadataKeyInt(int iValue)
36  : DAFFMetadataKey(DAFFMetadata::DAFF_INT), m_iValue(iValue) {};
37 };
38 
40 {
41 public:
42  double m_dValue;
43 
44  inline DAFFMetadataKeyFloat(double dValue)
45  : DAFFMetadataKey(DAFFMetadata::DAFF_FLOAT), m_dValue(dValue) {};
46 
47 };
48 
50 {
51 public:
52  std::string m_sValue;
53 
54  inline DAFFMetadataKeyString(const std::string& sValue)
55  : DAFFMetadataKey(DAFFMetadata::DAFF_STRING), m_sValue(sValue) {};
56 };
57 
59 
60 int DAFFMetadataImpl::load(void* pData, size_t &iBytesRead)
61 {
62  char* p = (char*) pData;
63 
64  // Read the number of keys
65  int* piNumKeys = (int*) p;
66  DAFF::le2se_4byte(piNumKeys, 1);
67  p += 4;
68 
69  int* piDatatype;
70  int* piValue;
71  double* pdValue;
72  std::string sValue;
73 
74  // Read the keys
75  for (int i=0; i<*piNumKeys; i++)
76  {
77  // Datatype
78  piDatatype = (int*) p;
79  DAFF::le2se_4byte(piDatatype, 1);
80  p += 4;
81 
82  // Key name
83  std::string sKey(p);
84  p += sKey.length()+1;
85 
86  // Value
87  switch (*piDatatype)
88  {
89  case DAFF_BOOL:
90  piValue = (int*) p;
91  DAFF::le2se_4byte(piValue, 1);
92  p += 4;
93 
94  insertKey(sKey, new DAFFMetadataKeyBool( *piValue != 0 ));
95  break;
96 
97  case DAFF_INT:
98  piValue = (int*) p;
99  DAFF::le2se_4byte(piValue, 1);
100  p += 4;
101 
102  insertKey(sKey, new DAFFMetadataKeyInt( *piValue ));
103  break;
104 
105  case DAFF_FLOAT:
106  pdValue = (double*) p;
107  DAFF::le2se_8byte(pdValue, 1);
108  p += 8;
109 
110  insertKey(sKey, new DAFFMetadataKeyFloat( *pdValue ));
111  break;
112 
113  case DAFF_STRING:
114  sValue = p;
115  p += sValue.length()+1;
116 
117  insertKey(sKey, new DAFFMetadataKeyString( sValue ));
118  break;
119 
120  default:
122  }
123  }
124 
125  iBytesRead = (size_t) (p - (char*)pData);
126  return 0;
127 }
128 
130 {
131  // Delete all keys
132  std::for_each(m_mKeys.begin(), m_mKeys.end(), deleteMetadataKeyPair);
133  m_mKeys.clear();
134 }
135 
137 {
138  return m_mKeys.empty();
139 }
140 
141 bool DAFFMetadataImpl::hasKey(const std::string& sKey) const {
142  return (findKey(sKey) != NULL);
143 }
144 
145 void DAFFMetadataImpl::getKeys(std::vector< std::string >& vsKeyList) const {
146  vsKeyList.clear();
147  for (KeyMapConstIterator cit=m_mKeys.begin(); cit!=m_mKeys.end(); ++cit)
148  vsKeyList.push_back(cit->first);
149 }
150 
151 int DAFFMetadataImpl::getKeyType( const std::string& sKey ) const {
152  const DAFFMetadataKey* pKey = findKey( sKey );
153  return ( pKey != NULL ? pKey->m_iType : -1 );
154 }
155 
156 std::string DAFFMetadataImpl::getKeyString(const std::string& sKey) const {
157  const DAFFMetadataKey* pKey = findKey(sKey);
158  assert( pKey != NULL );
159 
160  if (pKey == NULL) return "";
161 
162  std::stringstream ss;
163  switch (pKey->m_iType) {
164  case DAFF_BOOL:
165  return (dynamic_cast<const DAFFMetadataKeyBool*>(pKey)->m_bValue ? "yes" : "no");
166 
167  case DAFF_INT:
168  ss << dynamic_cast<const DAFFMetadataKeyInt*>(pKey)->m_iValue;
169  return ss.str();
170 
171  case DAFF_FLOAT:
172  ss << dynamic_cast<const DAFFMetadataKeyFloat*>(pKey)->m_dValue;
173  return ss.str();
174 
175  case DAFF_STRING:
176  return dynamic_cast<const DAFFMetadataKeyString*>(pKey)->m_sValue;
177 
178  default:
179  // This will never be reached, but satisfies the compiler warning...
180  return "";
181  }
182 }
183 
184 bool DAFFMetadataImpl::getKeyBool(const std::string& sKey) const {
185  const DAFFMetadataKey* pKey = findKey(sKey);
186  assert( pKey != NULL );
187  assert( pKey->m_iType == DAFF_BOOL );
188 
189  if ((pKey == NULL) || (pKey->m_iType != DAFF_BOOL)) return 0;
190  return dynamic_cast<const DAFFMetadataKeyBool*>(pKey)->m_bValue;
191 }
192 
193 int DAFFMetadataImpl::getKeyInt(const std::string& sKey) const {
194  const DAFFMetadataKey* pKey = findKey(sKey);
195  assert( pKey != NULL );
196  assert( pKey->m_iType == DAFF_INT );
197 
198  if ((pKey == NULL) || (pKey->m_iType != DAFF_INT)) return 0;
199  return dynamic_cast<const DAFFMetadataKeyInt*>(pKey)->m_iValue;
200 }
201 
202 double DAFFMetadataImpl::getKeyFloat(const std::string& sKey) const {
203  const DAFFMetadataKey* pKey = findKey(sKey);
204  assert( pKey != NULL );
205  assert( (pKey->m_iType == DAFF_FLOAT) || (pKey->m_iType == DAFF_INT) );
206 
207  if (pKey == NULL) return 0;
208  if ((pKey->m_iType != DAFF_FLOAT) && (pKey->m_iType != DAFF_INT)) return 0;
209 
210  if (pKey->m_iType == DAFF_FLOAT)
211  return dynamic_cast<const DAFFMetadataKeyFloat*>(pKey)->m_dValue;
212  else
213  return (double) dynamic_cast<const DAFFMetadataKeyInt*>(pKey)->m_iValue;
214 }
215 
216 std::string DAFFMetadataImpl::toString() const {
217  std::stringstream ss;
218  for (KeyMapConstIterator cit=m_mKeys.begin(); cit!=m_mKeys.end(); ++cit) {
219  ss << cit->first << " = " << getKeyString(cit->first) << std::endl;
220  }
221 
222  return ss.str();
223 }
224 
225 void DAFFMetadataImpl::insertKey(const std::string& sName, DAFFMetadataKey* pKey) {
226  // For later key search: Ensure that the keyname is upper case
227  std::string sKeyUpper(sName);
228  std::transform(sKeyUpper.begin(), sKeyUpper.end(), sKeyUpper.begin(), (int(*)(int)) ::toupper);
229 
230  m_mKeys[sKeyUpper] = pKey;
231 };
232 
233 const DAFFMetadataKey* DAFFMetadataImpl::findKey(const std::string& sKey) const {
234  // Empty strings are no valid key names
235  if (sKey.empty()) return NULL;
236 
237  // Convert the keyname to upper case
238  std::string sKeyUpper(sKey);
239  std::transform(sKeyUpper.begin(), sKeyUpper.end(), sKeyUpper.begin(), (int(*)(int)) ::toupper);
240 
241  // Search in the keymap
242  KeyMapConstIterator cit = m_mKeys.find(sKeyUpper);
243  return (cit == m_mKeys.end() ? NULL : cit->second);
244 }
245 
246 void DAFFMetadataImpl::deleteMetadataKeyPair(const KeyPair& pKeyPair) {
247  delete pKeyPair.second;
248 }
std::string getKeyString(const std::string &sKey) const
Returns the value of a string key.
DAFFMetadataKeyString(const std::string &sValue)
std::string toString() const
Return information on the metadata as string.
DAFFMetadataKeyInt(int iValue)
bool getKeyBool(const std::string &sKey) const
Returns the value (true|false) of a boolean key.
void getKeys(std::vector< std::string > &vsKeyList) const
Returns a list of all keys.
Given metadata type is unknown, use bool, int, double, string.
Definition: DAFFDefs.h:106
virtual ~DAFFMetadataKey()
DAFFMetadataKeyBool(bool bValue)
bool isEmpty() const
Returns if metadata does not contain any keys.
bool hasKey(const std::string &sKey) const
Checks for existence of a key.
int load(void *pData, size_t &iBytesRead)
#define NULL
Definition: DAFFDefs.h:59
int getKeyInt(const std::string &sKey) const
Returns the value of a integer number key.
DAFFMetadataKey(int iType)
void(* le2se_4byte)(void *src, size_t count)
Definition: Utils.cpp:102
DAFFMetadataKeyFloat(double dValue)
Metadata interface.
Definition: DAFFMetadata.h:31
double getKeyFloat(const std::string &sKey) const
Returns the value of a floating-point number key.
int getKeyType(const std::string &sKey) const
Returns the datatype of a key.
void(* le2se_8byte)(void *src, size_t count)
Definition: Utils.cpp:103
OpenDAFF is a project from the Institute of Technical Acoustics, RWTH Aachen University, Germany.