security/manager/pki/src/nsASN1Tree.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 #include "nsASN1Tree.h"
michael@0 5 #include "nsIComponentManager.h"
michael@0 6 #include "nsString.h"
michael@0 7 #include "nsCRT.h"
michael@0 8 #include "nsIMutableArray.h"
michael@0 9 #include "nsArrayUtils.h"
michael@0 10
michael@0 11 NS_IMPL_ISUPPORTS(nsNSSASN1Tree, nsIASN1Tree, nsITreeView)
michael@0 12
michael@0 13 nsNSSASN1Tree::nsNSSASN1Tree()
michael@0 14 :mTopNode(nullptr)
michael@0 15 {
michael@0 16 }
michael@0 17
michael@0 18 nsNSSASN1Tree::~nsNSSASN1Tree()
michael@0 19 {
michael@0 20 ClearNodes();
michael@0 21 }
michael@0 22
michael@0 23 void nsNSSASN1Tree::ClearNodesRecursively(myNode *n)
michael@0 24 {
michael@0 25 myNode *walk = n;
michael@0 26 while (walk) {
michael@0 27 myNode *kill = walk;
michael@0 28
michael@0 29 if (walk->child) {
michael@0 30 ClearNodesRecursively(walk->child);
michael@0 31 }
michael@0 32
michael@0 33 walk = walk->next;
michael@0 34 delete kill;
michael@0 35 }
michael@0 36 }
michael@0 37
michael@0 38 void nsNSSASN1Tree::ClearNodes()
michael@0 39 {
michael@0 40 ClearNodesRecursively(mTopNode);
michael@0 41 mTopNode = nullptr;
michael@0 42 }
michael@0 43
michael@0 44 void nsNSSASN1Tree::InitChildsRecursively(myNode *n)
michael@0 45 {
michael@0 46 if (!n->obj)
michael@0 47 return;
michael@0 48
michael@0 49 n->seq = do_QueryInterface(n->obj);
michael@0 50 if (!n->seq)
michael@0 51 return;
michael@0 52
michael@0 53 // If the object is a sequence, there might still be a reason
michael@0 54 // why it should not be displayed as a container.
michael@0 55 // If we decide that it has all the properties to justify
michael@0 56 // displaying as a container, we will create a new child chain.
michael@0 57 // If we decide, it does not make sense to display as a container,
michael@0 58 // we forget that it is a sequence by erasing n->seq.
michael@0 59 // That way, n->seq and n->child will be either both set or both null.
michael@0 60
michael@0 61 bool isContainer;
michael@0 62 n->seq->GetIsValidContainer(&isContainer);
michael@0 63 if (!isContainer) {
michael@0 64 n->seq = nullptr;
michael@0 65 return;
michael@0 66 }
michael@0 67
michael@0 68 nsCOMPtr<nsIMutableArray> asn1Objects;
michael@0 69 n->seq->GetASN1Objects(getter_AddRefs(asn1Objects));
michael@0 70 uint32_t numObjects;
michael@0 71 asn1Objects->GetLength(&numObjects);
michael@0 72
michael@0 73 if (!numObjects) {
michael@0 74 n->seq = nullptr;
michael@0 75 return;
michael@0 76 }
michael@0 77
michael@0 78 myNode *walk = nullptr;
michael@0 79 myNode *prev = nullptr;
michael@0 80
michael@0 81 uint32_t i;
michael@0 82 nsCOMPtr<nsISupports> isupports;
michael@0 83 for (i=0; i<numObjects; i++) {
michael@0 84 if (0 == i) {
michael@0 85 n->child = walk = new myNode;
michael@0 86 }
michael@0 87 else {
michael@0 88 walk = new myNode;
michael@0 89 }
michael@0 90
michael@0 91 walk->parent = n;
michael@0 92 if (prev) {
michael@0 93 prev->next = walk;
michael@0 94 }
michael@0 95
michael@0 96 walk->obj = do_QueryElementAt(asn1Objects, i);
michael@0 97
michael@0 98 InitChildsRecursively(walk);
michael@0 99
michael@0 100 prev = walk;
michael@0 101 }
michael@0 102 }
michael@0 103
michael@0 104 void nsNSSASN1Tree::InitNodes()
michael@0 105 {
michael@0 106 ClearNodes();
michael@0 107
michael@0 108 mTopNode = new myNode;
michael@0 109 mTopNode->obj = mASN1Object;
michael@0 110
michael@0 111 InitChildsRecursively(mTopNode);
michael@0 112 }
michael@0 113
michael@0 114 /* void loadASN1Structure (in nsIASN1Object asn1Object); */
michael@0 115 NS_IMETHODIMP
michael@0 116 nsNSSASN1Tree::LoadASN1Structure(nsIASN1Object *asn1Object)
michael@0 117 {
michael@0 118 //
michael@0 119 // The tree won't automatically re-draw if the contents
michael@0 120 // have been changed. So I do a quick test here to let
michael@0 121 // me know if I should forced the tree to redraw itself
michael@0 122 // by calling RowCountChanged on it.
michael@0 123 //
michael@0 124 bool redraw = (mASN1Object && mTree);
michael@0 125 int32_t rowsToDelete = 0;
michael@0 126
michael@0 127 if (redraw) {
michael@0 128 // This is the number of rows we will be deleting after
michael@0 129 // the contents have changed.
michael@0 130 rowsToDelete = 0-CountVisibleNodes(mTopNode);
michael@0 131 }
michael@0 132
michael@0 133 mASN1Object = asn1Object;
michael@0 134 InitNodes();
michael@0 135
michael@0 136 if (redraw) {
michael@0 137 // The number of rows in the new content.
michael@0 138 int32_t newRows = CountVisibleNodes(mTopNode);
michael@0 139 mTree->BeginUpdateBatch();
michael@0 140 // Erase all of the old rows.
michael@0 141 mTree->RowCountChanged(0, rowsToDelete);
michael@0 142 // Replace them with the new contents
michael@0 143 mTree->RowCountChanged(0, newRows);
michael@0 144 mTree->EndUpdateBatch();
michael@0 145 }
michael@0 146
michael@0 147 return NS_OK;
michael@0 148 }
michael@0 149
michael@0 150 /* readonly attribute long rowCount; */
michael@0 151 NS_IMETHODIMP
michael@0 152 nsNSSASN1Tree::GetRowCount(int32_t *aRowCount)
michael@0 153 {
michael@0 154 if (mASN1Object) {
michael@0 155 *aRowCount = CountVisibleNodes(mTopNode);
michael@0 156 } else {
michael@0 157 *aRowCount = 0;
michael@0 158 }
michael@0 159 return NS_OK;
michael@0 160 }
michael@0 161
michael@0 162 /* attribute nsITreeSelection selection; */
michael@0 163 NS_IMETHODIMP
michael@0 164 nsNSSASN1Tree::GetSelection(nsITreeSelection * *aSelection)
michael@0 165 {
michael@0 166 *aSelection = mSelection;
michael@0 167 NS_IF_ADDREF(*aSelection);
michael@0 168 return NS_OK;
michael@0 169 }
michael@0 170
michael@0 171 NS_IMETHODIMP
michael@0 172 nsNSSASN1Tree::SetSelection(nsITreeSelection * aSelection)
michael@0 173 {
michael@0 174 mSelection = aSelection;
michael@0 175 return NS_OK;
michael@0 176 }
michael@0 177
michael@0 178 NS_IMETHODIMP
michael@0 179 nsNSSASN1Tree::GetRowProperties(int32_t index, nsAString& aProps)
michael@0 180 {
michael@0 181 return NS_OK;
michael@0 182 }
michael@0 183
michael@0 184 NS_IMETHODIMP
michael@0 185 nsNSSASN1Tree::GetCellProperties(int32_t row, nsITreeColumn* col,
michael@0 186 nsAString& aProps)
michael@0 187 {
michael@0 188 return NS_OK;
michael@0 189 }
michael@0 190
michael@0 191 NS_IMETHODIMP
michael@0 192 nsNSSASN1Tree::GetColumnProperties(nsITreeColumn* col, nsAString& aProps)
michael@0 193 {
michael@0 194 return NS_OK;
michael@0 195 }
michael@0 196
michael@0 197 /* boolean isContainer (in long index); */
michael@0 198 NS_IMETHODIMP
michael@0 199 nsNSSASN1Tree::IsContainer(int32_t index, bool *_retval)
michael@0 200 {
michael@0 201 myNode *n = FindNodeFromIndex(index);
michael@0 202 if (!n)
michael@0 203 return NS_ERROR_FAILURE;
michael@0 204
michael@0 205 *_retval = (n->seq != nullptr);
michael@0 206 return NS_OK;
michael@0 207 }
michael@0 208
michael@0 209 /* boolean isContainerOpen (in long index); */
michael@0 210 NS_IMETHODIMP
michael@0 211 nsNSSASN1Tree::IsContainerOpen(int32_t index, bool *_retval)
michael@0 212 {
michael@0 213 myNode *n = FindNodeFromIndex(index);
michael@0 214 if (!n || !n->seq)
michael@0 215 return NS_ERROR_FAILURE;
michael@0 216
michael@0 217 n->seq->GetIsExpanded(_retval);
michael@0 218 return NS_OK;
michael@0 219 }
michael@0 220
michael@0 221 /* boolean isContainerEmpty (in long index); */
michael@0 222 NS_IMETHODIMP
michael@0 223 nsNSSASN1Tree::IsContainerEmpty(int32_t index, bool *_retval)
michael@0 224 {
michael@0 225 *_retval = false;
michael@0 226 return NS_OK;
michael@0 227 }
michael@0 228
michael@0 229 /* boolean isSeparator (in long index); */
michael@0 230 NS_IMETHODIMP
michael@0 231 nsNSSASN1Tree::IsSeparator(int32_t index, bool *_retval)
michael@0 232 {
michael@0 233 *_retval = false;
michael@0 234 return NS_OK;
michael@0 235 }
michael@0 236
michael@0 237 /* long getLevel (in long index); */
michael@0 238 NS_IMETHODIMP
michael@0 239 nsNSSASN1Tree::GetLevel(int32_t index, int32_t *_retval)
michael@0 240 {
michael@0 241 int32_t parentIndex;
michael@0 242 int32_t nodeLevel;
michael@0 243
michael@0 244 myNode *n = FindNodeFromIndex(index, &parentIndex, &nodeLevel);
michael@0 245 if (!n)
michael@0 246 return NS_ERROR_FAILURE;
michael@0 247
michael@0 248 *_retval = nodeLevel;
michael@0 249 return NS_OK;
michael@0 250 }
michael@0 251
michael@0 252 /* Astring getImageSrc (in long row, in nsITreeColumn col); */
michael@0 253 NS_IMETHODIMP
michael@0 254 nsNSSASN1Tree::GetImageSrc(int32_t row, nsITreeColumn* col,
michael@0 255 nsAString& _retval)
michael@0 256 {
michael@0 257 return NS_OK;
michael@0 258 }
michael@0 259
michael@0 260 /* long getProgressMode (in long row, in nsITreeColumn col); */
michael@0 261 NS_IMETHODIMP
michael@0 262 nsNSSASN1Tree::GetProgressMode(int32_t row, nsITreeColumn* col, int32_t* _retval)
michael@0 263 {
michael@0 264 return NS_OK;
michael@0 265 }
michael@0 266
michael@0 267 /* Astring getCellValue (in long row, in nsITreeColumn col); */
michael@0 268 NS_IMETHODIMP
michael@0 269 nsNSSASN1Tree::GetCellValue(int32_t row, nsITreeColumn* col,
michael@0 270 nsAString& _retval)
michael@0 271 {
michael@0 272 return NS_OK;
michael@0 273 }
michael@0 274
michael@0 275 /* Astring getCellText (in long row, in nsITreeColumn col); */
michael@0 276 NS_IMETHODIMP
michael@0 277 nsNSSASN1Tree::GetCellText(int32_t row, nsITreeColumn* col,
michael@0 278 nsAString& _retval)
michael@0 279 {
michael@0 280 _retval.Truncate();
michael@0 281
michael@0 282 myNode* n = FindNodeFromIndex(row);
michael@0 283 if (!n)
michael@0 284 return NS_ERROR_FAILURE;
michael@0 285
michael@0 286 // There's only one column for ASN1 dump.
michael@0 287 return n->obj->GetDisplayName(_retval);
michael@0 288 }
michael@0 289
michael@0 290 /* wstring getDisplayData (in unsigned long index); */
michael@0 291 NS_IMETHODIMP
michael@0 292 nsNSSASN1Tree::GetDisplayData(uint32_t index, nsAString &_retval)
michael@0 293 {
michael@0 294 myNode *n = FindNodeFromIndex(index);
michael@0 295 if (!n)
michael@0 296 return NS_ERROR_FAILURE;
michael@0 297
michael@0 298 n->obj->GetDisplayValue(_retval);
michael@0 299 return NS_OK;
michael@0 300 }
michael@0 301
michael@0 302 /* void setTree (in nsITreeBoxObject tree); */
michael@0 303 NS_IMETHODIMP
michael@0 304 nsNSSASN1Tree::SetTree(nsITreeBoxObject *tree)
michael@0 305 {
michael@0 306 mTree = tree;
michael@0 307 return NS_OK;
michael@0 308 }
michael@0 309
michael@0 310 /* void toggleOpenState (in long index); */
michael@0 311 NS_IMETHODIMP
michael@0 312 nsNSSASN1Tree::ToggleOpenState(int32_t index)
michael@0 313 {
michael@0 314 myNode *n = FindNodeFromIndex(index);
michael@0 315 if (!n)
michael@0 316 return NS_ERROR_FAILURE;
michael@0 317
michael@0 318 if (!n->seq)
michael@0 319 return NS_ERROR_FAILURE;
michael@0 320
michael@0 321 bool IsExpanded;
michael@0 322 n->seq->GetIsExpanded(&IsExpanded);
michael@0 323 int32_t rowCountChange;
michael@0 324 if (IsExpanded) {
michael@0 325 rowCountChange = -CountVisibleNodes(n->child);
michael@0 326 n->seq->SetIsExpanded(false);
michael@0 327 } else {
michael@0 328 n->seq->SetIsExpanded(true);
michael@0 329 rowCountChange = CountVisibleNodes(n->child);
michael@0 330 }
michael@0 331 if (mTree)
michael@0 332 mTree->RowCountChanged(index, rowCountChange);
michael@0 333 return NS_OK;
michael@0 334 }
michael@0 335
michael@0 336 /* void cycleHeader (in nsITreeColumn col); */
michael@0 337 NS_IMETHODIMP
michael@0 338 nsNSSASN1Tree::CycleHeader(nsITreeColumn* col)
michael@0 339 {
michael@0 340 return NS_OK;
michael@0 341 }
michael@0 342
michael@0 343 /* void selectionChanged (); */
michael@0 344 NS_IMETHODIMP
michael@0 345 nsNSSASN1Tree::SelectionChanged()
michael@0 346 {
michael@0 347 return NS_ERROR_NOT_IMPLEMENTED;
michael@0 348 }
michael@0 349
michael@0 350 /* void cycleCell (in long row, in nsITreeColumn col); */
michael@0 351 NS_IMETHODIMP
michael@0 352 nsNSSASN1Tree::CycleCell(int32_t row, nsITreeColumn* col)
michael@0 353 {
michael@0 354 return NS_OK;
michael@0 355 }
michael@0 356
michael@0 357 /* boolean isEditable (in long row, in nsITreeColumn col); */
michael@0 358 NS_IMETHODIMP
michael@0 359 nsNSSASN1Tree::IsEditable(int32_t row, nsITreeColumn* col,
michael@0 360 bool *_retval)
michael@0 361 {
michael@0 362 *_retval = false;
michael@0 363 return NS_OK;
michael@0 364 }
michael@0 365
michael@0 366 /* boolean isSelectable (in long row, in nsITreeColumn col); */
michael@0 367 NS_IMETHODIMP
michael@0 368 nsNSSASN1Tree::IsSelectable(int32_t row, nsITreeColumn* col,
michael@0 369 bool *_retval)
michael@0 370 {
michael@0 371 *_retval = false;
michael@0 372 return NS_OK;
michael@0 373 }
michael@0 374
michael@0 375 /* void setCellValue (in long row, in nsITreeColumn col, in AString value); */
michael@0 376 NS_IMETHODIMP
michael@0 377 nsNSSASN1Tree::SetCellValue(int32_t row, nsITreeColumn* col,
michael@0 378 const nsAString& value)
michael@0 379 {
michael@0 380 return NS_OK;
michael@0 381 }
michael@0 382
michael@0 383 /* void setCellText (in long row, in nsITreeColumn col, in AString value); */
michael@0 384 NS_IMETHODIMP
michael@0 385 nsNSSASN1Tree::SetCellText(int32_t row, nsITreeColumn* col,
michael@0 386 const nsAString& value)
michael@0 387 {
michael@0 388 return NS_OK;
michael@0 389 }
michael@0 390
michael@0 391 /* void performAction (in wstring action); */
michael@0 392 NS_IMETHODIMP
michael@0 393 nsNSSASN1Tree::PerformAction(const char16_t *action)
michael@0 394 {
michael@0 395 return NS_OK;
michael@0 396 }
michael@0 397
michael@0 398 /* void performActionOnRow (in wstring action, in long row); */
michael@0 399 NS_IMETHODIMP
michael@0 400 nsNSSASN1Tree::PerformActionOnRow(const char16_t *action, int32_t row)
michael@0 401 {
michael@0 402 return NS_OK;
michael@0 403 }
michael@0 404
michael@0 405 /* void performActionOnCell (in wstring action, in long row, in nsITreeColumn col); */
michael@0 406 NS_IMETHODIMP
michael@0 407 nsNSSASN1Tree::PerformActionOnCell(const char16_t *action, int32_t row,
michael@0 408 nsITreeColumn* col)
michael@0 409 {
michael@0 410 return NS_OK;
michael@0 411 }
michael@0 412
michael@0 413 //
michael@0 414 // CanDrop
michael@0 415 //
michael@0 416 NS_IMETHODIMP nsNSSASN1Tree::CanDrop(int32_t index, int32_t orientation,
michael@0 417 nsIDOMDataTransfer* aDataTransfer, bool *_retval)
michael@0 418 {
michael@0 419 NS_ENSURE_ARG_POINTER(_retval);
michael@0 420 *_retval = false;
michael@0 421
michael@0 422 return NS_OK;
michael@0 423 }
michael@0 424
michael@0 425
michael@0 426 //
michael@0 427 // Drop
michael@0 428 //
michael@0 429 NS_IMETHODIMP nsNSSASN1Tree::Drop(int32_t row, int32_t orient, nsIDOMDataTransfer* aDataTransfer)
michael@0 430 {
michael@0 431 return NS_OK;
michael@0 432 }
michael@0 433
michael@0 434
michael@0 435 //
michael@0 436 // IsSorted
michael@0 437 //
michael@0 438 // ...
michael@0 439 //
michael@0 440 NS_IMETHODIMP nsNSSASN1Tree::IsSorted(bool *_retval)
michael@0 441 {
michael@0 442 *_retval = false;
michael@0 443 return NS_OK;
michael@0 444 }
michael@0 445
michael@0 446
michael@0 447 /* long getParentIndex (in long rowIndex); */
michael@0 448 NS_IMETHODIMP
michael@0 449 nsNSSASN1Tree::GetParentIndex(int32_t rowIndex, int32_t *_retval)
michael@0 450 {
michael@0 451 int32_t parentIndex = -1;
michael@0 452
michael@0 453 myNode *n = FindNodeFromIndex(rowIndex, &parentIndex);
michael@0 454 if (!n)
michael@0 455 return NS_ERROR_FAILURE;
michael@0 456
michael@0 457 *_retval = parentIndex;
michael@0 458 return NS_OK;
michael@0 459 }
michael@0 460
michael@0 461 /* boolean hasNextSibling (in long rowIndex, in long afterIndex); */
michael@0 462 NS_IMETHODIMP
michael@0 463 nsNSSASN1Tree::HasNextSibling(int32_t rowIndex, int32_t afterIndex,
michael@0 464 bool *_retval)
michael@0 465 {
michael@0 466 myNode *n = FindNodeFromIndex(rowIndex);
michael@0 467 if (!n)
michael@0 468 return NS_ERROR_FAILURE;
michael@0 469
michael@0 470 if (!n->next) {
michael@0 471 *_retval = false;
michael@0 472 }
michael@0 473 else {
michael@0 474 int32_t nTotalSize = CountVisibleNodes(n);
michael@0 475 int32_t nLastChildPos = rowIndex + nTotalSize -1;
michael@0 476 int32_t nextSiblingPos = nLastChildPos +1;
michael@0 477 *_retval = (nextSiblingPos > afterIndex);
michael@0 478 }
michael@0 479
michael@0 480 return NS_OK;
michael@0 481 }
michael@0 482
michael@0 483 int32_t nsNSSASN1Tree::CountVisibleNodes(myNode *n)
michael@0 484 {
michael@0 485 if (!n)
michael@0 486 return 0;
michael@0 487
michael@0 488 myNode *walk = n;
michael@0 489 int32_t count = 0;
michael@0 490
michael@0 491 while (walk) {
michael@0 492 ++count;
michael@0 493
michael@0 494 if (walk->seq) {
michael@0 495 bool IsExpanded;
michael@0 496 walk->seq->GetIsExpanded(&IsExpanded);
michael@0 497 if (IsExpanded) {
michael@0 498 count += CountVisibleNodes(walk->child);
michael@0 499 }
michael@0 500 }
michael@0 501
michael@0 502 walk = walk->next;
michael@0 503 }
michael@0 504
michael@0 505 return count;
michael@0 506 }
michael@0 507
michael@0 508 // Entry point for find
michael@0 509 nsNSSASN1Tree::myNode *
michael@0 510 nsNSSASN1Tree::FindNodeFromIndex(int32_t wantedIndex,
michael@0 511 int32_t *optionalOutParentIndex, int32_t *optionalOutLevel)
michael@0 512 {
michael@0 513 if (0 == wantedIndex) {
michael@0 514 if (optionalOutLevel) {
michael@0 515 *optionalOutLevel = 0;
michael@0 516 }
michael@0 517 if (optionalOutParentIndex) {
michael@0 518 *optionalOutParentIndex = -1;
michael@0 519 }
michael@0 520 return mTopNode;
michael@0 521 }
michael@0 522 else {
michael@0 523 int32_t index = 0;
michael@0 524 int32_t level = 0;
michael@0 525 return FindNodeFromIndex(mTopNode, wantedIndex, index, level,
michael@0 526 optionalOutParentIndex, optionalOutLevel);
michael@0 527 }
michael@0 528 }
michael@0 529
michael@0 530 // Internal recursive helper function
michael@0 531 nsNSSASN1Tree::myNode *
michael@0 532 nsNSSASN1Tree::FindNodeFromIndex(myNode *n, int32_t wantedIndex,
michael@0 533 int32_t &index_counter, int32_t &level_counter,
michael@0 534 int32_t *optionalOutParentIndex, int32_t *optionalOutLevel)
michael@0 535 {
michael@0 536 if (!n)
michael@0 537 return nullptr;
michael@0 538
michael@0 539 myNode *walk = n;
michael@0 540 int32_t parentIndex = index_counter-1;
michael@0 541
michael@0 542 while (walk) {
michael@0 543 if (index_counter == wantedIndex) {
michael@0 544 if (optionalOutLevel) {
michael@0 545 *optionalOutLevel = level_counter;
michael@0 546 }
michael@0 547 if (optionalOutParentIndex) {
michael@0 548 *optionalOutParentIndex = parentIndex;
michael@0 549 }
michael@0 550 return walk;
michael@0 551 }
michael@0 552
michael@0 553 if (walk->seq) {
michael@0 554 bool IsExpanded;
michael@0 555 walk->seq->GetIsExpanded(&IsExpanded);
michael@0 556 if (IsExpanded) {
michael@0 557 ++index_counter; // set to walk->child
michael@0 558
michael@0 559 ++level_counter;
michael@0 560 myNode *found = FindNodeFromIndex(walk->child, wantedIndex, index_counter, level_counter,
michael@0 561 optionalOutParentIndex, optionalOutLevel);
michael@0 562 --level_counter;
michael@0 563
michael@0 564 if (found)
michael@0 565 return found;
michael@0 566 }
michael@0 567 }
michael@0 568
michael@0 569 walk = walk->next;
michael@0 570 if (walk) {
michael@0 571 ++index_counter;
michael@0 572 }
michael@0 573 }
michael@0 574
michael@0 575 return nullptr;
michael@0 576 }
michael@0 577

mercurial