1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include "dbase/DTable.hxx" 31 #include "dbase/DIndex.hxx" 32 #include "dbase/dindexnode.hxx" 33 #include <tools/debug.hxx> 34 #include "diagnose_ex.h" 35 36 #include <sal/types.h> 37 #include <algorithm> 38 #include <rtl/logfile.hxx> 39 40 using namespace connectivity; 41 using namespace connectivity::dbase; 42 using namespace com::sun::star::uno; 43 using namespace com::sun::star::sdbc; 44 //------------------------------------------------------------------ 45 sal_Bool ODbaseTable::seekRow(IResultSetHelper::Movement eCursorPosition, sal_Int32 nOffset, sal_Int32& nCurPos) 46 { 47 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::seekRow" ); 48 // ---------------------------------------------------------- 49 // Positionierung vorbereiten: 50 OSL_ENSURE(m_pFileStream,"ODbaseTable::seekRow: FileStream is NULL!"); 51 52 sal_uInt32 nNumberOfRecords = (sal_uInt32)m_aHeader.db_anz; 53 sal_uInt32 nTempPos = m_nFilePos; 54 m_nFilePos = nCurPos; 55 56 switch(eCursorPosition) 57 { 58 case IResultSetHelper::NEXT: 59 ++m_nFilePos; 60 break; 61 case IResultSetHelper::PRIOR: 62 if (m_nFilePos > 0) 63 --m_nFilePos; 64 break; 65 case IResultSetHelper::FIRST: 66 m_nFilePos = 1; 67 break; 68 case IResultSetHelper::LAST: 69 m_nFilePos = nNumberOfRecords; 70 break; 71 case IResultSetHelper::RELATIVE: 72 m_nFilePos = (((sal_Int32)m_nFilePos) + nOffset < 0) ? 0L 73 : (sal_uInt32)(((sal_Int32)m_nFilePos) + nOffset); 74 break; 75 case IResultSetHelper::ABSOLUTE: 76 case IResultSetHelper::BOOKMARK: 77 m_nFilePos = (sal_uInt32)nOffset; 78 break; 79 } 80 81 if (m_nFilePos > (sal_Int32)nNumberOfRecords) 82 m_nFilePos = (sal_Int32)nNumberOfRecords + 1; 83 84 if (m_nFilePos == 0 || m_nFilePos == (sal_Int32)nNumberOfRecords + 1) 85 goto Error; 86 else 87 { 88 sal_uInt16 nEntryLen = m_aHeader.db_slng; 89 90 OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position"); 91 sal_Int32 nPos = m_aHeader.db_kopf + (sal_Int32)(m_nFilePos-1) * nEntryLen; 92 93 sal_uIntPtr nLen = m_pFileStream->Seek(nPos); 94 if (m_pFileStream->GetError() != ERRCODE_NONE) 95 goto Error; 96 97 nLen = m_pFileStream->Read((char*)m_pBuffer, nEntryLen); 98 if (m_pFileStream->GetError() != ERRCODE_NONE) 99 goto Error; 100 } 101 goto End; 102 103 Error: 104 switch(eCursorPosition) 105 { 106 case IResultSetHelper::PRIOR: 107 case IResultSetHelper::FIRST: 108 m_nFilePos = 0; 109 break; 110 case IResultSetHelper::LAST: 111 case IResultSetHelper::NEXT: 112 case IResultSetHelper::ABSOLUTE: 113 case IResultSetHelper::RELATIVE: 114 if (nOffset > 0) 115 m_nFilePos = nNumberOfRecords + 1; 116 else if (nOffset < 0) 117 m_nFilePos = 0; 118 break; 119 case IResultSetHelper::BOOKMARK: 120 m_nFilePos = nTempPos; // vorherige Position 121 } 122 // aStatus.Set(SDB_STAT_NO_DATA_FOUND); 123 return sal_False; 124 125 End: 126 nCurPos = m_nFilePos; 127 return sal_True; 128 } 129 // ----------------------------------------------------------------------------- 130 sal_Bool ODbaseTable::ReadMemo(sal_uIntPtr nBlockNo, ORowSetValue& aVariable) 131 { 132 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::ReadMemo" ); 133 sal_Bool bIsText = sal_True; 134 // SdbConnection* pConnection = GetConnection(); 135 136 m_pMemoStream->Seek(nBlockNo * m_aMemoHeader.db_size); 137 switch (m_aMemoHeader.db_typ) 138 { 139 case MemodBaseIII: // dBase III-Memofeld, endet mit Ctrl-Z 140 { 141 const char cEOF = (char) 0x1a; 142 ByteString aBStr; 143 static char aBuf[514]; 144 aBuf[512] = 0; // sonst kann der Zufall uebel mitspielen 145 sal_Bool bReady = sal_False; 146 147 do 148 { 149 m_pMemoStream->Read(&aBuf,512); 150 151 sal_uInt16 i = 0; 152 while (aBuf[i] != cEOF && ++i < 512) 153 ; 154 bReady = aBuf[i] == cEOF; 155 156 aBuf[i] = 0; 157 aBStr += aBuf; 158 159 } while (!bReady && !m_pMemoStream->IsEof() && aBStr.Len() < STRING_MAXLEN); 160 161 ::rtl::OUString aStr(aBStr.GetBuffer(), aBStr.Len(),getConnection()->getTextEncoding()); 162 aVariable = aStr; 163 164 } break; 165 case MemoFoxPro: 166 case MemodBaseIV: // dBase IV-Memofeld mit Laengenangabe 167 { 168 char sHeader[4]; 169 m_pMemoStream->Read(sHeader,4); 170 // Foxpro stores text and binary data 171 if (m_aMemoHeader.db_typ == MemoFoxPro) 172 { 173 if (((sal_uInt8)sHeader[0]) != 0 || ((sal_uInt8)sHeader[1]) != 0 || ((sal_uInt8)sHeader[2]) != 0) 174 { 175 // String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID)); 176 // aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName()); 177 // aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO)); 178 // aStatus.Set(SDB_STAT_ERROR, 179 // String::CreateFromAscii("01000"), 180 // aStatus.CreateErrorMessage(aText), 181 // 0, String() ); 182 return sal_False; 183 } 184 185 bIsText = sHeader[3] != 0; 186 } 187 else if (((sal_uInt8)sHeader[0]) != 0xFF || ((sal_uInt8)sHeader[1]) != 0xFF || ((sal_uInt8)sHeader[2]) != 0x08) 188 { 189 // String aText = String(SdbResId(STR_STAT_IResultSetHelper::INVALID)); 190 // aText.SearchAndReplace(String::CreateFromAscii("%%d"),m_pMemoStream->GetFileName()); 191 // aText.SearchAndReplace(String::CreateFromAscii("%%t"),aStatus.TypeToString(MEMO)); 192 // aStatus.Set(SDB_STAT_ERROR, 193 // String::CreateFromAscii("01000"), 194 // aStatus.CreateErrorMessage(aText), 195 // 0, String() ); 196 return sal_False; 197 } 198 199 sal_uInt32 nLength; 200 (*m_pMemoStream) >> nLength; 201 202 if (m_aMemoHeader.db_typ == MemodBaseIV) 203 nLength -= 8; 204 205 // char cChar; 206 ::rtl::OUString aStr; 207 while ( nLength > STRING_MAXLEN ) 208 { 209 ByteString aBStr; 210 aBStr.Expand(STRING_MAXLEN); 211 m_pMemoStream->Read(aBStr.AllocBuffer(STRING_MAXLEN),STRING_MAXLEN); 212 aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding()); 213 nLength -= STRING_MAXLEN; 214 } 215 if ( nLength > 0 ) 216 { 217 ByteString aBStr; 218 aBStr.Expand(static_cast<xub_StrLen>(nLength)); 219 m_pMemoStream->Read(aBStr.AllocBuffer(static_cast<xub_StrLen>(nLength)),nLength); 220 // aBStr.ReleaseBufferAccess(); 221 222 aStr += ::rtl::OUString(aBStr.GetBuffer(),aBStr.Len(), getConnection()->getTextEncoding()); 223 224 } 225 if ( aStr.getLength() ) 226 aVariable = aStr; 227 } 228 } 229 return sal_True; 230 } 231 // ----------------------------------------------------------------------------- 232 void ODbaseTable::AllocBuffer() 233 { 234 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::AllocBuffer" ); 235 sal_uInt16 nSize = m_aHeader.db_slng; 236 OSL_ENSURE(nSize > 0, "Size too small"); 237 238 if (m_nBufferSize != nSize) 239 { 240 delete[] m_pBuffer; 241 m_pBuffer = NULL; 242 } 243 244 // Falls noch kein Puffer vorhanden: allozieren: 245 if (m_pBuffer == NULL && nSize > 0) 246 { 247 m_nBufferSize = nSize; 248 m_pBuffer = new sal_uInt8[m_nBufferSize+1]; 249 } 250 } 251 // ----------------------------------------------------------------------------- 252 sal_Bool ODbaseTable::WriteBuffer() 253 { 254 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::WriteBuffer" ); 255 OSL_ENSURE(m_nFilePos >= 1,"SdbDBFCursor::FileFetchRow: ungueltige Record-Position"); 256 257 // Auf gewuenschten Record positionieren: 258 long nPos = m_aHeader.db_kopf + (long)(m_nFilePos-1) * m_aHeader.db_slng; 259 m_pFileStream->Seek(nPos); 260 return m_pFileStream->Write((char*) m_pBuffer, m_aHeader.db_slng) > 0; 261 } 262 // ----------------------------------------------------------------------------- 263 sal_Int32 ODbaseTable::getCurrentLastPos() const 264 { 265 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ODbaseTable::getCurrentLastPos" ); 266 return m_aHeader.db_anz; 267 } 268 // ----------------------------------------------------------------------------- 269 //================================================================== 270 // ONDXNode 271 //================================================================== 272 273 //------------------------------------------------------------------ 274 void ONDXNode::Read(SvStream &rStream, ODbaseIndex& rIndex) 275 { 276 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Read" ); 277 rStream >> aKey.nRecord; // schluessel 278 279 if (rIndex.getHeader().db_keytype) 280 { 281 double aDbl; 282 rStream >> aDbl; 283 aKey = ONDXKey(aDbl,aKey.nRecord); 284 } 285 else 286 { 287 ByteString aBuf; 288 sal_uInt16 nLen = rIndex.getHeader().db_keylen; 289 char* pStr = aBuf.AllocBuffer(nLen+1); 290 291 rStream.Read(pStr,nLen); 292 pStr[nLen] = 0; 293 aBuf.ReleaseBufferAccess(); 294 aBuf.EraseTrailingChars(); 295 296 // aKey = ONDXKey((aBuf,rIndex.GetDBFConnection()->GetCharacterSet()) ,aKey.nRecord); 297 aKey = ONDXKey(::rtl::OUString(aBuf.GetBuffer(),aBuf.Len(),rIndex.m_pTable->getConnection()->getTextEncoding()) ,aKey.nRecord); 298 } 299 rStream >> aChild; 300 } 301 302 union 303 { 304 double aDbl; 305 char aData[128]; 306 } aNodeData; 307 //------------------------------------------------------------------ 308 void ONDXNode::Write(SvStream &rStream, const ONDXPage& rPage) const 309 { 310 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::Write" ); 311 const ODbaseIndex& rIndex = rPage.GetIndex(); 312 if (!rIndex.isUnique() || rPage.IsLeaf()) 313 rStream << (sal_uInt32)aKey.nRecord; // schluessel 314 else 315 rStream << (sal_uInt32)0; // schluessel 316 317 if (rIndex.getHeader().db_keytype) // double 318 { 319 if (aKey.getValue().isNull()) 320 { 321 memset(aNodeData.aData,0,rIndex.getHeader().db_keylen); 322 rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 323 } 324 else 325 rStream << (double) aKey.getValue(); 326 } 327 else 328 { 329 memset(aNodeData.aData,0x20,rIndex.getHeader().db_keylen); 330 if (!aKey.getValue().isNull()) 331 { 332 ::rtl::OUString sValue = aKey.getValue(); 333 ByteString aText(sValue.getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()); 334 strncpy(aNodeData.aData,aText.GetBuffer(),std::min(rIndex.getHeader().db_keylen, aText.Len())); 335 } 336 rStream.Write((sal_uInt8*)aNodeData.aData,rIndex.getHeader().db_keylen); 337 } 338 rStream << aChild; 339 } 340 341 342 //------------------------------------------------------------------ 343 ONDXPagePtr& ONDXNode::GetChild(ODbaseIndex* pIndex, ONDXPage* pParent) 344 { 345 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXNode::GetChild" ); 346 if (!aChild.Is() && pIndex) 347 { 348 aChild = pIndex->CreatePage(aChild.GetPagePos(),pParent,aChild.HasPage()); 349 } 350 return aChild; 351 } 352 353 //================================================================== 354 // ONDXKey 355 //================================================================== 356 //------------------------------------------------------------------ 357 sal_Bool ONDXKey::IsText(sal_Int32 eType) 358 { 359 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::IsText" ); 360 return eType == DataType::VARCHAR || eType == DataType::CHAR; 361 } 362 363 //------------------------------------------------------------------ 364 StringCompare ONDXKey::Compare(const ONDXKey& rKey) const 365 { 366 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::Compare" ); 367 // DBG_ASSERT(is(), "Falscher Indexzugriff"); 368 StringCompare eResult; 369 370 if (getValue().isNull()) 371 { 372 if (rKey.getValue().isNull() || (rKey.IsText(getDBType()) && !rKey.getValue().getString().getLength())) 373 eResult = COMPARE_EQUAL; 374 else 375 eResult = COMPARE_LESS; 376 } 377 else if (rKey.getValue().isNull()) 378 { 379 if (getValue().isNull() || (IsText(getDBType()) && !getValue().getString().getLength())) 380 eResult = COMPARE_EQUAL; 381 else 382 eResult = COMPARE_GREATER; 383 } 384 else if (IsText(getDBType())) 385 { 386 sal_Int32 nRes = getValue().getString().compareTo(rKey.getValue()); 387 eResult = (nRes > 0) ? COMPARE_GREATER : (nRes == 0) ? COMPARE_EQUAL : COMPARE_LESS; 388 } 389 else 390 { 391 double m = getValue(),n = rKey.getValue(); 392 eResult = (m > n) ? COMPARE_GREATER : (n == m) ? COMPARE_EQUAL : COMPARE_LESS; 393 } 394 395 // Record vergleich, wenn Index !Unique 396 if (eResult == COMPARE_EQUAL && nRecord && rKey.nRecord) 397 eResult = (nRecord > rKey.nRecord) ? COMPARE_GREATER : 398 (nRecord == rKey.nRecord) ? COMPARE_EQUAL : COMPARE_LESS; 399 400 return eResult; 401 } 402 // ----------------------------------------------------------------------------- 403 void ONDXKey::setValue(const ORowSetValue& _rVal) 404 { 405 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::setValue" ); 406 xValue = _rVal; 407 } 408 // ----------------------------------------------------------------------------- 409 const ORowSetValue& ONDXKey::getValue() const 410 { 411 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXKey::getValue" ); 412 return xValue; 413 } 414 // ----------------------------------------------------------------------------- 415 SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPagePtr& rPage) 416 { 417 rStream >> rPage.nPagePos; 418 return rStream; 419 } 420 // ----------------------------------------------------------------------------- 421 SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPagePtr& rPage) 422 { 423 rStream << rPage.nPagePos; 424 return rStream; 425 } 426 // ----------------------------------------------------------------------------- 427 //================================================================== 428 // ONDXPagePtr 429 //================================================================== 430 //------------------------------------------------------------------ 431 ONDXPagePtr::ONDXPagePtr(const ONDXPagePtr& rRef) 432 :ONDXPageRef(rRef) 433 ,nPagePos(rRef.nPagePos) 434 { 435 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" ); 436 } 437 438 //------------------------------------------------------------------ 439 ONDXPagePtr::ONDXPagePtr(ONDXPage* pRefPage) 440 :ONDXPageRef(pRefPage) 441 ,nPagePos(0) 442 { 443 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPagePtr::ONDXPagePtr" ); 444 if (pRefPage) 445 nPagePos = pRefPage->GetPagePos(); 446 } 447 //------------------------------------------------------------------ 448 ONDXPagePtr& ONDXPagePtr::operator=(const ONDXPagePtr& rRef) 449 { 450 ONDXPageRef::operator=(rRef); 451 nPagePos = rRef.nPagePos; 452 return *this; 453 } 454 455 //------------------------------------------------------------------ 456 ONDXPagePtr& ONDXPagePtr::operator= (ONDXPage* pRef) 457 { 458 ONDXPageRef::operator=(pRef); 459 nPagePos = (pRef) ? pRef->GetPagePos() : 0; 460 return *this; 461 } 462 // ----------------------------------------------------------------------------- 463 static sal_uInt32 nValue; 464 //------------------------------------------------------------------ 465 SvStream& connectivity::dbase::operator >> (SvStream &rStream, ONDXPage& rPage) 466 { 467 rStream.Seek(rPage.GetPagePos() * 512); 468 rStream >> nValue >> rPage.aChild; 469 rPage.nCount = sal_uInt16(nValue); 470 471 // DBG_ASSERT(rPage.nCount && rPage.nCount < rPage.GetIndex().GetMaxNodes(), "Falscher Count"); 472 for (sal_uInt16 i = 0; i < rPage.nCount; i++) 473 rPage[i].Read(rStream, rPage.GetIndex()); 474 return rStream; 475 } 476 477 //------------------------------------------------------------------ 478 SvStream& connectivity::dbase::operator << (SvStream &rStream, const ONDXPage& rPage) 479 { 480 // Seite existiert noch nicht 481 sal_uIntPtr nSize = (rPage.GetPagePos() + 1) * 512; 482 if (nSize > rStream.Seek(STREAM_SEEK_TO_END)) 483 { 484 rStream.SetStreamSize(nSize); 485 rStream.Seek(rPage.GetPagePos() * 512); 486 487 char aEmptyData[512]; 488 memset(aEmptyData,0x00,512); 489 rStream.Write((sal_uInt8*)aEmptyData,512); 490 } 491 sal_uIntPtr nCurrentPos = rStream.Seek(rPage.GetPagePos() * 512); 492 OSL_UNUSED( nCurrentPos ); 493 494 nValue = rPage.nCount; 495 rStream << nValue << rPage.aChild; 496 497 sal_uInt16 i = 0; 498 for (; i < rPage.nCount; i++) 499 rPage[i].Write(rStream, rPage); 500 501 // check if we have to fill the stream with '\0' 502 if(i < rPage.rIndex.getHeader().db_maxkeys) 503 { 504 sal_uIntPtr nTell = rStream.Tell() % 512; 505 sal_uInt16 nBufferSize = rStream.GetBufferSize(); 506 sal_uIntPtr nSize = nBufferSize - nTell; 507 if ( nSize <= nBufferSize ) 508 { 509 char* pEmptyData = new char[nSize]; 510 memset(pEmptyData,0x00,nSize); 511 rStream.Write((sal_uInt8*)pEmptyData,nSize); 512 rStream.Seek(nTell); 513 delete [] pEmptyData; 514 } 515 } 516 return rStream; 517 } 518 // ----------------------------------------------------------------------------- 519 #if OSL_DEBUG_LEVEL > 1 520 //------------------------------------------------------------------ 521 void ONDXPage::PrintPage() 522 { 523 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::PrintPage" ); 524 DBG_TRACE4("\nSDB: -----------Page: %d Parent: %d Count: %d Child: %d-----", 525 nPagePos, HasParent() ? aParent->GetPagePos() : 0 ,nCount, aChild.GetPagePos()); 526 527 for (sal_uInt16 i = 0; i < nCount; i++) 528 { 529 ONDXNode rNode = (*this)[i]; 530 ONDXKey& rKey = rNode.GetKey(); 531 if (!IsLeaf()) 532 rNode.GetChild(&rIndex, this); 533 534 if (rKey.getValue().isNull()) 535 { 536 DBG_TRACE2("SDB: [%d,NULL,%d]",rKey.GetRecord(), rNode.GetChild().GetPagePos()); 537 } 538 else if (rIndex.getHeader().db_keytype) 539 { 540 DBG_TRACE3("SDB: [%d,%f,%d]",rKey.GetRecord(), rKey.getValue().getDouble(),rNode.GetChild().GetPagePos()); 541 } 542 else 543 { 544 DBG_TRACE3("SDB: [%d,%s,%d]",rKey.GetRecord(), (const char* )ByteString(rKey.getValue().getString().getStr(), rIndex.m_pTable->getConnection()->getTextEncoding()).GetBuffer(),rNode.GetChild().GetPagePos()); 545 } 546 } 547 DBG_TRACE("SDB: -----------------------------------------------\n"); 548 if (!IsLeaf()) 549 { 550 #if OSL_DEBUG_LEVEL > 1 551 GetChild(&rIndex)->PrintPage(); 552 for (sal_uInt16 i = 0; i < nCount; i++) 553 { 554 ONDXNode rNode = (*this)[i]; 555 rNode.GetChild(&rIndex,this)->PrintPage(); 556 } 557 #endif 558 } 559 DBG_TRACE("SDB: ===============================================\n"); 560 } 561 #endif 562 // ----------------------------------------------------------------------------- 563 sal_Bool ONDXPage::IsFull() const 564 { 565 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::IsFull" ); 566 return Count() == rIndex.getHeader().db_maxkeys; 567 } 568 // ----------------------------------------------------------------------------- 569 //------------------------------------------------------------------ 570 sal_uInt16 ONDXPage::Search(const ONDXKey& rSearch) 571 { 572 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" ); 573 // binare Suche spaeter 574 sal_uInt16 i = 0xFFFF; 575 while (++i < Count()) 576 if ((*this)[i].GetKey() == rSearch) 577 break; 578 579 return (i < Count()) ? i : NODE_NOTFOUND; 580 } 581 582 //------------------------------------------------------------------ 583 sal_uInt16 ONDXPage::Search(const ONDXPage* pPage) 584 { 585 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Search" ); 586 sal_uInt16 i = 0xFFFF; 587 while (++i < Count()) 588 if (((*this)[i]).GetChild() == pPage) 589 break; 590 591 // wenn nicht gefunden, dann wird davon ausgegangen, dass die Seite selbst 592 // auf die Page zeigt 593 return (i < Count()) ? i : NODE_NOTFOUND; 594 } 595 // ----------------------------------------------------------------------------- 596 // laeuft rekursiv 597 void ONDXPage::SearchAndReplace(const ONDXKey& rSearch, 598 ONDXKey& rReplace) 599 { 600 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::SearchAndReplace" ); 601 OSL_ENSURE(rSearch != rReplace,"Invalid here:rSearch == rReplace"); 602 if (rSearch != rReplace) 603 { 604 sal_uInt16 nPos = NODE_NOTFOUND; 605 ONDXPage* pPage = this; 606 607 while (pPage && (nPos = pPage->Search(rSearch)) == NODE_NOTFOUND) 608 pPage = pPage->aParent; 609 610 if (pPage) 611 { 612 (*pPage)[nPos].GetKey() = rReplace; 613 pPage->SetModified(sal_True); 614 } 615 } 616 } 617 // ----------------------------------------------------------------------------- 618 ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) 619 { 620 DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 621 return ppNodes[nPos]; 622 } 623 624 //------------------------------------------------------------------ 625 const ONDXNode& ONDXPage::operator[] (sal_uInt16 nPos) const 626 { 627 DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 628 return ppNodes[nPos]; 629 } 630 // ----------------------------------------------------------------------------- 631 void ONDXPage::Remove(sal_uInt16 nPos) 632 { 633 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbase", "Ocke.Janssen@sun.com", "ONDXPage::Remove" ); 634 DBG_ASSERT(nCount > nPos, "falscher Indexzugriff"); 635 636 for (sal_uInt16 i = nPos; i < (nCount-1); i++) 637 (*this)[i] = (*this)[i+1]; 638 639 nCount--; 640 bModified = sal_True; 641 } 642 // ----------------------------------------------------------------------------- 643 644 645 646 647 648 649 650 651 652 653 654