Home | History | Annotate | Download | only in webmidi
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef MIDIPortMap_h
      6 #define MIDIPortMap_h
      7 
      8 #include "bindings/core/v8/ExceptionState.h"
      9 #include "bindings/core/v8/ScriptState.h"
     10 #include "bindings/core/v8/ScriptValue.h"
     11 #include "bindings/core/v8/V8Binding.h"
     12 #include "core/dom/Iterator.h"
     13 #include "platform/heap/Handle.h"
     14 #include "wtf/HashMap.h"
     15 #include "wtf/text/StringHash.h"
     16 #include "wtf/text/WTFString.h"
     17 
     18 namespace blink {
     19 
     20 template <typename T>
     21 class MIDIPortMap : public GarbageCollected<MIDIPortMap<T> > {
     22 public:
     23     explicit MIDIPortMap(const HeapHashMap<String, Member<T> >& entries) : m_entries(entries) { }
     24 
     25     // IDL attributes / methods
     26     size_t size() const { return m_entries.size(); }
     27     Iterator* keys();
     28     Iterator* entries();
     29     Iterator* values();
     30     T* get(const String& key) const;
     31     bool has(const String& key) const { return m_entries.contains(key); }
     32     Iterator* iterator(ScriptState*, ExceptionState&) { return entries(); }
     33 
     34     virtual void trace(Visitor* visitor)
     35     {
     36         visitor->trace(m_entries);
     37     }
     38 
     39 private:
     40     typedef HeapHashMap<String, Member<T> > MapType;
     41     typedef typename HeapHashMap<String, Member<T> >::const_iterator IteratorType;
     42     struct KeySelector {
     43         static const String& select(ScriptState*, IteratorType i) { return i->key; }
     44     };
     45     struct ValueSelector {
     46         static T* select(ScriptState*, IteratorType i) { return i->value; }
     47     };
     48     struct EntrySelector {
     49         static Vector<ScriptValue> select(ScriptState* scriptState, IteratorType i)
     50         {
     51             Vector<ScriptValue> entry;
     52             entry.append(ScriptValue(scriptState, v8String(scriptState->isolate(), i->key)));
     53             entry.append(ScriptValue(scriptState, V8ValueTraits<T*>::toV8Value(i->value, scriptState->context()->Global(), scriptState->isolate())));
     54             return entry;
     55         }
     56     };
     57 
     58     // Note: This template class relies on the fact that m_map.m_entries will
     59     // never be modified once it is created.
     60     template <typename Selector>
     61     class MapIterator : public Iterator {
     62     public:
     63         MapIterator(MIDIPortMap<T>* map, IteratorType iterator, IteratorType end)
     64             : m_map(map)
     65             , m_iterator(iterator)
     66             , m_end(end)
     67         {
     68         }
     69 
     70         virtual ScriptValue next(ScriptState* scriptState, ExceptionState&) OVERRIDE
     71         {
     72             if (m_iterator == m_end)
     73                 return ScriptValue(scriptState, v8DoneIteratorResult(scriptState->isolate()));
     74             ScriptValue result(scriptState, v8IteratorResult(scriptState, Selector::select(scriptState, m_iterator)));
     75             ++m_iterator;
     76             return result;
     77         }
     78 
     79         virtual ScriptValue next(ScriptState* scriptState, ScriptValue, ExceptionState& exceptionState) OVERRIDE
     80         {
     81             return next(scriptState, exceptionState);
     82         }
     83 
     84         virtual void trace(Visitor* visitor) OVERRIDE
     85         {
     86             visitor->trace(m_map);
     87             Iterator::trace(visitor);
     88         }
     89 
     90     private:
     91         // m_map is stored just for keeping it alive. It needs to be kept
     92         // alive while JavaScript holds the iterator to it.
     93         const Member<const MIDIPortMap<T> > m_map;
     94         IteratorType m_iterator;
     95         const IteratorType m_end;
     96     };
     97 
     98     const MapType m_entries;
     99 };
    100 
    101 template <typename T>
    102 Iterator* MIDIPortMap<T>::keys()
    103 {
    104     return new MapIterator<KeySelector>(this, m_entries.begin(), m_entries.end());
    105 }
    106 
    107 template <typename T>
    108 Iterator* MIDIPortMap<T>::entries()
    109 {
    110     return new MapIterator<EntrySelector>(this, m_entries.begin(), m_entries.end());
    111 }
    112 
    113 template <typename T>
    114 Iterator* MIDIPortMap<T>::values()
    115 {
    116     return new MapIterator<ValueSelector>(this, m_entries.begin(), m_entries.end());
    117 }
    118 
    119 template <typename T>
    120 T* MIDIPortMap<T>::get(const String& key) const
    121 {
    122     return has(key) ? m_entries.get(key) : 0;
    123 }
    124 
    125 } // namespace blink
    126 
    127 #endif
    128