Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
86 Kevin 1
// Protocol Buffers - Google's data interchange format
2
// Copyright 2008 Google Inc.  All rights reserved.
3
// http://code.google.com/p/protobuf/
4
//
5
// Redistribution and use in source and binary forms, with or without
6
// modification, are permitted provided that the following conditions are
7
// met:
8
//
9
//     * Redistributions of source code must retain the above copyright
10
// notice, this list of conditions and the following disclaimer.
11
//     * Redistributions in binary form must reproduce the above
12
// copyright notice, this list of conditions and the following disclaimer
13
// in the documentation and/or other materials provided with the
14
// distribution.
15
//     * Neither the name of Google Inc. nor the names of its
16
// contributors may be used to endorse or promote products derived from
17
// this software without specific prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
 
31
package com.google.protobuf;
32
 
33
import java.util.List;
34
import java.util.AbstractList;
35
import java.util.ArrayList;
36
import java.util.RandomAccess;
37
import java.util.Collection;
38
 
39
/**
40
 * An implementation of {@link LazyStringList} that wraps an ArrayList. Each
41
 * element is either a ByteString or a String. It caches the last one requested
42
 * which is most likely the one needed next. This minimizes memory usage while
43
 * satisfying the most common use cases.
44
 * <p>
45
 * <strong>Note that this implementation is not synchronized.</strong>
46
 * If multiple threads access an <tt>ArrayList</tt> instance concurrently,
47
 * and at least one of the threads modifies the list structurally, it
48
 * <i>must</i> be synchronized externally.  (A structural modification is
49
 * any operation that adds or deletes one or more elements, or explicitly
50
 * resizes the backing array; merely setting the value of an element is not
51
 * a structural modification.)  This is typically accomplished by
52
 * synchronizing on some object that naturally encapsulates the list.
53
 * <p>
54
 * If the implementation is accessed via concurrent reads, this is thread safe.
55
 * Conversions are done in a thread safe manner. It's possible that the
56
 * conversion may happen more than once if two threads attempt to access the
57
 * same element and the modifications were not visible to each other, but this
58
 * will not result in any corruption of the list or change in behavior other
59
 * than performance.
60
 *
61
 * @author jonp@google.com (Jon Perlow)
62
 */
63
public class LazyStringArrayList extends AbstractList<String>
64
    implements LazyStringList, RandomAccess {
65
 
66
  public final static LazyStringList EMPTY = new UnmodifiableLazyStringList(
67
      new LazyStringArrayList());
68
 
69
  private final List<Object> list;
70
 
71
  public LazyStringArrayList() {
72
    list = new ArrayList<Object>();
73
  }
74
 
75
  public LazyStringArrayList(List<String> from) {
76
    list = new ArrayList<Object>(from);
77
  }
78
 
79
  @Override
80
  public String get(int index) {
81
    Object o = list.get(index);
82
    if (o instanceof String) {
83
      return (String) o;
84
    } else {
85
      ByteString bs = (ByteString) o;
86
      String s = bs.toStringUtf8();
87
      if (Internal.isValidUtf8(bs)) {
88
        list.set(index, s);
89
      }
90
      return s;
91
    }
92
  }
93
 
94
  @Override
95
  public int size() {
96
    return list.size();
97
  }
98
 
99
  @Override
100
  public String set(int index, String s) {
101
    Object o = list.set(index, s);
102
    return asString(o);
103
  }
104
 
105
  @Override
106
  public void add(int index, String element) {
107
    list.add(index, element);
108
    modCount++;
109
  }
110
 
111
  @Override
112
  public boolean addAll(int index, Collection<? extends String> c) {
113
    boolean ret = list.addAll(index, c);
114
    modCount++;
115
    return ret;
116
  }
117
 
118
  @Override
119
  public String remove(int index) {
120
    Object o = list.remove(index);
121
    modCount++;
122
    return asString(o);
123
  }
124
 
125
  public void clear() {
126
    list.clear();
127
    modCount++;
128
  }
129
 
130
  // @Override
131
  public void add(ByteString element) {
132
    list.add(element);
133
    modCount++;
134
  }
135
 
136
  // @Override
137
  public ByteString getByteString(int index) {
138
    Object o = list.get(index);
139
    if (o instanceof String) {
140
      ByteString b = ByteString.copyFromUtf8((String) o);
141
      list.set(index, b);
142
      return b;
143
    } else {
144
      return (ByteString) o;
145
    }
146
  }
147
 
148
  private String asString(Object o) {
149
    if (o instanceof String) {
150
      return (String) o;
151
    } else {
152
      return ((ByteString) o).toStringUtf8();
153
    }
154
  }
155
}