1
/* Copyright (C) 2003 MySQL AB
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.
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.
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 */
16
#include <ndb_global.h>
17
#include <SimpleProperties.hpp>
20
#include <UtilBuffer.hpp>
23
SimpleProperties::Writer::first(){
28
SimpleProperties::Writer::add(Uint16 key, Uint32 value){
29
Uint32 head = Uint32Value;
32
if(!putWord(htonl(head)))
35
return putWord(htonl(value));
39
SimpleProperties::Writer::add(const char * value, int len){
40
const Uint32 valLen = (len + 3) / 4;
43
return putWords((Uint32*)value, valLen);
45
const Uint32 putLen= valLen - 1;
46
if (!putWords((Uint32*)value, putLen))
49
// Special handling of last bytes
58
return putWord(tmp.lastWord);
62
SimpleProperties::Writer::add(Uint16 key, const char * value){
63
Uint32 head = StringValue;
66
if(!putWord(htonl(head)))
68
Uint32 strLen = strlen(value) + 1; // Including NULL-byte
69
if(!putWord(htonl(strLen)))
72
return add(value, (int)strLen);
77
SimpleProperties::Writer::add(Uint16 key, const void* value, int len){
78
Uint32 head = BinaryValue;
81
if(!putWord(htonl(head)))
83
if(!putWord(htonl(len)))
86
return add((const char*)value, len);
89
SimpleProperties::Reader::Reader(){
94
SimpleProperties::Reader::first(){
101
SimpleProperties::Reader::next(){
106
SimpleProperties::Reader::valid() const {
107
return m_type != InvalidValue;
111
SimpleProperties::Reader::getKey() const{
116
SimpleProperties::Reader::getValueLen() const {
129
SimpleProperties::ValueType
130
SimpleProperties::Reader::getValueType() const {
135
SimpleProperties::Reader::getUint32() const {
140
SimpleProperties::Reader::getString(char * dst) const {
141
if(peekWords((Uint32*)dst, m_itemLen))
147
SimpleProperties::Reader::readValue(){
148
if(!step(m_itemLen)){
149
m_type = InvalidValue;
155
m_type = InvalidValue;
160
m_key = tmp & 0xFFFF;
161
m_type = (SimpleProperties::ValueType)(tmp >> 16);
165
if(!peekWord(&m_ui32_value))
167
m_ui32_value = ntohl(m_ui32_value);
173
m_strLen = ntohl(tmp);
174
m_itemLen = (m_strLen + 3)/4;
178
m_type = InvalidValue;
183
SimpleProperties::UnpackStatus
184
SimpleProperties::unpack(Reader & it, void * dst,
185
const SP2StructMapping _map[], Uint32 mapSz,
187
bool ignoreUnknownKeys){
193
Uint16 key = it.getKey();
194
for(Uint32 i = 0; i<mapSz; i++){
195
if(key == _map[i].Key){
197
if(_map[i].Type == InvalidValue)
199
if(_map[i].Type != it.getValueType())
202
char * _dst = (char *)dst;
203
_dst += _map[i].Offset;
205
switch(it.getValueType()){
207
const Uint32 val = it.getUint32();
209
if(val < _map[i].minValue)
211
if(val > _map[i].maxValue)
214
* ((Uint32 *)_dst) = val;
219
unsigned len = it.getValueLen();
220
if(len < _map[i].minValue)
222
if(len > _map[i].maxValue)
233
if(!found && !ignoreUnknownKeys)
240
SimpleProperties::UnpackStatus
241
SimpleProperties::pack(Writer & it, const void * __src,
242
const SP2StructMapping _map[], Uint32 mapSz,
245
const char * _src = (const char *)__src;
247
for(Uint32 i = 0; i<mapSz; i++){
249
const char * src = _src + _map[i].Offset;
250
switch(_map[i].Type){
251
case SimpleProperties::InvalidValue:
254
case SimpleProperties::Uint32Value:{
255
Uint32 val = * ((Uint32*)src);
257
if(val < _map[i].minValue)
259
if(val > _map[i].maxValue)
262
ok = it.add(_map[i].Key, val);
265
case SimpleProperties::BinaryValue:{
266
const char * src_len = _src + _map[i].Length_Offset;
267
Uint32 len = *((Uint32*)src_len);
269
if(len > _map[i].maxValue)
272
ok = it.add(_map[i].Key, src, len);
275
case SimpleProperties::StringValue:
277
size_t len = strlen(src);
278
if(len > _map[i].maxValue)
281
ok = it.add(_map[i].Key, src);
292
SimpleProperties::Reader::printAll(NdbOut& ndbout){
294
for(first(); valid(); next()){
295
switch(getValueType()){
296
case SimpleProperties::Uint32Value:
297
ndbout << "Key: " << getKey()
298
<< " value(" << getValueLen() << ") : "
299
<< getUint32() << endl;
301
case SimpleProperties::BinaryValue:
302
case SimpleProperties::StringValue:
303
if(getValueLen() < 1024){
305
ndbout << "Key: " << getKey()
306
<< " value(" << getValueLen() << ") : "
307
<< "\"" << tmp << "\"" << endl;
309
ndbout << "Key: " << getKey()
310
<< " value(" << getValueLen() << ") : "
311
<< "\"" << "<TOO LONG>" << "\"" << endl;
316
ndbout << "Unknown type for key: " << getKey()
317
<< " type: " << (Uint32)getValueType() << endl;
322
SimplePropertiesLinearReader::SimplePropertiesLinearReader
323
(const Uint32 * src, Uint32 len){
331
SimplePropertiesLinearReader::reset() {
336
SimplePropertiesLinearReader::step(Uint32 len){
338
return m_pos < m_len;
342
SimplePropertiesLinearReader::getWord(Uint32 * dst) {
344
* dst = m_src[m_pos++];
351
SimplePropertiesLinearReader::peekWord(Uint32 * dst) const {
353
* dst = m_src[m_pos];
360
SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const {
361
if(m_pos + len <= m_len){
362
memcpy(dst, &m_src[m_pos], 4 * len);
368
LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
374
bool LinearWriter::reset() { m_pos = 0; return m_len > 0;}
377
LinearWriter::putWord(Uint32 val){
379
m_src[m_pos++] = val;
386
LinearWriter::putWords(const Uint32 * src, Uint32 len){
387
if(m_pos + len <= m_len){
388
memcpy(&m_src[m_pos], src, 4 * len);
396
LinearWriter::getWordsUsed() const { return m_pos;}
398
UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
404
bool UtilBufferWriter::reset() { m_buf.clear(); return true;}
407
UtilBufferWriter::putWord(Uint32 val){
408
return (m_buf.append(&val, 4) == 0);
412
UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){
413
return (m_buf.append(src, 4 * len) == 0);
418
UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
421
LinearPagesReader::LinearPagesReader(const Uint32 * base,
428
m_noOfPages = noOfPages;
429
m_pageHeaderSz = headerSize;
435
LinearPagesReader::reset() { m_pos = 0;}
438
LinearPagesReader::step(Uint32 len){
440
return m_pos < m_len;
444
LinearPagesReader::getWord(Uint32 * dst) {
446
* dst = m_base[getPos(m_pos++)];
453
LinearPagesReader::peekWord(Uint32 * dst) const {
455
* dst = m_base[getPos(m_pos)];
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)];
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;
479
LinearPagesWriter::LinearPagesWriter(Uint32 * base,
485
m_noOfPages = noOfPages;
486
m_pageHeaderSz = headerSize;
487
m_len = noOfPages * (pageSize - headerSize);
492
LinearPagesWriter::putWord(Uint32 val){
494
m_base[getPos(m_pos++)] = val;
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];
512
LinearPagesWriter::getWordsUsed() const {
513
return getPos(m_pos);
518
LinearPagesWriter::getPagesUsed() const {
519
return m_pos / (m_pageSz - m_pageHeaderSz);
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;