Bug 1438688, part 2 - Load XPT information from a static variable instead of a file. r=njn
authorAndrew McCreight <continuation@gmail.com>
Wed, 28 Feb 2018 12:51:39 -0800
changeset 411419 e3b0f068f61e4b352072c1246609ad5c50930587
parent 411418 4f8ea03dbe4d83513bde0e4422da2a47f35bbd67
child 411420 1f3b60346b7750df21c3a93a2eef0d801d77e421
push id33755
push useraiakab@mozilla.com
push dateTue, 03 Apr 2018 09:29:11 +0000
treeherdermozilla-central@2ee160335e15 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs1438688
milestone61.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1438688, part 2 - Load XPT information from a static variable instead of a file. r=njn This patch removes C++ code related to reading in XPT information from files. (Code related to packaging XPT files will be removed in the next patch.) This includes code in the manifest parser, in addition to the actual code for parsing files. XPT information is now loaded directly from a single static data structure, XPTHeader::kHeader, which will be automatically generated at compile time from .idl files (via .xpt files). Note that the script to do that is not added until part 6 of this patch series, so linking will fail on parts 2 through 5. I inlined XPTInterfaceInfoManager::RegisterXPTHeader into the ctor, because that is the only caller. It feels like the lock there should not be needed any more, but I left it alone for now. The forward declaration of XPTArena in xptiprivate.h is needed because it was being bootlegged via xpt_xdr.h. Some of the data structures in reflect/xptinfo/ (which wrap the xpt_struct.h data structures) are still allocated using XPTArena. Hopefully we can get rid of that in followup work. I also deleted a lot of comments in xpt_struct.h that talk about the on-disk format. I also deleted checking of the major version number, because that should not matter when the XPT information is baked into the executable. MozReview-Commit-ID: 6NJdaCWRBhU
xpcom/components/ManifestParser.cpp
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h
xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
xpcom/reflect/xptinfo/xptiprivate.h
xpcom/typelib/xpt/moz.build
xpcom/typelib/xpt/xpt_struct.cpp
xpcom/typelib/xpt/xpt_struct.h
xpcom/typelib/xpt/xpt_xdr.cpp
xpcom/typelib/xpt/xpt_xdr.h
--- a/xpcom/components/ManifestParser.cpp
+++ b/xpcom/components/ManifestParser.cpp
@@ -75,20 +75,16 @@ static const ManifestDirective kParsingT
     "manifest",         1, false, false, true, true, false,
     &nsComponentManagerImpl::ManifestManifest, nullptr,
   },
   {
     "binary-component", 1, true, true, false, false, false,
     &nsComponentManagerImpl::ManifestBinaryComponent, nullptr,
   },
   {
-    "interfaces",       1, false, true, false, false, false,
-    &nsComponentManagerImpl::ManifestXPT, nullptr,
-  },
-  {
     "component",        2, false, true, false, false, false,
     &nsComponentManagerImpl::ManifestComponent, nullptr,
   },
   {
     "contract",         2, false, true, false, false, false,
     &nsComponentManagerImpl::ManifestContract, nullptr,
   },
   {
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -12,32 +12,29 @@
 
 #include "nsCategoryManager.h"
 #include "nsCOMPtr.h"
 #include "nsComponentManager.h"
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsCategoryManager.h"
 #include "nsCategoryManagerUtils.h"
-#include "xptiprivate.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/XPTInterfaceInfoManager.h"
 #include "nsIConsoleService.h"
 #include "nsIObserverService.h"
 #include "nsISimpleEnumerator.h"
 #include "nsIStringEnumerator.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMPrivate.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIClassInfo.h"
 #include "nsLocalFile.h"
 #include "nsReadableUtils.h"
 #include "nsString.h"
 #include "prcmon.h"
-#include "xptinfo.h" // this after nsISupports, to pick up IID so that xpt stuff doesn't try to define it itself...
 #include "nsThreadUtils.h"
 #include "prthread.h"
 #include "private/pprthred.h"
 #include "nsTArray.h"
 #include "prio.h"
 #include "ManifestParser.h"
 #include "nsNetUtil.h"
 #include "mozilla/Services.h"
@@ -570,47 +567,16 @@ void
 nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& aCx,
                                                 int aLineNo,
                                                 char* const* aArgv)
 {
   LogMessageWithContext(aCx.mFile, aLineNo,
                         "Binary XPCOM components are no longer supported.");
 }
 
-static void
-DoRegisterXPT(FileLocation& aFile)
-{
-  uint32_t len;
-  FileLocation::Data data;
-  UniquePtr<char[]> buf;
-  nsresult rv = aFile.GetData(data);
-  if (NS_SUCCEEDED(rv)) {
-    rv = data.GetSize(&len);
-  }
-  if (NS_SUCCEEDED(rv)) {
-    buf = MakeUnique<char[]>(len);
-    rv = data.Copy(buf.get(), len);
-  }
-  if (NS_SUCCEEDED(rv)) {
-    XPTInterfaceInfoManager::GetSingleton()->RegisterBuffer(buf.get(), len);
-  } else {
-    nsCString uri;
-    aFile.GetURIString(uri);
-    LogMessage("Could not read '%s'.", uri.get());
-  }
-}
-
-void
-nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& aCx,
-                                    int aLineNo, char* const* aArgv)
-{
-  FileLocation f(aCx.mFile, aArgv[0]);
-  DoRegisterXPT(f);
-}
-
 void
 nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& aCx,
                                           int aLineNo, char* const* aArgv)
 {
   mLock.AssertNotCurrentThreadOwns();
 
   char* id = aArgv[0];
   char* file = aArgv[1];
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -285,18 +285,16 @@ public:
     mozilla::FileLocation mFile;
     bool mChromeOnly;
   };
 
   void ManifestManifest(ManifestProcessingContext& aCx, int aLineNo,
                         char* const* aArgv);
   void ManifestBinaryComponent(ManifestProcessingContext& aCx, int aLineNo,
                                char* const* aArgv);
