DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
/* -*- 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 http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_Blob_h
#define mozilla_dom_Blob_h

#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/BlobImpl.h"
#include "nsCycleCollectionParticipant.h"
#include "nsCOMPtr.h"
#include "nsIDOMBlob.h"
#include "nsIMutable.h"
#include "nsWrapperCache.h"
#include "nsWeakReference.h"

class nsIInputStream;

namespace mozilla {
namespace dom {

struct BlobPropertyBag;
class File;
class OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString;

class Blob : public nsIDOMBlob,
             public nsIMutable,
             public nsSupportsWeakReference,
             public nsWrapperCache {
 public:
  NS_DECL_NSIDOMBLOB
  NS_DECL_NSIMUTABLE

  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Blob, nsIDOMBlob)

  typedef OwningArrayBufferViewOrArrayBufferOrBlobOrUSVString BlobPart;

  // This creates a Blob or a File based on the type of BlobImpl.
  static Blob* Create(nsISupports* aParent, BlobImpl* aImpl);

  static already_AddRefed<Blob> CreateStringBlob(nsISupports* aParent,
                                                 const nsACString& aData,
                                                 const nsAString& aContentType);

  // The returned Blob takes ownership of aMemoryBuffer. aMemoryBuffer will be
  // freed by free so it must be allocated by malloc or something
  // compatible with it.
  static already_AddRefed<Blob> CreateMemoryBlob(nsISupports* aParent,
                                                 void* aMemoryBuffer,
                                                 uint64_t aLength,
                                                 const nsAString& aContentType);

  BlobImpl* Impl() const { return mImpl; }

  bool IsFile() const;

  const nsTArray<RefPtr<BlobImpl>>* GetSubBlobImpls() const;

  // This method returns null if this Blob is not a File; it returns
  // the same object in case this Blob already implements the File interface;
  // otherwise it returns a new File object with the same BlobImpl.
  already_AddRefed<File> ToFile();

  // This method creates a new File object with the given name and the same
  // BlobImpl.
  already_AddRefed<File> ToFile(const nsAString& aName, ErrorResult& aRv) const;

  already_AddRefed<Blob> CreateSlice(uint64_t aStart, uint64_t aLength,
                                     const nsAString& aContentType,
                                     ErrorResult& aRv);

  void CreateInputStream(nsIInputStream** aStream, ErrorResult& aRv);

  int64_t GetFileId();

  // A utility function that enforces the spec constraints on the type of a
  // blob: no codepoints outside the ASCII range (otherwise type becomes empty)
  // and lowercase ASCII only.  We can't just use our existing nsContentUtils
  // ASCII-related helpers because we need the "outside ASCII range" check, and
  // we can't use NS_IsAscii because its definition of "ASCII" (chars all <=
  // 0x7E) differs from the file API definition (which excludes control chars).
  static void MakeValidBlobType(nsAString& aType);

  // WebIDL methods
  nsISupports* GetParentObject() const { return mParent; }

  bool IsMemoryFile() const;

  // Blob constructor
  static already_AddRefed<Blob> Constructor(
      const GlobalObject& aGlobal, const Optional<Sequence<BlobPart>>& aData,
      const BlobPropertyBag& aBag, ErrorResult& aRv);

  virtual JSObject* WrapObject(JSContext* aCx,
                               JS::Handle<JSObject*> aGivenProto) override;

  uint64_t GetSize(ErrorResult& aRv);

  void GetType(nsAString& aType);

  already_AddRefed<Blob> Slice(const Optional<int64_t>& aStart,
                               const Optional<int64_t>& aEnd,
                               const Optional<nsAString>& aContentType,
                               ErrorResult& aRv);

  size_t GetAllocationSize() const;

  nsresult GetSendInfo(nsIInputStream** aBody, uint64_t* aContentLength,
                       nsACString& aContentType, nsACString& aCharset) const;

 protected:
  // File constructor should never be used directly. Use Blob::Create instead.
  Blob(nsISupports* aParent, BlobImpl* aImpl);
  virtual ~Blob();

  virtual bool HasFileInterface() const { return false; }

  // The member is the real backend implementation of this File/Blob.
  // It's thread-safe and not CC-able and it's the only element that is moved
  // between threads.
  // Note: we should not store any other state in this class!
  RefPtr<BlobImpl> mImpl;

 private:
  nsCOMPtr<nsISupports> mParent;
};

// Override BindingJSObjectMallocBytes for blobs to tell the JS GC how much
// memory is held live by the binding object.
size_t BindingJSObjectMallocBytes(Blob* aBlob);

}  // namespace dom
}  // namespace mozilla

#endif  // mozilla_dom_Blob_h