Separate WireServer.cpp into multiple files.

This patch copies methods and classes from WireServer.cpp and
distributes them over multiple files. Headers and forward declarations
are added as necessary, but no functional changes are made.

Bug: dawn:88
Change-Id: I471b8c27804916257eff266a51d087ba1ddbfeb6
Reviewed-on: https://dawn-review.googlesource.com/c/4000
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_wire/server/ObjectStorage.h b/src/dawn_wire/server/ObjectStorage.h
new file mode 100644
index 0000000..3405a88
--- /dev/null
+++ b/src/dawn_wire/server/ObjectStorage.h
@@ -0,0 +1,182 @@
+// Copyright 2019 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef DAWNWIRE_SERVER_OBJECTSTORAGE_H_
+#define DAWNWIRE_SERVER_OBJECTSTORAGE_H_
+
+#include "dawn_wire/TypeTraits_autogen.h"
+#include "dawn_wire/WireCmd_autogen.h"
+
+#include <algorithm>
+#include <map>
+
+namespace dawn_wire { namespace server {
+
+    template <typename T>
+    struct ObjectDataBase {
+        // The backend-provided handle and serial to this object.
+        T handle;
+        uint32_t serial = 0;
+
+        // Used by the error-propagation mechanism to know if this object is an error.
+        // TODO(cwallez@chromium.org): this is doubling the memory usage of
+        // std::vector<ObjectDataBase> consider making it a special marker value in handle instead.
+        bool valid;
+        // Whether this object has been allocated, used by the KnownObjects queries
+        // TODO(cwallez@chromium.org): make this an internal bit vector in KnownObjects.
+        bool allocated;
+    };
+
+    // Stores what the backend knows about the type.
+    template <typename T, bool IsBuilder = IsBuilderType<T>::value>
+    struct ObjectData : public ObjectDataBase<T> {};
+
+    template <typename T>
+    struct ObjectData<T, true> : public ObjectDataBase<T> {
+        ObjectHandle builtObject = ObjectHandle{0, 0};
+    };
+
+    template <>
+    struct ObjectData<dawnBuffer, false> : public ObjectDataBase<dawnBuffer> {
+        void* mappedData = nullptr;
+        size_t mappedDataSize = 0;
+    };
+
+    // Keeps track of the mapping between client IDs and backend objects.
+    template <typename T>
+    class KnownObjects {
+      public:
+        using Data = ObjectData<T>;
+
+        KnownObjects() {
+            // Pre-allocate ID 0 to refer to the null handle.
+            Data nullObject;
+            nullObject.handle = nullptr;
+            nullObject.valid = true;
+            nullObject.allocated = true;
+            mKnown.push_back(nullObject);
+        }
+
+        // Get a backend objects for a given client ID.
+        // Returns nullptr if the ID hasn't previously been allocated.
+        const Data* Get(uint32_t id) const {
+            if (id >= mKnown.size()) {
+                return nullptr;
+            }
+
+            const Data* data = &mKnown[id];
+
+            if (!data->allocated) {
+                return nullptr;
+            }
+
+            return data;
+        }
+        Data* Get(uint32_t id) {
+            if (id >= mKnown.size()) {
+                return nullptr;
+            }
+
+            Data* data = &mKnown[id];
+
+            if (!data->allocated) {
+                return nullptr;
+            }
+
+            return data;
+        }
+
+        // Allocates the data for a given ID and returns it.
+        // Returns nullptr if the ID is already allocated, or too far ahead.
+        // Invalidates all the Data*
+        Data* Allocate(uint32_t id) {
+            if (id > mKnown.size()) {
+                return nullptr;
+            }
+
+            Data data;
+            data.allocated = true;
+            data.valid = false;
+            data.handle = nullptr;
+
+            if (id >= mKnown.size()) {
+                mKnown.push_back(data);
+                return &mKnown.back();
+            }
+
+            if (mKnown[id].allocated) {
+                return nullptr;
+            }
+
+            mKnown[id] = data;
+            return &mKnown[id];
+        }
+
+        // Marks an ID as deallocated
+        void Free(uint32_t id) {
+            ASSERT(id < mKnown.size());
+            mKnown[id].allocated = false;
+        }
+
+        std::vector<T> AcquireAllHandles() {
+            std::vector<T> objects;
+            for (Data& data : mKnown) {
+                if (data.allocated && data.handle != nullptr) {
+                    objects.push_back(data.handle);
+                    data.valid = false;
+                    data.allocated = false;
+                    data.handle = nullptr;
+                }
+            }
+
+            return objects;
+        }
+
+      private:
+        std::vector<Data> mKnown;
+    };
+
+    // ObjectIds are lost in deserialization. Store the ids of deserialized
+    // objects here so they can be used in command handlers. This is useful
+    // for creating ReturnWireCmds which contain client ids
+    template <typename T>
+    class ObjectIdLookupTable {
+      public:
+        void Store(T key, ObjectId id) {
+            mTable[key] = id;
+        }
+
+        // Return the cached ObjectId, or 0 (null handle)
+        ObjectId Get(T key) const {
+            const auto it = mTable.find(key);
+            if (it != mTable.end()) {
+                return it->second;
+            }
+            return 0;
+        }
+
+        void Remove(T key) {
+            auto it = mTable.find(key);
+            if (it != mTable.end()) {
+                mTable.erase(it);
+            }
+        }
+
+      private:
+        std::map<T, ObjectId> mTable;
+    };
+
+}}  // namespace dawn_wire::server
+
+#endif  // DAWNWIRE_SERVER_OBJECTSTORAGE_H_