Opera 12.15 Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SearchUtils.h 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* -*- Mode: c++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
  2. **
  3. ** Copyright (C) 1995-2011 Opera Software ASA. All rights reserved.
  4. **
  5. ** This file is part of the Opera web browser.
  6. ** It may not be distributed under any circumstances.
  7. */
  8. #ifndef SEARCHUTILS_H
  9. #define SEARCHUTILS_H
  10. #ifndef CHECK_RESULT
  11. # if defined(__GNUC__)
  12. # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
  13. # define CHECK_RESULT(X) X __attribute__((warn_unused_result))
  14. # endif
  15. # endif
  16. #endif
  17. #ifndef CHECK_RESULT
  18. # define CHECK_RESULT(X) X
  19. #endif // CHECK_RESULT
  20. #ifndef RETURN_OOM_IF_NULL
  21. #define RETURN_OOM_IF_NULL( expr ) \
  22. do { \
  23. if (NULL == (expr)) \
  24. return OpStatus::ERR_NO_MEMORY; \
  25. } while(0)
  26. #endif
  27. #define INVALID_FILE_LENGTH ((OpFileLength)-1)
  28. /**
  29. * Class declaring private copy constructor and assignment operator.
  30. * Inherit from this class if you want to prevent accidental assignment to
  31. * a class variable, which may result in the destructor being called twice
  32. * on the same data. It should typically be used whenever there is a
  33. * destructor that does some non-trivial cleanup.
  34. */
  35. class NonCopyable
  36. {
  37. protected:
  38. NonCopyable() {}
  39. private:
  40. // Disable implicit copy constructor and assignment
  41. NonCopyable(const NonCopyable&);
  42. NonCopyable& operator=(const NonCopyable&);
  43. };
  44. /**
  45. * Class for detecting loops during iterations.
  46. * This particular implementation is especially useful if the operation for
  47. * advancing to the next element is costly, or if the iterator itself has a
  48. * large state, such as when traversing data on disk. Usage:
  49. *
  50. * <pre>
  51. * LoopDetector<Link*> loopDetector;
  52. * for (p = First(); p; p = p->Next()) {
  53. * //...
  54. * RETURN_IF_ERROR(loopDetector.CheckNext(p));
  55. * }
  56. * </pre>
  57. */
  58. template <class T, T nullValue=0> class LoopDetector
  59. {
  60. public:
  61. LoopDetector() : n(0) { prevId = nullValue; }
  62. void Reset() { n = 0; }
  63. /**
  64. * Check next element in a sequence to detect if there is a loop
  65. * @return OK, or ERR if the element has been seen before (loop detected)
  66. */
  67. CHECK_RESULT(OP_STATUS CheckNext(T id))
  68. {
  69. if (n > 0 && id == prevId)
  70. {
  71. OP_ASSERT(!"Loop detected, probably a corrupt file. Contact search_engine owner if reproducible");
  72. return OpStatus::ERR;
  73. }
  74. n++;
  75. if ((n & (n-1)) == 0) // Update prevId at n==1,2,4,8,16,32...
  76. prevId = id;
  77. return OpStatus::OK;
  78. }
  79. private:
  80. int n;
  81. T prevId;
  82. };
  83. #endif // SEARCHUTILS_H