summaryrefslogtreecommitdiffstats
path: root/netwerk/cache/nsCacheMetaData.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /netwerk/cache/nsCacheMetaData.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'netwerk/cache/nsCacheMetaData.cpp')
-rw-r--r--netwerk/cache/nsCacheMetaData.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/netwerk/cache/nsCacheMetaData.cpp b/netwerk/cache/nsCacheMetaData.cpp
new file mode 100644
index 000000000..0df867d83
--- /dev/null
+++ b/netwerk/cache/nsCacheMetaData.cpp
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsCacheMetaData.h"
+#include "nsICacheEntryDescriptor.h"
+
+const char *
+nsCacheMetaData::GetElement(const char * key)
+{
+ const char * data = mBuffer;
+ const char * limit = mBuffer + mMetaSize;
+
+ while (data < limit) {
+ // Point to the value part
+ const char * value = data + strlen(data) + 1;
+ MOZ_ASSERT(value < limit, "Cache Metadata corrupted");
+ if (strcmp(data, key) == 0)
+ return value;
+
+ // Skip value part
+ data = value + strlen(value) + 1;
+ }
+ MOZ_ASSERT(data == limit, "Metadata corrupted");
+ return nullptr;
+}
+
+
+nsresult
+nsCacheMetaData::SetElement(const char * key,
+ const char * value)
+{
+ const uint32_t keySize = strlen(key) + 1;
+ char * pos = (char *)GetElement(key);
+
+ if (!value) {
+ // No value means remove the key/value pair completely, if existing
+ if (pos) {
+ uint32_t oldValueSize = strlen(pos) + 1;
+ uint32_t offset = pos - mBuffer;
+ uint32_t remainder = mMetaSize - (offset + oldValueSize);
+
+ memmove(pos - keySize, pos + oldValueSize, remainder);
+ mMetaSize -= keySize + oldValueSize;
+ }
+ return NS_OK;
+ }
+
+ const uint32_t valueSize = strlen(value) + 1;
+ uint32_t newSize = mMetaSize + valueSize;
+ if (pos) {
+ const uint32_t oldValueSize = strlen(pos) + 1;
+ const uint32_t offset = pos - mBuffer;
+ const uint32_t remainder = mMetaSize - (offset + oldValueSize);
+
+ // Update the value in place
+ newSize -= oldValueSize;
+ nsresult rv = EnsureBuffer(newSize);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Move the remainder to the right place
+ pos = mBuffer + offset;
+ memmove(pos + valueSize, pos + oldValueSize, remainder);
+ } else {
+ // allocate new meta data element
+ newSize += keySize;
+ nsresult rv = EnsureBuffer(newSize);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Add after last element
+ pos = mBuffer + mMetaSize;
+ memcpy(pos, key, keySize);
+ pos += keySize;
+ }
+
+ // Update value
+ memcpy(pos, value, valueSize);
+ mMetaSize = newSize;
+
+ return NS_OK;
+}
+
+nsresult
+nsCacheMetaData::FlattenMetaData(char * buffer, uint32_t bufSize)
+{
+ if (mMetaSize > bufSize) {
+ NS_ERROR("buffer size too small for meta data.");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ memcpy(buffer, mBuffer, mMetaSize);
+ return NS_OK;
+}
+
+nsresult
+nsCacheMetaData::UnflattenMetaData(const char * data, uint32_t size)
+{
+ if (data && size) {
+ // Check if the metadata ends with a zero byte.
+ if (data[size-1] != '\0') {
+ NS_ERROR("Cache MetaData is not null terminated");
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ // Check that there are an even number of zero bytes
+ // to match the pattern { key \0 value \0 }
+ bool odd = false;
+ for (uint32_t i = 0; i < size; i++) {
+ if (data[i] == '\0')
+ odd = !odd;
+ }
+ if (odd) {
+ NS_ERROR("Cache MetaData is malformed");
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ nsresult rv = EnsureBuffer(size);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ memcpy(mBuffer, data, size);
+ mMetaSize = size;
+ }
+ return NS_OK;
+}
+
+nsresult
+nsCacheMetaData::VisitElements(nsICacheMetaDataVisitor * visitor)
+{
+ const char * data = mBuffer;
+ const char * limit = mBuffer + mMetaSize;
+
+ while (data < limit) {
+ const char * key = data;
+ // Skip key part
+ data += strlen(data) + 1;
+ MOZ_ASSERT(data < limit, "Metadata corrupted");
+ bool keepGoing;
+ nsresult rv = visitor->VisitMetaDataElement(key, data, &keepGoing);
+ if (NS_FAILED(rv) || !keepGoing)
+ return NS_OK;
+
+ // Skip value part
+ data += strlen(data) + 1;
+ }
+ MOZ_ASSERT(data == limit, "Metadata corrupted");
+ return NS_OK;
+}
+
+nsresult
+nsCacheMetaData::EnsureBuffer(uint32_t bufSize)
+{
+ if (mBufferSize < bufSize) {
+ char * buf = (char *)realloc(mBuffer, bufSize);
+ if (!buf) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mBuffer = buf;
+ mBufferSize = bufSize;
+ }
+ return NS_OK;
+}