~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/common/util/SimpleProperties.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#include <ndb_global.h>
 
17
#include <SimpleProperties.hpp>
 
18
#include <NdbOut.hpp>
 
19
#include <NdbTCP.h>
 
20
#include <UtilBuffer.hpp>
 
21
 
 
22
bool
 
23
SimpleProperties::Writer::first(){
 
24
  return reset();
 
25
}
 
26
 
 
27
bool 
 
28
SimpleProperties::Writer::add(Uint16 key, Uint32 value){
 
29
  Uint32 head = Uint32Value;  
 
30
  head <<= 16;
 
31
  head += key;
 
32
  if(!putWord(htonl(head)))
 
33
    return false;
 
34
  
 
35
  return putWord(htonl(value));
 
36
}
 
37
 
 
38
bool
 
39
SimpleProperties::Writer::add(const char * value, int len){
 
40
  const Uint32 valLen = (len + 3) / 4;
 
41
 
 
42
  if ((len % 4) == 0)
 
43
    return putWords((Uint32*)value, valLen);
 
44
 
 
45
  const Uint32 putLen= valLen - 1;
 
46
  if (!putWords((Uint32*)value, putLen))
 
47
    return false;
 
48
 
 
49
  // Special handling of last bytes
 
50
  union {
 
51
    Uint32 lastWord;
 
52
    char lastBytes[4];
 
53
  } tmp;
 
54
  tmp.lastWord =0 ;
 
55
  memcpy(tmp.lastBytes,
 
56
         value + putLen*4,
 
57
         len - putLen*4);
 
58
  return putWord(tmp.lastWord);
 
59
}
 
60
 
 
61
bool
 
62
SimpleProperties::Writer::add(Uint16 key, const char * value){
 
63
  Uint32 head = StringValue;
 
64
  head <<= 16;
 
65
  head += key;
 
66
  if(!putWord(htonl(head)))
 
67
    return false;
 
68
  Uint32 strLen = strlen(value) + 1; // Including NULL-byte
 
69
  if(!putWord(htonl(strLen)))
 
70
    return false;
 
71
 
 
72
  return add(value, (int)strLen);
 
73
 
 
74
}
 
75
 
 
76
bool
 
77
SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
 
78
  Uint32 head = BinaryValue;
 
79
  head <<= 16;
 
80
  head += key;
 
81
  if(!putWord(htonl(head)))
 
82
    return false;
 
83
  if(!putWord(htonl(len)))
 
84
    return false;
 
85
 
 
86
  return add((const char*)value, len);
 
87
}
 
88
 
 
89
SimpleProperties::Reader::Reader(){
 
90
  m_itemLen = 0;
 
91
}
 
92
 
 
93
bool 
 
94
SimpleProperties::Reader::first(){
 
95
  reset();
 
96
  m_itemLen = 0;
 
97
  return readValue();
 
98
}
 
99
 
 
100
bool
 
101
SimpleProperties::Reader::next(){
 
102
  return readValue();
 
103
}
 
104
    
 
105
bool
 
106
SimpleProperties::Reader::valid() const {
 
107
  return m_type != InvalidValue;
 
108
}
 
109
 
 
110
Uint16
 
111
SimpleProperties::Reader::getKey() const{
 
112
  return m_key;
 
113
}
 
114
 
 
115
Uint16
 
116
SimpleProperties::Reader::getValueLen() const {
 
117
  switch(m_type){
 
118
  case Uint32Value:
 
119
    return 4;
 
120
  case StringValue:
 
121
  case BinaryValue:
 
122
    return m_strLen;
 
123
  case InvalidValue:
 
124
    return 0;
 
125
  }
 
126
  return 0;
 
127
}
 
128
 
 
129
SimpleProperties::ValueType
 
130
SimpleProperties::Reader::getValueType() const {
 
131
  return m_type;
 
132
}
 
133
    
 
134
Uint32
 
135
SimpleProperties::Reader::getUint32() const {
 
136
  return m_ui32_value;
 
137
}
 
138
 
 
139
char * 
 
140
SimpleProperties::Reader::getString(char * dst) const {
 
141
  if(peekWords((Uint32*)dst, m_itemLen))
 
142
    return dst;
 
143
  return 0;
 
144
}
 
145
 
 
146
bool
 
