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