00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 #include <ndb_global.h> 00018 #include <SimpleProperties.hpp> 00019 #include <NdbOut.hpp> 00020 #include <NdbTCP.h> 00021 #include <UtilBuffer.hpp> 00022 00023 bool 00024 SimpleProperties::Writer::first(){ 00025 return reset(); 00026 } 00027 00028 bool 00029 SimpleProperties::Writer::add(Uint16 key, Uint32 value){ 00030 Uint32 head = Uint32Value; 00031 head <<= 16; 00032 head += key; 00033 if(!putWord(htonl(head))) 00034 return false; 00035 00036 return putWord(htonl(value)); 00037 } 00038 00039 bool 00040 SimpleProperties::Writer::add(const char * value, int len){ 00041 const Uint32 valLen = (len + 3) / 4; 00042 00043 if ((len % 4) == 0) 00044 return putWords((Uint32*)value, valLen); 00045 00046 const Uint32 putLen= valLen - 1; 00047 if (!putWords((Uint32*)value, putLen)) 00048 return false; 00049 00050 // Special handling of last bytes 00051 union { 00052 Uint32 lastWord; 00053 char lastBytes[4]; 00054 } tmp; 00055 tmp.lastWord =0 ; 00056 memcpy(tmp.lastBytes, 00057 value + putLen*4, 00058 len - putLen*4); 00059 return putWord(tmp.lastWord); 00060 } 00061 00062 bool 00063 SimpleProperties::Writer::add(Uint16 key, const char * value){ 00064 Uint32 head = StringValue; 00065 head <<= 16; 00066 head += key; 00067 if(!putWord(htonl(head))) 00068 return false; 00069 Uint32 strLen = strlen(value) + 1; // Including NULL-byte 00070 if(!putWord(htonl(strLen))) 00071 return false; 00072 00073 return add(value, (int)strLen); 00074 00075 } 00076 00077 bool 00078 SimpleProperties::Writer::add(Uint16 key, const void* value, int len){ 00079 Uint32 head = BinaryValue; 00080 head <<= 16; 00081 head += key; 00082 if(!putWord(htonl(head))) 00083 return false; 00084 if(!putWord(htonl(len))) 00085 return false; 00086 00087 return add((const char*)value, len); 00088 } 00089 00090 SimpleProperties::Reader::Reader(){ 00091 m_itemLen = 0; 00092 } 00093 00094 bool 00095 SimpleProperties::Reader::first(){ 00096 reset(); 00097 m_itemLen = 0; 00098 return readValue(); 00099 } 00100 00101 bool 00102 SimpleProperties::Reader::next(){ 00103 return readValue(); 00104 } 00105 00106 bool 00107 SimpleProperties::Reader::valid() const { 00108 return m_type != InvalidValue; 00109 } 00110 00111 Uint16 00112 SimpleProperties::Reader::getKey() const{ 00113 return m_key; 00114 } 00115 00116 Uint16 00117 SimpleProperties::Reader::getValueLen() const { 00118 switch(m_type){ 00119 case Uint32Value: 00120 return 4; 00121 case StringValue: 00122 case BinaryValue: 00123 return m_strLen; 00124 case InvalidValue: 00125 return 0; 00126 } 00127 return 0; 00128 } 00129 00130 SimpleProperties::ValueType 00131 SimpleProperties::Reader::getValueType() const { 00132 return m_type; 00133 } 00134 00135 Uint32 00136 SimpleProperties::Reader::getUint32() const { 00137 return m_ui32_value; 00138 } 00139 00140 char * 00141 SimpleProperties::Reader::getString(char * dst) const { 00142 if(peekWords((Uint32*)dst, m_itemLen)) 00143 return dst; 00144 return 0; 00145 } 00146 00147 bool 00148 SimpleProperties::Reader::readValue(){ 00149 if(!step(m_itemLen)){ 00150 m_type = InvalidValue; 00151 return false; 00152 } 00153 00154 Uint32 tmp; 00155 if(!getWord(&tmp)){ 00156 m_type = InvalidValue; 00157 return false; 00158 } 00159 00160 tmp = ntohl(tmp); 00161 m_key = tmp & 0xFFFF; 00162 m_type = (SimpleProperties::ValueType)(tmp >> 16); 00163 switch(m_type){ 00164 case Uint32Value: 00165 m_itemLen = 1; 00166 if(!peekWord(&m_ui32_value)) 00167 return false; 00168 m_ui32_value = ntohl(m_ui32_value); 00169 return true; 00170 case StringValue: 00171 case BinaryValue: 00172 if(!getWord(&tmp)) 00173 return false; 00174 m_strLen = ntohl(tmp); 00175 m_itemLen = (m_strLen + 3)/4; 00176 return true; 00177 default: 00178 m_itemLen = 0; 00179 m_type = InvalidValue; 00180 return false; 00181 } 00182 } 00183 00184 SimpleProperties::UnpackStatus 00185 SimpleProperties::unpack(Reader & it, void * dst, 00186 const SP2StructMapping _map[], Uint32 mapSz, 00187 bool ignoreMinMax, 00188 bool ignoreUnknownKeys){ 00189 do { 00190 if(!it.valid()) 00191 break; 00192 00193 bool found = false; 00194 Uint16 key = it.getKey(); 00195 for(Uint32 i = 0; i<mapSz; i++){ 00196 if(key == _map[i].Key){ 00197 found = true; 00198 if(_map[i].Type == InvalidValue) 00199 return Break; 00200 if(_map[i].Type != it.getValueType()) 00201 return TypeMismatch; 00202 00203 char * _dst = (char *)dst; 00204 _dst += _map[i].Offset; 00205 00206 switch(it.getValueType()){ 00207 case Uint32Value:{ 00208 const Uint32 val = it.getUint32(); 00209 if(!ignoreMinMax){ 00210 if(val < _map[i].minValue) 00211 return ValueTooLow; 00212 if(val > _map[i].maxValue) 00213 return ValueTooHigh; 00214 } 00215 * ((Uint32 *)_dst) = val; 00216 break; 00217 } 00218 case BinaryValue: 00219 case StringValue:{ 00220 unsigned len = it.getValueLen(); 00221 if(len < _map[i].minValue) 00222 return ValueTooLow; 00223 if(len > _map[i].maxValue) 00224 return ValueTooHigh; 00225 it.getString(_dst); 00226 break; 00227 } 00228 default: 00229 abort(); 00230 } 00231 break; 00232 } 00233 } 00234 if(!found && !ignoreUnknownKeys) 00235 return UnknownKey; 00236 } while(it.next()); 00237 00238 return Eof; 00239 } 00240 00241 SimpleProperties::UnpackStatus 00242 SimpleProperties::pack(Writer & it, const void * __src, 00243 const SP2StructMapping _map[], Uint32 mapSz, 00244 bool ignoreMinMax){ 00245 00246 const char * _src = (const char *)__src; 00247 00248 for(Uint32 i = 0; i<mapSz; i++){ 00249 bool ok = false; 00250 const char * src = _src + _map[i].Offset; 00251 switch(_map[i].Type){ 00252 case SimpleProperties::InvalidValue: 00253 ok = true; 00254 break; 00255 case SimpleProperties::Uint32Value:{ 00256 Uint32 val = * ((Uint32*)src); 00257 if(!ignoreMinMax){ 00258 if(val < _map[i].minValue) 00259 return ValueTooLow; 00260 if(val > _map[i].maxValue) 00261 return ValueTooHigh; 00262 } 00263 ok = it.add(_map[i].Key, val); 00264 } 00265 break; 00266 case SimpleProperties::BinaryValue:{ 00267 const char * src_len = _src + _map[i].Length_Offset; 00268 Uint32 len = *((Uint32*)src_len); 00269 if(!ignoreMinMax){ 00270 if(len == _map[i].maxValue) 00271 return ValueTooHigh; 00272 } 00273 ok = it.add(_map[i].Key, src, len); 00274 break; 00275 } 00276 case SimpleProperties::StringValue: 00277 if(!ignoreMinMax){ 00278 size_t len = strlen(src); 00279 if(len == _map[i].maxValue) 00280 return ValueTooHigh; 00281 } 00282 ok = it.add(_map[i].Key, src); 00283 break; 00284 } 00285 if(!ok) 00286 return OutOfMemory; 00287 } 00288 00289 return Eof; 00290 } 00291 00292 void 00293 SimpleProperties::Reader::printAll(NdbOut& ndbout){ 00294 char tmp[1024]; 00295 for(first(); valid(); next()){ 00296 switch(getValueType()){ 00297 case SimpleProperties::Uint32Value: 00298 ndbout << "Key: " << getKey() 00299 << " value(" << getValueLen() << ") : " 00300 << getUint32() << endl; 00301 break; 00302 case SimpleProperties::BinaryValue: 00303 case SimpleProperties::StringValue: 00304 if(getValueLen() < 1024){ 00305 getString(tmp); 00306 ndbout << "Key: " << getKey() 00307 << " value(" << getValueLen() << ") : " 00308 << "\"" << tmp << "\"" << endl; 00309 } else { 00310 ndbout << "Key: " << getKey() 00311 << " value(" << getValueLen() << ") : " 00312 << "\"" << "<TOO LONG>" << "\"" << endl; 00313 00314 } 00315 break; 00316 default: 00317 ndbout << "Unknown type for key: " << getKey() 00318 << " type: " << (Uint32)getValueType() << endl; 00319 } 00320 } 00321 } 00322 00323 SimplePropertiesLinearReader::SimplePropertiesLinearReader 00324 (const Uint32 * src, Uint32 len){ 00325 m_src = src; 00326 m_len = len; 00327 m_pos = 0; 00328 first(); 00329 } 00330 00331 void 00332 SimplePropertiesLinearReader::reset() { 00333 m_pos = 0; 00334 } 00335 00336 bool 00337 SimplePropertiesLinearReader::step(Uint32 len){ 00338 m_pos += len; 00339 return m_pos < m_len; 00340 } 00341 00342 bool 00343 SimplePropertiesLinearReader::getWord(Uint32 * dst) { 00344 if(m_pos<m_len){ 00345 * dst = m_src[m_pos++]; 00346 return true; 00347 } 00348 return false; 00349 } 00350 00351 bool 00352 SimplePropertiesLinearReader::peekWord(Uint32 * dst) const { 00353 if(m_pos<m_len){ 00354 * dst = m_src[m_pos]; 00355 return true; 00356 } 00357 return false; 00358 } 00359 00360 bool 00361 SimplePropertiesLinearReader::peekWords(Uint32 * dst, Uint32 len) const { 00362 if(m_pos + len <= m_len){ 00363 memcpy(dst, &m_src[m_pos], 4 * len); 00364 return true; 00365 } 00366 return false; 00367 } 00368 00369 LinearWriter::LinearWriter(Uint32 * src, Uint32 len){ 00370 m_src = src; 00371 m_len = len; 00372 reset(); 00373 } 00374 00375 bool LinearWriter::reset() { m_pos = 0; return m_len > 0;} 00376 00377 bool 00378 LinearWriter::putWord(Uint32 val){ 00379 if(m_pos < m_len){ 00380 m_src[m_pos++] = val; 00381 return true; 00382 } 00383 return false; 00384 } 00385 00386 bool 00387 LinearWriter::putWords(const Uint32 * src, Uint32 len){ 00388 if(m_pos + len <= m_len){ 00389 memcpy(&m_src[m_pos], src, 4 * len); 00390 m_pos += len; 00391 return true; 00392 } 00393 return false; 00394 } 00395 00396 Uint32 00397 LinearWriter::getWordsUsed() const { return m_pos;} 00398 00399 UtilBufferWriter::UtilBufferWriter(UtilBuffer & b) 00400 : m_buf(b) 00401 { 00402 reset(); 00403 } 00404 00405 bool UtilBufferWriter::reset() { m_buf.clear(); return true;} 00406 00407 bool 00408 UtilBufferWriter::putWord(Uint32 val){ 00409 return (m_buf.append(&val, 4) == 0); 00410 } 00411 00412 bool 00413 UtilBufferWriter::putWords(const Uint32 * src, Uint32 len){ 00414 return (m_buf.append(src, 4 * len) == 0); 00415 } 00416 00417 00418 Uint32 00419 UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;} 00420 00421 #if 0 00422 LinearPagesReader::LinearPagesReader(const Uint32 * base, 00423 Uint32 pageSize, 00424 Uint32 headerSize, 00425 Uint32 noOfPages, 00426 Uint32 len){ 00427 m_base = base; 00428 m_pageSz = pageSize; 00429 m_noOfPages = noOfPages; 00430 m_pageHeaderSz = headerSize; 00431 m_len = len; 00432 reset(); 00433 } 00434 00435 void 00436 LinearPagesReader::reset() { m_pos = 0;} 00437 00438 bool 00439 LinearPagesReader::step(Uint32 len){ 00440 m_pos += len; 00441 return m_pos < m_len; 00442 } 00443 00444 bool 00445 LinearPagesReader::getWord(Uint32 * dst) { 00446 if(m_pos<m_len){ 00447 * dst = m_base[getPos(m_pos++)]; 00448 return true; 00449 } 00450 return false; 00451 } 00452 00453 bool 00454 LinearPagesReader::peekWord(Uint32 * dst) const { 00455 if(m_pos<m_len){ 00456 * dst = m_base[getPos(m_pos)]; 00457 return true; 00458 } 00459 return false; 00460 } 00461 00462 bool 00463 LinearPagesReader::peekWords(Uint32 * dst, Uint32 len) const { 00464 if(m_pos + len <= m_len){ 00465 for(Uint32 i = 0; i<len; i++) 00466 * (dst + i) = m_base[getPos(m_pos + i)]; 00467 return true; 00468 } 00469 return false; 00470 } 00471 00472 Uint32 00473 LinearPagesReader::getPos(Uint32 pos) const { 00474 const Uint32 sz = (m_pageSz - m_pageHeaderSz); 00475 Uint32 no = pos / sz; 00476 Uint32 in = pos % sz; 00477 return no * m_pageSz + m_pageHeaderSz + in; 00478 } 00479 00480 LinearPagesWriter::LinearPagesWriter(Uint32 * base, 00481 Uint32 pageSize, 00482 Uint32 noOfPages, 00483 Uint32 headerSize){ 00484 m_base = base; 00485 m_pageSz = pageSize; 00486 m_noOfPages = noOfPages; 00487 m_pageHeaderSz = headerSize; 00488 m_len = noOfPages * (pageSize - headerSize); 00489 reset(); 00490 } 00491 00492 bool 00493 LinearPagesWriter::putWord(Uint32 val){ 00494 if(m_pos < m_len){ 00495 m_base[getPos(m_pos++)] = val; 00496 return true; 00497 } 00498 return false; 00499 } 00500 00501 bool 00502 LinearPagesWriter::putWords(const Uint32 * src, Uint32 len){ 00503 if(m_pos + len <= m_len){ 00504 for(Uint32 i = 0; i<len; i++) 00505 m_base[getPos(m_pos++)] = src[i]; 00506 return true; 00507 } 00508 return false; 00509 } 00510 00511 #if 0 00512 Uint32 00513 LinearPagesWriter::getWordsUsed() const { 00514 return getPos(m_pos); 00515 } 00516 #endif 00517 00518 Uint32 00519 LinearPagesWriter::getPagesUsed() const { 00520 return m_pos / (m_pageSz - m_pageHeaderSz); 00521 } 00522 00523 Uint32 00524 LinearPagesWriter::getPos(Uint32 pos) const { 00525 const Uint32 sz = (m_pageSz - m_pageHeaderSz); 00526 Uint32 no = pos / sz; 00527 Uint32 in = pos % sz; 00528 return no * m_pageSz + m_pageHeaderSz + in; 00529 } 00530 #endif
1.4.7