147
SimpleProperties::Reader::readValue(){
 
148
  if(!step(m_itemLen)){
 
149
    m_type = InvalidValue;
 
150
    return false;
 
151
  }
 
152
  
 
153
  Uint32 tmp;
 
154
  if(!getWord(&tmp)){
 
155
    m_type = InvalidValue;
 
156
    return false;
 
157
  }
 
158
 
 
159
  tmp = ntohl(tmp);
 
160
  m_key = tmp & 0xFFFF;
 
161
  m_type = (SimpleProperties::ValueType)(tmp >> 16);
 
162
  switch(m_type){
 
163
  case Uint32Value:
 
164
    m_itemLen = 1;
 
165
    if(!peekWord(&m_ui32_value))
 
166
      return false;
 
167
    m_ui32_value = ntohl(m_ui32_value);
 
168
    return true;
 
169
  case StringValue:
 
170
  case BinaryValue:
 
171
    if(!getWord(&tmp))
 
172
      return false;
 
173
    m_strLen = ntohl(tmp);
 
174
    m_itemLen = (m_strLen + 3)/4;
 
175
    return true;
 
176
  default:
 
177
    m_itemLen = 0;
 
178
    m_type = InvalidValue;
 
179
    return false;
 
180
  }
 
181
}
 
182
 
 
183
SimpleProperties::UnpackStatus 
 
184
SimpleProperties::unpack(Reader & it, void * dst, 
 
185
                         const SP2StructMapping _map[], Uint32 mapSz,
 
186
                         bool ignoreMinMax,
 
187
                         bool ignoreUnknownKeys){
 
188
  do {
 
189
    if(!it.valid())
 
190
      break;
 
191
    
 
192
    bool found = false;
 
193
    Uint16 key = it.getKey();
 
194
    for(Uint32 i = 0; i<mapSz; i++){
 
195
      if(key == _map[i].Key){
 
196
        found = true;
 
197
        if(_map[i].Type == InvalidValue)
 
198
          return Break;
 
199
        if(_map[i].Type != it.getValueType())
 
200
          return TypeMismatch;
 
201
        
 
202
        char * _dst = (char *)dst;
 
203
        _dst += _map[i].Offset;
 
204
        
 
205
        switch(it.getValueType()){
 
206
        case Uint32Value:{
 
207
          const Uint32 val = it.getUint32();
 
208
          if(!ignoreMinMax){
 
209
            if(val < _map[i].minValue)
 
210
              return ValueTooLow;
 
211
            if(val > _map[i].maxValue)
 
212
              return ValueTooHigh;
 
213
          }
 
214
          * ((Uint32 *)_dst) = val;
 
215
          break;
 
216
        }
 
217
        case BinaryValue:
 
218
        case StringValue:{
 
219
          unsigned len = it.getValueLen();
 
220
          if(len < _map[i].minValue)
 
221
            return ValueTooLow;
 
222
          if(len > _map[i].maxValue)
 
223
            return ValueTooHigh;
 
224
          it.getString(_dst);
 
225
          break;
 
226
        }
 
227
        default:
 
228
          abort();
 
229
        }
 
230
        break;
 
231
      }
 
232
    }
 
233
    if(!found && !ignoreUnknownKeys)
 
234
      return UnknownKey;
 
235
  } while(it.next());
 
236
  
 
237
  return Eof;
 
238
}
 
239
 
 
240
SimpleProperties::UnpackStatus 
 
241
SimpleProperties::pack(Writer & it, const void * __src, 
 
242
                       const SP2StructMapping _map[], Uint32 mapSz,
 
243
                       bool ignoreMinMax){
 
244
 
 
245
  const char * _src = (const char *)__src;
 
246
 
 
247
  for(Uint32 i = 0; i<mapSz; i++){
 
248
    bool ok = false;
 
249
    const char * src = _src + _map[i].Offset;
 
250
    switch(_map[i].Type){
 
251
    case SimpleProperties::InvalidValue:
 
252
      ok = true;
 
253
      break;
 
254
    case SimpleProperties::Uint32Value:{
 
255
      Uint32 val = * ((Uint32*)src);
 
256
      if(!ignoreMinMax){
 
257
        if(val < _map[i].minValue)
 
258
          return ValueTooLow;
 
259
        if(val > _map[i].maxValue)
 
260
          return ValueTooHigh;
 
261
      }
 
262
      ok = it.add(_map[i].Key, val);
 
263
    }
 
264
      break;
 
265
    case SimpleProperties::BinaryValue:{
 
266
      const char * src_len = _src + _map[i].Length_Offset;
 
267
      Uint32 len = *((Uint32*)src_len);
 
268
      if(!ignoreMinMax){
 
269
        if(len > _map[i].maxValue)
 
270
          return ValueTooHigh;
 
271
      }
 
272
      ok = it.add(_map[i].Key, src, len);
 
273
      break;
 
274
    }
 
275
    case SimpleProperties::StringValue:
 
276
      if(!ignoreMinMax){
 
277
        size_t len = strlen(src);
 
278
        if(len > _map[i].maxValue)
 
279
          return ValueTooHigh;
 
280
      }
 
281
      ok = it.add(_map[i].Key, src);
 
282
      break;
 
283
    }
 
284
    if(!ok)
 
285
      return OutOfMemory;
 
286
  }
 
287
  
 
288
  return Eof;
 
289
}
 
