michael@0: //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "ChunkSet.h" michael@0: michael@0: namespace mozilla { michael@0: namespace safebrowsing { michael@0: michael@0: nsresult michael@0: ChunkSet::Serialize(nsACString& aChunkStr) michael@0: { michael@0: aChunkStr.Truncate(); michael@0: michael@0: uint32_t i = 0; michael@0: while (i < mChunks.Length()) { michael@0: if (i != 0) { michael@0: aChunkStr.Append(','); michael@0: } michael@0: aChunkStr.AppendInt((int32_t)mChunks[i]); michael@0: michael@0: uint32_t first = i; michael@0: uint32_t last = first; michael@0: i++; michael@0: while (i < mChunks.Length() && (mChunks[i] == mChunks[i - 1] + 1 || mChunks[i] == mChunks[i - 1])) { michael@0: last = i++; michael@0: } michael@0: michael@0: if (last != first) { michael@0: aChunkStr.Append('-'); michael@0: aChunkStr.AppendInt((int32_t)mChunks[last]); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: ChunkSet::Set(uint32_t aChunk) michael@0: { michael@0: uint32_t idx = mChunks.BinaryIndexOf(aChunk); michael@0: if (idx == nsTArray::NoIndex) { michael@0: mChunks.InsertElementSorted(aChunk); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: ChunkSet::Unset(uint32_t aChunk) michael@0: { michael@0: mChunks.RemoveElementSorted(aChunk); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: bool michael@0: ChunkSet::Has(uint32_t aChunk) const michael@0: { michael@0: return mChunks.BinaryIndexOf(aChunk) != nsTArray::NoIndex; michael@0: } michael@0: michael@0: nsresult michael@0: ChunkSet::Merge(const ChunkSet& aOther) michael@0: { michael@0: const uint32_t *dupIter = aOther.mChunks.Elements(); michael@0: const uint32_t *end = aOther.mChunks.Elements() + aOther.mChunks.Length(); michael@0: michael@0: for (const uint32_t *iter = dupIter; iter != end; iter++) { michael@0: nsresult rv = Set(*iter); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult michael@0: ChunkSet::Remove(const ChunkSet& aOther) michael@0: { michael@0: uint32_t *addIter = mChunks.Elements(); michael@0: uint32_t *end = mChunks.Elements() + mChunks.Length(); michael@0: michael@0: for (uint32_t *iter = addIter; iter != end; iter++) { michael@0: if (!aOther.Has(*iter)) { michael@0: *addIter = *iter; michael@0: addIter++; michael@0: } michael@0: } michael@0: michael@0: mChunks.SetLength(addIter - mChunks.Elements()); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: void michael@0: ChunkSet::Clear() michael@0: { michael@0: mChunks.Clear(); michael@0: } michael@0: michael@0: } michael@0: }