-  void ManifestXPT(ManifestProcessingContext& aCx, int aLineNo,
-                   char* const* aArgv);
   void ManifestComponent(ManifestProcessingContext& aCx, int aLineNo,
                          char* const* aArgv);
   void ManifestContract(ManifestProcessingContext& aCx, int aLineNo,
                         char* const* aArgv);
   void ManifestCategory(ManifestProcessingContext& aCx, int aLineNo,
                         char* const* aArgv);
 
   void RereadChromeManifests(bool aChromeOnly = true);
--- a/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h
+++ b/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h
@@ -12,17 +12,16 @@
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "nsDataHashtable.h"
 
 template<typename T> class nsCOMArray;
 class nsIMemoryReporter;
-struct XPTHeader;
 struct XPTInterfaceDirectoryEntry;
 class xptiInterfaceEntry;
 class xptiInterfaceInfo;
 class xptiTypelibGuts;
 
 namespace mozilla {
 
 class XPTInterfaceInfoManager final
@@ -35,35 +34,31 @@ class XPTInterfaceInfoManager final
 
 public:
     // GetSingleton() is infallible
     static XPTInterfaceInfoManager* GetSingleton();
     static void FreeInterfaceInfoManager();
 
     void GetScriptableInterfaces(nsCOMArray<nsIInterfaceInfo>& aInterfaces);
 
-    void RegisterBuffer(char *buf, uint32_t length);
-
     static Mutex& GetResolveLock()
     {
         return GetSingleton()->mResolveLock;
     }
 
     xptiInterfaceEntry* GetInterfaceEntryForIID(const nsIID *iid);
 
     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
 
 private:
     XPTInterfaceInfoManager();
     ~XPTInterfaceInfoManager();
 
     void InitMemoryReporter();
 
-    void RegisterXPTHeader(const XPTHeader* aHeader);
-
     // idx is the index of this interface in the XPTHeader
     void VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface,
                                 uint16_t idx,
                                 xptiTypelibGuts* typelib);
 
 private:
 
     class xptiWorkingSet
--- a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
+++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp
@@ -76,16 +76,22 @@ XPTInterfaceInfoManager::FreeInterfaceIn
 {
     gInterfaceInfoManager = nullptr;
 }
 
 XPTInterfaceInfoManager::XPTInterfaceInfoManager()
     :   mWorkingSet(),
         mResolveLock("XPTInterfaceInfoManager.mResolveLock")
 {
+    xptiTypelibGuts* typelib = xptiTypelibGuts::Create(&XPTHeader::kHeader);
+
+    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
+    for (uint16_t k = 0; k < XPTHeader::kHeader.mNumInterfaces; k++) {
+        VerifyAndAddEntryIfNew(XPTHeader::kHeader.mInterfaceDirectory + k, k, typelib);
+    }
 }
 
 XPTInterfaceInfoManager::~XPTInterfaceInfoManager()
 {
     // We only do this on shutdown of the service.
     mWorkingSet.InvalidateInterfaceInfos();
 
     UnregisterWeakMemoryReporter(this);
@@ -93,48 +99,16 @@ XPTInterfaceInfoManager::~XPTInterfaceIn
 
 void
 XPTInterfaceInfoManager::InitMemoryReporter()
 {
     RegisterWeakMemoryReporter(this);
 }
 
 void
-XPTInterfaceInfoManager::RegisterBuffer(char *buf, uint32_t length)
-{
-    XPTState state;
-    XPT_InitXDRState(&state, buf, length);
-
-    XPTCursor curs;
-    NotNull<XPTCursor*> cursor = WrapNotNull(&curs);
-    if (!XPT_MakeCursor(&state, XPT_HEADER, 0, cursor)) {
-        return;
-    }
-
-    XPTHeader *header = nullptr;
-    if (XPT_DoHeader(gXPTIStructArena, cursor, &header)) {
-        RegisterXPTHeader(header);
-    }
-}
-
-void
-XPTInterfaceInfoManager::RegisterXPTHeader(const XPTHeader* aHeader)
-{
-    if (aHeader->mMajorVersion >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
-        MOZ_ASSERT(!aHeader->mNumInterfaces, "bad libxpt");
-    }
-
-    xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader);
-
-    ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor);
-    for(uint16_t k = 0; k < aHeader->mNumInterfaces; k++)
-        VerifyAndAddEntryIfNew(aHeader->mInterfaceDirectory + k, k, typelib);
-}
-
-void
 XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface,
                                                 uint16_t idx,
                                                 xptiTypelibGuts* typelib)
 {
     if (!iface->InterfaceDescriptor())
         return;
 
     // The number of maximum methods is not arbitrary. It is the same value as
--- a/xpcom/reflect/xptinfo/xptiprivate.h
+++ b/xpcom/reflect/xptinfo/xptiprivate.h
@@ -10,17 +10,16 @@
 
 #include "nscore.h"
 #include <new>
 #include "nsISupports.h"
 
 // this after nsISupports, to pick up IID
 // so that xpt stuff doesn't try to define it itself...
 #include "xpt_struct.h"
-#include "xpt_xdr.h"
 
 #include "nsIInterfaceInfo.h"
 #include "nsIInterfaceInfoManager.h"
 #include "xptinfo.h"
 #include "ShimInterfaceInfo.h"
 
 #include "nsIServiceManager.h"
 #include "nsIFile.h"
@@ -57,16 +56,17 @@
 #include <stdarg.h>
 
 /***************************************************************************/
 
 class xptiInterfaceInfo;
 class xptiInterfaceEntry;
 class xptiTypelibGuts;
 
+struct XPTArena;
 extern XPTArena* gXPTIStructArena;
 
 /***************************************************************************/
 
 /***************************************************************************/
 
 // No virtuals.
 // These are always constructed in the struct arena using placement new.
--- a/xpcom/typelib/xpt/moz.build
+++ b/xpcom/typelib/xpt/moz.build
@@ -5,24 +5,21 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 Library('xpt')
 
 DIRS += ['tools']
 
 UNIFIED_SOURCES += [
     'xpt_arena.cpp',
-    'xpt_struct.cpp',
-    'xpt_xdr.cpp',
 ]
 
 EXPORTS += [
     'xpt_arena.h',
     'xpt_struct.h',
-    'xpt_xdr.h',
 ]
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '!/xpcom/base',
     '/xpcom/base',
 ]