290
 
 
291
void
 
292
SimpleProperties::Reader::printAll(NdbOut& ndbout){
 
293
  char tmp[1024];
 
294
  for(first(); valid(); next()){
 
295
    switch(getValueType()){
 
296
    case SimpleProperties::Uint32Value:
 
297
      ndbout << "Key: " << getKey()
 
298
             << " value(" << getValueLen() << ") : " 
 
299
             << getUint32() << endl;
 
300
      break;
 
301
    case SimpleProperties::BinaryValue:
 
302
    case SimpleProperties::StringValue:
 
303
      if(getValueLen() < 1024){
 
304
        getString(tmp);
 
305
        ndbout << "Key: " << getKey()
 
306
               << " value(" << getValueLen() << ") : " 
 
307
               << "\"" << tmp << "\"" << endl;
 
308
      } else {
 
309
        ndbout << "Key: " << getKey()
 
310
               << " value(" << getValueLen() << ") : " 
 
311
               << "\"" << "<TOO LONG>" << "\"" << endl;
 
312
        
 
313
      }
 
314
      break;
 
315
    default:
 
316
      ndbout << "Unknown type for key: " << getKey() 
 
317
             << " type: " << (Uint32)getValueType() << endl;
 
318
    }
 
319
  }
 
320
}
 
321
 
 
322
SimplePropertiesLinearReader::SimplePropertiesLinearReader
 
323
(const Uint32 * src, Uint32 len){
 
324
  m_src = src;
 
325
  m_len = len;
 
326
  m_pos = 0;
 
327
  first();
 
328
}
 
329
 
 
330
void 
 
331
SimplePropertiesLinearReader::reset() { 
 
332
  m_pos = 0;
 
333
}
 
334
 
 
335
bool 
 
336
SimplePropertiesLinearReader::step(Uint32 len){
 
337
  m_pos += len;
 
338
  return m_pos < m_len;
 
339
}
 
340
  
 
341
bool
 
342
SimplePropertiesLinearReader::getWord(Uint32 * dst) { 
 
343
  if(m_pos<m_len){
 
344
    * dst = m_src[m_pos++];
 
345
    return true;
 
346
  } 
 
347
  return false;
 
348
}
 
349
 
 
350
bool 
 
351
SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
 
352
  if(m_pos<m_len){
 
353
    * dst = m_src[m_pos];
 
354
    return true;
 
355
  } 
 
356
  return false;
 
357
}
 
358
 
 
359
bool 
 
360
SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
 
361
  if(m_pos + len <= m_len){
 
362
    memcpy(dst, &m_src[m_pos], 4 * len);
 
363
    return true;
 
364
  }
 
365
  return false;
 
366
}
 
367
 
 
368
LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
 
369
  m_src = src;
 
370
  m_len = len;
 
371
  reset();
 
372
}
 
373
 
 
374
bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}
 
375
 
 
376
bool 
 
377
LinearWriter::putWord(Uint32 val){
 
378
  if(m_pos < m_len){
 
379
    m_src[m_pos++] = val;
 
380
    return true;
 
381
  }
 
382
  return false;
 
383
}
 
384
 
 
385
bool 
 
386
LinearWriter::putWords(const Uint32 * src, Uint32 len){
 
387
  if(m_pos + len <= m_len){
 
388
    memcpy(&m_src[m_pos], src, 4 * len);
 
389
    m_pos += len;
 
390
    return true;
 
391
  }
 
392
  return false;
 
393
}
 
394
 
 
395
Uint32
 
396
LinearWriter::getWordsUsed() const { return m_pos;}
 
397
 
 
398
UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
 
399
  : m_buf(b)
 
400
{
 
401
  reset();
 
402
}
 
