michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: michael@0: #define ADLOG_ENTRY_BLOCK_SIZE 4096 michael@0: michael@0: class ADLog { michael@0: michael@0: public: michael@0: michael@0: // Use typedef in case somebody wants to process 64-bit output on a michael@0: // 32-bit machine someday. michael@0: typedef const char* Pointer; michael@0: michael@0: struct Entry { michael@0: Pointer address; michael@0: const char *type; michael@0: michael@0: const char *data; // The contents of the memory. michael@0: size_t datasize; michael@0: michael@0: const char *allocation_stack; michael@0: }; michael@0: michael@0: ADLog(); michael@0: ~ADLog(); michael@0: michael@0: /* michael@0: * Returns false on failure and true on success. michael@0: */ michael@0: bool Read(const char *aFilename); michael@0: michael@0: private: michael@0: // Link structure for a circularly linked list. michael@0: struct EntryBlock; michael@0: struct EntryBlockLink { michael@0: EntryBlock *mPrev; michael@0: EntryBlock *mNext; michael@0: }; michael@0: michael@0: struct EntryBlock : public EntryBlockLink { michael@0: Entry entries[ADLOG_ENTRY_BLOCK_SIZE]; michael@0: }; michael@0: michael@0: size_t mEntryCount; michael@0: EntryBlockLink mEntries; michael@0: michael@0: public: michael@0: michael@0: class const_iterator { michael@0: private: michael@0: // Only |ADLog| member functions can construct iterators. michael@0: friend class ADLog; michael@0: const_iterator(EntryBlock *aBlock, size_t aOffset); michael@0: michael@0: public: michael@0: const Entry* operator*() { return mCur; } michael@0: const Entry* operator->() { return mCur; } michael@0: michael@0: const_iterator& operator++(); michael@0: const_iterator& operator--(); michael@0: michael@0: bool operator==(const const_iterator& aOther) const { michael@0: return mCur == aOther.mCur; michael@0: } michael@0: michael@0: bool operator!=(const const_iterator& aOther) const { michael@0: return mCur != aOther.mCur; michael@0: } michael@0: michael@0: private: michael@0: void SetBlock(EntryBlock *aBlock) { michael@0: mBlock = aBlock; michael@0: mBlockStart = aBlock->entries; michael@0: mBlockEnd = aBlock->entries + ADLOG_ENTRY_BLOCK_SIZE; michael@0: } michael@0: michael@0: EntryBlock *mBlock; michael@0: Entry *mCur, *mBlockStart, *mBlockEnd; michael@0: michael@0: // Not to be implemented. michael@0: const_iterator operator++(int); michael@0: const_iterator operator--(int); michael@0: }; michael@0: michael@0: const_iterator begin() { michael@0: return const_iterator(mEntries.mNext, 0); michael@0: } michael@0: const_iterator end() { michael@0: return const_iterator(mEntries.mPrev, michael@0: mEntryCount % ADLOG_ENTRY_BLOCK_SIZE); michael@0: } michael@0: michael@0: size_t count() { return mEntryCount; } michael@0: };