deleted file mode 100644
--- a/xpcom/typelib/xpt/xpt_struct.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 tw=80: */
-/* 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/. */
-
-/* Implementation of XDR routines for typelib structures. */
-
-#include "xpt_xdr.h"
-#include "xpt_struct.h"
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-
-using mozilla::WrapNotNull;
-
-#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032"
-#define XPT_MAGIC_STRING "XPCOM\\nTypeLib\\r\\n\\032"
-
-/*
- * Annotation records are variable-size records used to store secondary
- * information about the typelib, e.g. such as the name of the tool that
- * generated the typelib file, the date it was generated, etc.  The
- * information is stored with very loose format requirements so as to
- * allow virtually any private data to be stored in the typelib.
- *
- * There are two types of Annotations:
- *
- * EmptyAnnotation
- * PrivateAnnotation
- *
- * The tag field of the prefix discriminates among the variant record
- * types for Annotation's.  If the tag is 0, this record is an
- * EmptyAnnotation. EmptyAnnotation's are ignored - they're only used to
- * indicate an array of Annotation's that's completely empty.  If the tag
- * is 1, the record is a PrivateAnnotation.
- *
- * We don't actually store annotations; we just skip over them if they are
- * present.
- */
-
-#define XPT_ANN_LAST    0x80
-#define XPT_ANN_PRIVATE 0x40
-
-#define XPT_ANN_IS_LAST(flags) (flags & XPT_ANN_LAST)
-#define XPT_ANN_IS_PRIVATE(flags)(flags & XPT_ANN_PRIVATE)
-
-
-/***************************************************************************/
-/* Forward declarations. */
-
-static bool
-DoInterfaceDirectoryEntry(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                          XPTInterfaceDirectoryEntry *ide);
-
-static bool
-DoConstDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                  XPTConstDescriptor *cd, XPTInterfaceDescriptor *id);
-
-static bool
-DoMethodDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                   XPTMethodDescriptor *md, XPTInterfaceDescriptor *id);
-
-static bool
-SkipAnnotation(NotNull<XPTCursor*> cursor, bool *isLast);
-
-static bool
-DoInterfaceDescriptor(XPTArena *arena, NotNull<XPTCursor*> outer,
-                      const XPTInterfaceDescriptor **idp);
-
-static bool
-DoTypeDescriptorPrefix(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                       XPTTypeDescriptorPrefix *tdp);
-
-static bool
-DoTypeDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                 XPTTypeDescriptor *td, XPTInterfaceDescriptor *id);
-
-static bool
-DoParamDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                  XPTParamDescriptor *pd, XPTInterfaceDescriptor *id);
-
-/***************************************************************************/
-
-bool
-XPT_DoHeader(XPTArena *arena, NotNull<XPTCursor*> cursor, XPTHeader **headerp)
-{
-    unsigned int i;
-    uint32_t file_length = 0;
-    uint32_t ide_offset;
-
-    XPTHeader* header = XPT_NEWZAP(arena, XPTHeader);
-    if (!header)
-        return false;
-    *headerp = header;
-
-    uint8_t magic[16];
-    for (i = 0; i < sizeof(magic); i++) {
-        if (!XPT_Do8(cursor, &magic[i]))
-            return false;
-    }
-
-    if (strncmp((const char*)magic, XPT_MAGIC, 16) != 0) {
-        /* Require that the header contain the proper magic */
-        fprintf(stderr,
-                "libxpt: bad magic header in input file; "
-                "found '%s', expected '%s'\n",
-                magic, XPT_MAGIC_STRING);
-        return false;
-    }
-
-    uint8_t minor_version;
-    if (!XPT_Do8(cursor, &header->mMajorVersion) ||
-        !XPT_Do8(cursor, &minor_version)) {
-        return false;
-    }
-
-    if (header->mMajorVersion >= XPT_MAJOR_INCOMPATIBLE_VERSION) {
-        /* This file is newer than we are and set to an incompatible version
-         * number. We must set the header state thusly and return.
-         */
-        header->mNumInterfaces = 0;
-        return true;
-    }
-
-    if (!XPT_Do16(cursor, &header->mNumInterfaces) ||
-        !XPT_Do32(cursor, &file_length) ||
-        !XPT_Do32(cursor, &ide_offset)) {
-        return false;
-    }
-
-    /*
-     * Make sure the file length reported in the header is the same size as
-     * as our buffer unless it is zero (not set)
-     */
-    if (file_length != 0 &&
-        cursor->state->pool_allocated < file_length) {
-        fputs("libxpt: File length in header does not match actual length. File may be corrupt\n",
-            stderr);
-        return false;
-    }
-
-    uint32_t data_pool;
-    if (!XPT_Do32(cursor, &data_pool))
-        return false;
-
-    XPT_SetDataOffset(cursor->state, data_pool);
-
-    XPTInterfaceDirectoryEntry* interface_directory = nullptr;
-
-    if (header->mNumInterfaces) {
-        size_t n = header->mNumInterfaces * sizeof(XPTInterfaceDirectoryEntry);
-        interface_directory =
-            static_cast<XPTInterfaceDirectoryEntry*>(XPT_CALLOC8(arena, n));
-        if (!interface_directory)
-            return false;
-    }
-
-    /*
-     * Iterate through the annotations rather than recurring, to avoid blowing
-     * the stack on large xpt files. We don't actually store annotations, we
-     * just skip over them.
-     */
-    bool isLast;
-    do {
-        if (!SkipAnnotation(cursor, &isLast))
-            return false;
-    } while (!isLast);
-
-    /* shouldn't be necessary now, but maybe later */
-    XPT_SeekTo(cursor, ide_offset);
-
-    for (i = 0; i < header->mNumInterfaces; i++) {
-        if (!DoInterfaceDirectoryEntry(arena, cursor,
-                                       &interface_directory[i]))
-            return false;
-    }
-
-    header->mInterfaceDirectory = interface_directory;
-
-    return true;
-}
-
-/* InterfaceDirectoryEntry records go in the header */
-bool
-DoInterfaceDirectoryEntry(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                          XPTInterfaceDirectoryEntry *ide)
-{
-    const char* dummy_name_space;
-
-    /* write the IID in our cursor space */
-    if (!XPT_DoIID(cursor, &(ide->mIID)) ||
-
-        /* write the name string in the data pool, and the offset in our
-           cursor space */
-        !XPT_DoCString(arena, cursor, &(ide->mName)) ||
-
-        /* don't write the name_space string in the data pool, because we don't
-         * need it. Do write the offset in our cursor space */
-        !XPT_DoCString(arena, cursor, &dummy_name_space, /* ignore = */ true) ||
-
-        /* do InterfaceDescriptors */
-        !DoInterfaceDescriptor(arena, cursor, &ide->mInterfaceDescriptor)) {
-        return false;
-    }
-
-    return true;
-}
-
-static bool
-InterfaceDescriptorAddType(XPTArena *arena,
-                           XPTInterfaceDescriptor *id,
-                           XPTTypeDescriptor *td)
-{
-    const XPTTypeDescriptor *old = id->mAdditionalTypes;
-    XPTTypeDescriptor *new_;
-    size_t old_size = id->mNumAdditionalTypes * sizeof(XPTTypeDescriptor);
-    size_t new_size = old_size + sizeof(XPTTypeDescriptor);
-
-    /* XXX should grow in chunks to minimize alloc overhead */
-    new_ = static_cast<XPTTypeDescriptor*>(XPT_CALLOC8(arena, new_size));
-    if (!new_)
-        return false;
-    if (old) {
-        memcpy(new_, old, old_size);
-    }
-
-    new_[id->mNumAdditionalTypes] = *td;
-    id->mAdditionalTypes = new_;
-
-    if (id->mNumAdditionalTypes == UINT8_MAX)
-        return false;
-
-    id->mNumAdditionalTypes += 1;
-    return true;
-}
-
-bool
-DoInterfaceDescriptor(XPTArena *arena, NotNull<XPTCursor*> outer,
-                      const XPTInterfaceDescriptor **idp)
-{
-    XPTInterfaceDescriptor *id;
-    XPTCursor curs;
-    NotNull<XPTCursor*> cursor = WrapNotNull(&curs);
-    uint32_t i, id_sz = 0;
-
-    id = XPT_NEWZAP(arena, XPTInterfaceDescriptor);
-    if (!id)
-        return false;
-    *idp = id;
-
-    if (!XPT_MakeCursor(outer->state, XPT_DATA, id_sz, cursor))
-        return false;
-
-    if (!XPT_Do32(outer, &cursor->offset))
-        return false;
-    if (!cursor->offset) {
-        *idp = NULL;
-        return true;
-    }
-    if(!XPT_Do16(cursor, &id->mParentInterface) ||
-       !XPT_Do16(cursor, &id->mNumMethods)) {
-        return false;
-    }
-
-    XPTMethodDescriptor* method_descriptors = nullptr;
-
-    if (id->mNumMethods) {
-        size_t n = id->mNumMethods * sizeof(XPTMethodDescriptor);
-        method_descriptors =
-            static_cast<XPTMethodDescriptor*>(XPT_CALLOC8(arena, n));
-        if (!method_descriptors)
-            return false;
-    }
-
-    for (i = 0; i < id->mNumMethods; i++) {
-        if (!DoMethodDescriptor(arena, cursor, &method_descriptors[i], id))
-            return false;
-    }
-
-    id->mMethodDescriptors = method_descriptors;
-
-    if (!XPT_Do16(cursor, &id->mNumConstants)) {
-        return false;
-    }
-
-    XPTConstDescriptor* const_descriptors = nullptr;
-
-    if (id->mNumConstants) {
-        size_t n = id->mNumConstants * sizeof(XPTConstDescriptor);
-        const_descriptors =
-            static_cast<XPTConstDescriptor*>(XPT_CALLOC8(arena, n));
-        if (!const_descriptors)
-            return false;
-    }
-
-    for (i = 0; i < id->mNumConstants; i++) {
-        if (!DoConstDescriptor(arena, cursor, &const_descriptors[i], id)) {
-            return false;
-        }
-    }
-
-    id->mConstDescriptors = const_descriptors;
-
-    if (!XPT_Do8(cursor, &id->mFlags)) {
-        return false;
-    }
-
-    return true;
-}
-
-bool
-DoConstDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                  XPTConstDescriptor *cd, XPTInterfaceDescriptor *id)
-{
-    bool ok = false;
-
-    if (!XPT_DoCString(arena, cursor, &cd->mName) ||
-        !DoTypeDescriptor(arena, cursor, &cd->mType, id)) {
-
-        return false;
-    }
-
-    switch (cd->mType.Tag()) {
-      case TD_INT16:
-        ok = XPT_Do16(cursor, (uint16_t*) &cd->mValue.i16);
-        break;
-      case TD_INT32:
-        ok = XPT_Do32(cursor, (uint32_t*) &cd->mValue.i32);
-        break;
-      case TD_UINT16:
-        ok = XPT_Do16(cursor, &cd->mValue.ui16);
-        break;
-      case TD_UINT32:
-        ok = XPT_Do32(cursor, &cd->mValue.ui32);
-        break;
-      default:
-        MOZ_ASSERT(false, "illegal type");
-        break;
-    }
-
-    return ok;
-}
-
-bool
-DoMethodDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                   XPTMethodDescriptor *md, XPTInterfaceDescriptor *id)
-{
-    int i;
-
-    if (!XPT_Do8(cursor, &md->mFlags) ||
-        !XPT_DoCString(arena, cursor, &md->mName) ||
-        !XPT_Do8(cursor, &md->mNumArgs))
-        return false;
-
-    XPTParamDescriptor* params = nullptr;
-
-    if (md->mNumArgs) {
-        size_t n = md->mNumArgs * sizeof(XPTParamDescriptor);
-        params = static_cast<XPTParamDescriptor*>(XPT_CALLOC8(arena, n));
-        if (!params)
-            return false;
-    }
-
-    for(i = 0; i < md->mNumArgs; i++) {
-        if (!DoParamDescriptor(arena, cursor, &params[i], id))
-            return false;
-    }
-
-    md->mParams = params;
-
-    // |result| appears in the on-disk format but it isn't used,
-    // because a method is either notxpcom, in which case it can't be
-    // called from script so the XPT information is irrelevant, or the
-    // result type is nsresult.
-    XPTParamDescriptor result;
-    if (!DoParamDescriptor(arena, cursor, &result, id))
-        return false;
-
-    return true;
-}
-
-bool
-DoParamDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                  XPTParamDescriptor *pd, XPTInterfaceDescriptor *id)
-{
-    if (!XPT_Do8(cursor, &pd->mFlags) ||
-        !DoTypeDescriptor(arena, cursor, &pd->mType, id))
-        return false;
-
-    return true;
-}
-
-bool
-DoTypeDescriptorPrefix(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                       XPTTypeDescriptorPrefix *tdp)
-{
-    return XPT_Do8(cursor, &tdp->mFlags);
-}
-
-bool
-DoTypeDescriptor(XPTArena *arena, NotNull<XPTCursor*> cursor,
-                 XPTTypeDescriptor *td, XPTInterfaceDescriptor *id)
-{
-    if (!DoTypeDescriptorPrefix(arena, cursor, &td->mPrefix)) {
-        return false;
-    }
-
-    switch (td->Tag()) {
-      case TD_INTERFACE_TYPE:
-        uint16_t iface;
-        if (!XPT_Do16(cursor, &iface))
-            return false;
-        td->mData1 = (iface >> 8) & 0xff;
-        td->mData2 = iface & 0xff;
-        break;
-      case TD_INTERFACE_IS_TYPE:
-        if (!XPT_Do8(cursor, &td->mData1))
-            return false;
-        break;
-      case TD_ARRAY: {
-        // argnum2 appears in the on-disk format but it isn't used.
-        uint8_t argnum2 = 0;
-        if (!XPT_Do8(cursor, &td->mData1) ||
-            !XPT_Do8(cursor, &argnum2))
-            return false;
-
-        XPTTypeDescriptor elementTypeDescriptor;
-        if (!DoTypeDescriptor(arena, cursor, &elementTypeDescriptor, id))
-            return false;
-        if (!InterfaceDescriptorAddType(arena, id, &elementTypeDescriptor))
-            return false;
-        td->mData2 = id->mNumAdditionalTypes - 1;
-
-        break;
-      }
-      case TD_PSTRING_SIZE_IS:
-      case TD_PWSTRING_SIZE_IS: {
-        // argnum2 appears in the on-disk format but it isn't used.
-        uint8_t argnum2 = 0;
-        if (!XPT_Do8(cursor, &td->mData1) ||
-            !XPT_Do8(cursor, &argnum2))
-            return false;
-        break;
-      }
-      default:
-        /* nothing special */
-        break;
-    }
-    return true;
-}
-
-bool
-SkipAnnotation(NotNull<XPTCursor*> cursor, bool *isLast)
-{
-    uint8_t flags;
-    if (!XPT_Do8(cursor, &flags))
-        return false;
-
-    *isLast = XPT_ANN_IS_LAST(flags);
-
-    if (XPT_ANN_IS_PRIVATE(flags)) {
-        if (!XPT_SkipStringInline(cursor) ||
-            !XPT_SkipStringInline(cursor))
-            return false;
-    }
-
-    return true;
-}
-
--- a/xpcom/typelib/xpt/xpt_struct.h
+++ b/xpcom/typelib/xpt/xpt_struct.h
@@ -1,92 +1,52 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 https://mozilla.org/MPL/2.0/. */
 
 /*
- * Structures matching the in-memory representation of typelib structures.
+ * Structures for representing typelib structures in memory.
  * http://www.mozilla.org/scriptable/typelib_file.html
  */
 
 #ifndef xpt_struct_h
 #define xpt_struct_h
 
 #include "nsID.h"
 #include <stdint.h>
 #include "mozilla/Assertions.h"
 