403
 
 
404
bool UtilBufferWriter::reset() { m_buf.clear(); return true;}
 
405
 
 
406
bool 
 
407
UtilBufferWriter::putWord(Uint32 val){
 
408
  return (m_buf.append(&val, 4) == 0);
 
409
}
 
410
 
 
411
bool 
 
412
UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
 
413
  return (m_buf.append(src, 4 * len) == 0);
 
414
}
 
415
 
 
416
 
 
417
Uint32
 
418
UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
 
419
 
 
420
#if 0
 
421
LinearPagesReader::LinearPagesReader(const Uint32 * base, 
 
422
                                     Uint32 pageSize, 
 
423
                                     Uint32 headerSize,
 
424
                                     Uint32 noOfPages, 
 
425
                                     Uint32 len){
 
426
  m_base = base;
 
427
  m_pageSz = pageSize;
 
428
  m_noOfPages = noOfPages;
 
429
  m_pageHeaderSz = headerSize;
 
430
  m_len = len;
 
431
  reset();
 
432
}
 
433
 
 
434
void 
 
435
LinearPagesReader::reset() { m_pos = 0;}
 
436
 
 
437
bool 
 
438
LinearPagesReader::step(Uint32 len){
 
439
  m_pos += len;
 
440
  return m_pos < m_len;
 
441
}
 
442
 
 
443
bool 
 
444
LinearPagesReader::getWord(Uint32 * dst) { 
 
445
  if(m_pos<m_len){
 
446
    * dst = m_base[getPos(m_pos++)];
 
447
    return true;
 
448
  } 
 
449
  return false;
 
450
}
 
451
 
 
452
bool 
 
453
LinearPagesReader::peekWord(Uint32 * dst) const {
 
454
  if(m_pos<m_len){
 
455
    * dst = m_base[getPos(m_pos)];
 
456
    return true;
 
457
  } 
 
458
  return false;
 
459
}
 
460
 
 
461
bool 
 
462
LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const {
 
463
  if(m_pos + len <= m_len){
 
464
    for(Uint32 i = 0; i<len; i++)
 
465
      * (dst + i) = m_base[getPos(m_pos + i)];
 
466
    return true;
 
467
  }
 
468
  return false;
 
469
}
 
470
 
 
471
Uint32 
 
472
LinearPagesReader::getPos(Uint32 pos) const {
 
473
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
 
474
  Uint32 no = pos / sz;
 
475
  Uint32 in = pos % sz;
 
476
  return no * m_pageSz + m_pageHeaderSz + in;
 
477
}
 
478
 
 
479
LinearPagesWriter::LinearPagesWriter(Uint32 * base, 
 
480
                                     Uint32 pageSize, 
 
481
                                     Uint32 noOfPages, 
 
482
                                     Uint32 headerSize){
 
483
  m_base = base;
 
484
  m_pageSz = pageSize;
 
485
  m_noOfPages = noOfPages;
 
486
  m_pageHeaderSz = headerSize;
 
487
  m_len = noOfPages * (pageSize - headerSize);
 
488
  reset();
 
489
}
 
490
 
 
491
bool 
 
492
LinearPagesWriter::putWord(Uint32 val){
 
493
  if(m_pos < m_len){
 
494
    m_base[getPos(m_pos++)] = val;
 
495
    return true;
 
496
  }
 
497
  return false;
 
498
}
 
499
 
 
500
bool 
 
501
LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){
 
502
  if(m_pos + len <= m_len){
 
503
    for(Uint32 i = 0; i<len; i++)
 
504
      m_base[getPos(m_pos++)] = src[i];
 
505
    return true;
 
506
  }
 
507
  return false;
 
508
}
 
509
 
 
510
#if 0
 
511
Uint32 
 
512
LinearPagesWriter::getWordsUsed() const { 
 
513
  return getPos(m_pos);
 
514
}
 
515
#endif
 
516
 
 
517
Uint32 
 
518
LinearPagesWriter::getPagesUsed() const { 
 
519
  return m_pos / (m_pageSz - m_pageHeaderSz);
 
520
}
 
521
 
 
522
Uint32 
 
523
LinearPagesWriter::getPos(Uint32 pos) const {
 
524
  const Uint32 sz = (m_pageSz - m_pageHeaderSz);
 
525
  Uint32 no = pos / sz;
 
526
  Uint32 in = pos % sz;
 
527
  return no * m_pageSz + m_pageHeaderSz + in;
 
528
}
 
529
#endif