/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */


#include "StringBytesMap.h"

namespace libyarn {

StringBytesMap::StringBytesMap() {
	mapProto = StringBytesMapProto::default_instance();
}

StringBytesMap::StringBytesMap(const StringBytesMapProto &proto) :
		mapProto(proto) {
}

StringBytesMap::~StringBytesMap() {
}

StringBytesMapProto& StringBytesMap::getProto() {
	return mapProto;
}

void StringBytesMap::setKey(string &key) {
	mapProto.set_key(key);
}
string StringBytesMap::getKey() {
	return mapProto.key();
}

void StringBytesMap::setValue(string &value) {
	mapProto.set_value(value);
}

string StringBytesMap::getValue() {
	return mapProto.value();
}


} /* namespace libyarn */