-/*
- * Originally, I was going to have structures that exactly matched the on-disk
- * representation, but that proved difficult: different compilers can pack
- * their structs differently, and that makes overlaying them atop a
- * read-from-disk byte buffer troublesome.  So now I just have some structures
- * that are used in memory, and we're going to write a nice XDR library to
- * write them to disk and stuff.  It is pure joy. -- shaver
- */
-
-/* Structures for the typelib components */
-
-struct XPTHeader;
 struct XPTInterfaceDirectoryEntry;
 struct XPTInterfaceDescriptor;
 struct XPTConstDescriptor;
 struct XPTMethodDescriptor;
 struct XPTParamDescriptor;
 struct XPTTypeDescriptor;
 struct XPTTypeDescriptorPrefix;
 
-/*
- * Every XPCOM typelib file begins with a header.
- */
 struct XPTHeader {
-  // Some of these fields exists in the on-disk format but don't need to be
-  // stored in memory (other than very briefly, which can be done with local
-  // variables).
+  uint16_t mNumInterfaces;
+  const XPTInterfaceDirectoryEntry* mInterfaceDirectory;
 
-  //uint8_t mMagic[16];
-  uint8_t mMajorVersion;
-  //uint8_t mMinorVersion;
-  uint16_t mNumInterfaces;
-  //uint32_t mFileLength;
-  const XPTInterfaceDirectoryEntry* mInterfaceDirectory;
-  //uint32_t mDataPool;
+  static const XPTHeader kHeader;
 };
 
 /*
- * Any file with a major version number of XPT_MAJOR_INCOMPATIBLE_VERSION
- * or higher is to be considered incompatible by this version of xpt and
- * we will refuse to read it. We will return a header with magic, major and
- * minor versions set from the file. num_interfaces will be set to zero to
- * confirm our inability to read the file; i.e. even if some client of this
- * library gets out of sync with us regarding the agreed upon value for
- * XPT_MAJOR_INCOMPATIBLE_VERSION, anytime num_interfaces is zero we *know*
- * that this library refused to read the file due to version incompatibility.
- */
-#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02
-
-/*
- * A contiguous array of fixed-size InterfaceDirectoryEntry records begins at
- * the byte offset identified by the mInterfaceDirectory field in the file
- * header.  The array is used to quickly locate an interface description
- * using its IID.  No interface should appear more than once in the array.
+ * An array of directory entries is used to quickly locate an interface
+ * description using its IID. No interface should appear more than once in the
+ * array.
  */
 struct XPTInterfaceDirectoryEntry {
   inline const XPTInterfaceDescriptor* InterfaceDescriptor() const;
   inline const char* Name() const;
 
   nsID mIID;
   const char* mName;
-
-  // This field exists in the on-disk format. But it isn't used so we don't
-  // allocate space for it in memory.
-  //const char* mNameSpace;
-
   const XPTInterfaceDescriptor* mInterfaceDescriptor;
 };
 
 /*
  * An InterfaceDescriptor describes a single XPCOM interface, including all of
  * its methods.
  */
 struct XPTInterfaceDescriptor {
@@ -100,61 +60,41 @@ struct XPTInterfaceDescriptor {
   bool IsBuiltinClass() const { return !!(mFlags & kBuiltinClassMask); }
   bool IsMainProcessScriptableOnly() const { return !!(mFlags & kMainProcessScriptableOnlyMask); }
 
   inline const XPTMethodDescriptor& Method(size_t aIndex) const;
   inline const XPTConstDescriptor& Const(size_t aIndex) const;
 
   /*
    * This field ordering minimizes the size of this struct.
-   * The fields are serialized on disk in a different order.
-   * See DoInterfaceDescriptor().
    */
   const XPTMethodDescriptor* mMethodDescriptors;
   const XPTConstDescriptor* mConstDescriptors;
   const XPTTypeDescriptor* mAdditionalTypes;
   uint16_t mParentInterface;
   uint16_t mNumMethods;
   uint16_t mNumConstants;
   uint8_t mFlags;
-
-  /*
-   * mAdditionalTypes are used for arrays where we may need multiple
-   * XPTTypeDescriptors for a single XPTMethodDescriptor. Since we still
-   * want to have a simple array of XPTMethodDescriptor (each with a single
-   * embedded XPTTypeDescriptor), a XPTTypeDescriptor can have a reference
-   * to an 'additional_type'. That reference is an index in this
-   * "mAdditionalTypes" array. So a given XPTMethodDescriptor might have
-   * a whole chain of these XPTTypeDescriptors to represent, say, a multi
-   * dimensional array.
-   *
-   * Note that in the typelib file these additional types are stored 'inline'
-   * in the MethodDescriptor. But, in the typelib MethodDescriptors can be
-   * of varying sizes, where in XPT's in memory mapping of the data we want
-   * them to be of fixed size. This mAdditionalTypes scheme is here to allow
-   * for that.
-   */
   uint8_t mNumAdditionalTypes;
 };
 
 /*
- * A TypeDescriptor is a variable-size record used to identify the type of a
- * method argument or return value.
+ * A TypeDescriptor is a union used to identify the type of a method
+ * argument or return value.
  *
  * There are three types of TypeDescriptors:
  *
  * SimpleTypeDescriptor
  * InterfaceTypeDescriptor
  * InterfaceIsTypeDescriptor
  *
  * The tag field in the prefix indicates which of the variant TypeDescriptor
- * records is being used, and hence the way any remaining fields should be
- * parsed. Values from 0 to 17 refer to SimpleTypeDescriptors. The value 18
- * designates an InterfaceTypeDescriptor, while 19 represents an
- * InterfaceIsTypeDescriptor.
+ * records is being used, and hence which union members are valid. Values from 0
+ * to 17 refer to SimpleTypeDescriptors. The value 18 designates an
+ * InterfaceTypeDescriptor, while 19 represents an InterfaceIsTypeDescriptor.
  */
 
 /* why bother with a struct?  - other code relies on this being a struct */
 struct XPTTypeDescriptorPrefix {
   uint8_t TagPart() const {
     static const uint8_t kFlagMask = 0xe0;
     return (uint8_t) (mFlags & ~kFlagMask);
   }
@@ -229,66 +169,62 @@ struct XPTTypeDescriptor {
   // assert if the tag is invalid. The memory layout here doesn't exactly match
   // the on-disk format. This is to save memory. Some fields for some cases are
   // smaller than they are on disk or omitted entirely.
   uint8_t mData1;
   uint8_t mData2;
 };
 
 /*
- * A ConstDescriptor is a variable-size record that records the name and
- * value of a scoped interface constant. This is allowed only for a subset
- * of types.
+ * A ConstDescriptor records the name and value of a scoped interface constant.
+ * This is allowed only for a subset of types.
  *
- * The type (and thus the size) of the value record is determined by the
- * contents of the associated TypeDescriptor record. For instance, if type
- * corresponds to int16_t, then value is a two-byte record consisting of a
- * 16-bit signed integer.
+ * The type of the value record is determined by the contents of the associated
+ * TypeDescriptor record. For instance, if type corresponds to int16_t, then
+ * value is a 16-bit signed integer.
  */
 union XPTConstValue {
   int16_t i16;
   uint16_t ui16;
   int32_t i32;
   uint32_t ui32;
-}; /* varies according to type */
+};
 
 struct XPTConstDescriptor {
   const char* Name() const {
     return mName;
   }
 
   const char* mName;
   XPTTypeDescriptor mType;
   union XPTConstValue mValue;
 };
 
 /*
- * A ParamDescriptor is a variable-size record used to describe either a
- * single argument to a method or a method's result.
+ * A ParamDescriptor is used to describe either a single argument to a method or
+ * a method's result.
  */
 struct XPTParamDescriptor {
   uint8_t mFlags;
   XPTTypeDescriptor mType;
 };
 
 /*
- * A MethodDescriptor is a variable-size record used to describe a single
- * interface method.
+ * A MethodDescriptor is used to describe a single interface method.
  */
 struct XPTMethodDescriptor {
   const char* Name() const {
     return mName;
   }
   const XPTParamDescriptor& Param(uint8_t aIndex) const {
     return mParams[aIndex];
   }
 
   const char* mName;
   const XPTParamDescriptor* mParams;
-  //XPTParamDescriptor mResult; // Present on disk, omitted here.
   uint8_t mFlags;
   uint8_t mNumArgs;
 };
 
 const char*
 XPTInterfaceDirectoryEntry::Name() const {
   return mName;
 }
deleted file mode 100644
--- a/xpcom/typelib/xpt/xpt_xdr.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 tw=80: */
-/* 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/. */
-
-/* Implementation of XDR primitives. */
-
-#include "xpt_xdr.h"
-#include "nscore.h"
-#include <string.h>             /* strchr */
-#include "mozilla/Assertions.h"
-#include "mozilla/EndianUtils.h"
-
-static size_t
-CursPoolOffsetRaw(NotNull<XPTCursor*> cursor)
-{
-    if (cursor->pool == XPT_HEADER) {
-        return cursor->offset;
-    }
-    MOZ_ASSERT(cursor->state->data_offset);
-    return cursor->offset + cursor->state->data_offset;
-}
-
-static size_t
-CursPoolOffset(NotNull<XPTCursor*> cursor)
-{
-    return CursPoolOffsetRaw(cursor) - 1;
-}
-
-static char*
-CursPoint(NotNull<XPTCursor*> cursor)
-{
-    return &cursor->state->pool_data[CursPoolOffset(cursor)];
-}
-
-static bool
-CheckCount(NotNull<XPTCursor*> cursor, uint32_t space)
-{
-    // Fail if we're in the data area and about to exceed the allocation.
-    // XXX Also fail if we're in the data area and !state->data_offset
-    if (cursor->pool == XPT_DATA &&
-        (CursPoolOffset(cursor) + space > cursor->state->pool_allocated)) {
-        MOZ_ASSERT(false);
-        fprintf(stderr, "FATAL: no room for %u in cursor\n", space);
-        return false;
-    }
-
-    return true;
-}
-
-void
-XPT_InitXDRState(XPTState* state, char *data, uint32_t len)
-{
-    state->next_cursor[0] = state->next_cursor[1] = 1;
-    state->pool_data = data;
-    state->pool_allocated = len;
-}
-
-/* All offsets are 1-based */
-void
-XPT_SetDataOffset(XPTState *state, uint32_t data_offset)
-{
-   state->data_offset = data_offset;
-}
-
-bool
-XPT_MakeCursor(XPTState *state, XPTPool pool, uint32_t len,
-               NotNull<XPTCursor*> cursor)
-{
-    cursor->state = state;
-    cursor->pool = pool;
-    cursor->bits = 0;
-    cursor->offset = state->next_cursor[pool];
-
-    if (!(CheckCount(cursor, len)))
-        return false;
-
-    /* this check should be in CHECK_CURSOR */
-    if (pool == XPT_DATA && !state->data_offset) {
-        fprintf(stderr, "no data offset for XPT_DATA cursor!\n");
-        return false;
-    }
-
-    state->next_cursor[pool] += len;
-
-    return true;
-}
-
-bool
-XPT_SeekTo(NotNull<XPTCursor*> cursor, uint32_t offset)
-{
-    /* XXX do some real checking and update len and stuff */
-    cursor->offset = offset;
-    return true;
-}
-
-bool
-XPT_SkipStringInline(NotNull<XPTCursor*> cursor)
-{
-    uint16_t length;
-    if (!XPT_Do16(cursor, &length))
-        return false;
-
-    uint8_t byte;
-    for (uint16_t i = 0; i < length; i++)
-        if (!XPT_Do8(cursor, &byte))
-            return false;
-
-    return true;
-}
-
-bool
-XPT_DoCString(XPTArena *arena, NotNull<XPTCursor*> cursor, const char **identp,
-              bool ignore)
-{
-    uint32_t offset = 0;
-    if (!XPT_Do32(cursor, &offset))
-        return false;
-
-    if (!offset) {
-        *identp = NULL;
-        return true;
-    }
-
-    XPTCursor my_cursor;
-    my_cursor.pool = XPT_DATA;
-    my_cursor.offset = offset;
-    my_cursor.state = cursor->state;
-    char* start = CursPoint(WrapNotNull(&my_cursor));
-
-    char* end = strchr(start, 0); /* find the end of the string */
-    if (!end) {
-        fprintf(stderr, "didn't find end of string on decode!\n");
-        return false;
-    }
-    int len = end - start;
-    MOZ_ASSERT(len > 0);
-
-    if (!ignore) {
-        char *ident = (char*)XPT_CALLOC1(arena, len + 1u);
-        if (!ident)
-            return false;
-
-        memcpy(ident, start, (size_t)len);
-        ident[len] = 0;
-        *identp = ident;
-    }
-
-    return true;
-}
-
-/*
- * IIDs are written in struct order, in the usual big-endian way.  From the
- * typelib file spec:
- *
- *   "For example, this IID:
- *     {00112233-4455-6677-8899-aabbccddeeff}
- *   is converted to the 128-bit value
- *     0x00112233445566778899aabbccddeeff
- *   Note that the byte storage order corresponds to the layout of the nsIID
- *   C-struct on a big-endian architecture."
- *
- * (http://www.mozilla.org/scriptable/typelib_file.html#iid)
- */
-bool
-XPT_DoIID(NotNull<XPTCursor*> cursor, nsID *iidp)
-{
-    int i;
-
-    if (!XPT_Do32(cursor, &iidp->m0) ||
-        !XPT_Do16(cursor, &iidp->m1) ||
-        !XPT_Do16(cursor, &iidp->m2))
-        return false;
-
-    for (i = 0; i < 8; i++)
-        if (!XPT_Do8(cursor, (uint8_t *)&iidp->m3[i]))
-            return false;
-
-    return true;
-}
-
-// MSVC apparently cannot handle functions as template parameters very well,
-// so we need to use a macro approach here.
-
-#define XPT_DOINT(T, func, valuep)                \
-    do {                                          \
-        const size_t sz = sizeof(T);              \
-                                                  \
-        if (!CheckCount(cursor, sz)) {            \
-            return false;                         \
-        }                                         \
-                                                  \
-        *valuep = func(CursPoint(cursor));        \
-        cursor->offset += sz;                     \
-        return true;                              \
-    } while(0)
-
-bool
-XPT_Do64(NotNull<XPTCursor*> cursor, int64_t *u64p)
-{
-    XPT_DOINT(int64_t, mozilla::BigEndian::readInt64, u64p);
-}
-
-/*
- * When we're handling 32- or 16-bit quantities, we handle a byte at a time to
- * avoid alignment issues.  Someone could come and optimize this to detect
- * well-aligned cases and do a single store, if they cared.  I might care
- * later.
- */
-bool
-XPT_Do32(NotNull<XPTCursor*> cursor, uint32_t *u32p)
-{
-    XPT_DOINT(uint32_t, mozilla::BigEndian::readUint32, u32p);
-}
-
-bool
-XPT_Do16(NotNull<XPTCursor*> cursor, uint16_t *u16p)
-{
-    XPT_DOINT(uint16_t, mozilla::BigEndian::readUint16, u16p);
-}
-
-#undef XPT_DOINT
-
-bool
-XPT_Do8(NotNull<XPTCursor*> cursor, uint8_t *u8p)
-{
-    if (!CheckCount(cursor, 1))
-        return false;
-
-    *u8p = *CursPoint(cursor);
-
-    cursor->offset++;
-
-    return true;
-}
-
-
deleted file mode 100644
--- a/xpcom/typelib/xpt/xpt_xdr.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 tw=80: */
-/* 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/. */
-
-/*
- * Basic APIs for streaming typelib structures from disk.
- */
-
-#ifndef __xpt_xdr_h__
-#define __xpt_xdr_h__
-
-#include "xpt_struct.h"
-#include "mozilla/NotNull.h"
-
-using mozilla::NotNull;
-
-struct XPTArena;
-struct XPTCursor;
-struct XPTState;
-
-bool
-XPT_SkipStringInline(NotNull<XPTCursor*> cursor);
-
-bool
-XPT_DoCString(XPTArena *arena, NotNull<XPTCursor*> cursor, const char **strp,
-              bool ignore = false);
-
-bool
-XPT_DoIID(NotNull<XPTCursor*> cursor, nsID *iidp);
-
-bool
-XPT_Do64(NotNull<XPTCursor*> cursor, int64_t *u64p);
-
-bool
-XPT_Do32(NotNull<XPTCursor*> cursor, uint32_t *u32p);
-
-bool
-XPT_Do16(NotNull<XPTCursor*> cursor, uint16_t *u16p);
-
-bool
-XPT_Do8(NotNull<XPTCursor*> cursor, uint8_t *u8p);
-
-bool
-XPT_DoHeader(XPTArena *arena, NotNull<XPTCursor*> cursor, XPTHeader **headerp);
-
-enum XPTPool {
-    XPT_HEADER = 0,
-    XPT_DATA = 1
-};
-
-struct XPTState {
-    uint32_t         data_offset;
-    uint32_t         next_cursor[2];
-    char             *pool_data;
-    uint32_t         pool_allocated;
-};
-
-struct XPTCursor {
-    XPTState    *state;
-    XPTPool     pool;
-    uint32_t    offset;
-    uint8_t     bits;
-};
-
-void
-XPT_InitXDRState(XPTState* state, char* data, uint32_t len);
-
-bool
-XPT_MakeCursor(XPTState *state, XPTPool pool, uint32_t len,
-               NotNull<XPTCursor*> cursor);
-
-bool
-XPT_SeekTo(NotNull<XPTCursor*> cursor, uint32_t offset);
-
-void
-XPT_SetDataOffset(XPTState *state, uint32_t data_offset);
-
-#endif /* __xpt_xdr_h__ */