summaryrefslogtreecommitdiffstats
path: root/mobile/android/exoplayer2/src/main/java/org/mozilla/thirdparty/com/google/android/exoplayer2/upstream/cache/ContentMetadataMutations.java
blob: c7a8d9f711135d5ac5d77c7cfc530b5776067d1e (plain)
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
141
142
143
144
145
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * 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.
 */
package org.mozilla.thirdparty.com.google.android.exoplayer2.upstream.cache;

import android.net.Uri;
import androidx.annotation.Nullable;
import org.mozilla.thirdparty.com.google.android.exoplayer2.C;
import org.mozilla.thirdparty.com.google.android.exoplayer2.util.Assertions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Defines multiple mutations on metadata value which are applied atomically. This class isn't
 * thread safe.
 */
public class ContentMetadataMutations {

  /**
   * Adds a mutation to set the {@link ContentMetadata#KEY_CONTENT_LENGTH} value, or to remove any
   * existing value if {@link C#LENGTH_UNSET} is passed.
   *
   * @param mutations The mutations to modify.
   * @param length The length value, or {@link C#LENGTH_UNSET} to remove any existing entry.
   * @return The mutations instance, for convenience.
   */
  public static ContentMetadataMutations setContentLength(
      ContentMetadataMutations mutations, long length) {
    return mutations.set(ContentMetadata.KEY_CONTENT_LENGTH, length);
  }

  /**
   * Adds a mutation to set the {@link ContentMetadata#KEY_REDIRECTED_URI} value, or to remove any
   * existing entry if {@code null} is passed.
   *
   * @param mutations The mutations to modify.
   * @param uri The {@link Uri} value, or {@code null} to remove any existing entry.
   * @return The mutations instance, for convenience.
   */
  public static ContentMetadataMutations setRedirectedUri(
      ContentMetadataMutations mutations, @Nullable Uri uri) {
    if (uri == null) {
      return mutations.remove(ContentMetadata.KEY_REDIRECTED_URI);
    } else {
      return mutations.set(ContentMetadata.KEY_REDIRECTED_URI, uri.toString());
    }
  }

  private final Map<String, Object> editedValues;
  private final List<String> removedValues;

  /** Constructs a DefaultMetadataMutations. */
  public ContentMetadataMutations() {
    editedValues = new HashMap<>();
    removedValues = new ArrayList<>();
  }

  /**
   * Adds a mutation to set a metadata value. Passing {@code null} as {@code name} or {@code value}
   * isn't allowed.
   *
   * @param name The name of the metadata value.
   * @param value The value to be set.
   * @return This instance, for convenience.
   */
  public ContentMetadataMutations set(String name, String value) {
    return checkAndSet(name, value);
  }

  /**
   * Adds a mutation to set a metadata value. Passing {@code null} as {@code name} isn't allowed.
   *
   * @param name The name of the metadata value.
   * @param value The value to be set.
   * @return This instance, for convenience.
   */
  public ContentMetadataMutations set(String name, long value) {
    return checkAndSet(name, value);
  }

  /**
   * Adds a mutation to set a metadata value. Passing {@code null} as {@code name} or {@code value}
   * isn't allowed.
   *
   * @param name The name of the metadata value.
   * @param value The value to be set.
   * @return This instance, for convenience.
   */
  public ContentMetadataMutations set(String name, byte[] value) {
    return checkAndSet(name, Arrays.copyOf(value, value.length));
  }

  /**
   * Adds a mutation to remove a metadata value.
   *
   * @param name The name of the metadata value.
   * @return This instance, for convenience.
   */
  public ContentMetadataMutations remove(String name) {
    removedValues.add(name);
    editedValues.remove(name);
    return this;
  }

  /** Returns a list of names of metadata values to be removed. */
  public List<String> getRemovedValues() {
    return Collections.unmodifiableList(new ArrayList<>(removedValues));
  }

  /** Returns a map of metadata name, value pairs to be set. Values are copied.  */
  public Map<String, Object> getEditedValues() {
    HashMap<String, Object> hashMap = new HashMap<>(editedValues);
    for (Entry<String, Object> entry : hashMap.entrySet()) {
      Object value = entry.getValue();
      if (value instanceof byte[]) {
        byte[] bytes = (byte[]) value;
        entry.setValue(Arrays.copyOf(bytes, bytes.length));
      }
    }
    return Collections.unmodifiableMap(hashMap);
  }

  private ContentMetadataMutations checkAndSet(String name, Object value) {
    editedValues.put(Assertions.checkNotNull(name), Assertions.checkNotNull(value));
    removedValues.remove(name);
    return this;
  }
}