/** * 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. */ using System; using System.Collections.Generic; using System.Linq; using System.Text; using Avro; namespace Avro.Generic { /// /// The default type used by GenericReader and GenericWriter for RecordSchema. /// public class GenericRecord { public RecordSchema Schema { get; private set; } private IDictionary contents = new Dictionary(); public GenericRecord(RecordSchema schema) { this.Schema = schema; } public object this[string fieldName] { get { return contents[fieldName]; } } public void Add(string fieldName, object fieldValue) { if (Schema.Contains(fieldName)) { // TODO: Use a matcher to verify that object has the right type for the field. //contents.Add(fieldName, fieldValue); contents[fieldName] = fieldValue; return; } throw new AvroException("No such field: " + fieldName); } public bool TryGetValue(string fieldName, out object result) { return contents.TryGetValue(fieldName, out result); } public override bool Equals(object obj) { if (this == obj) return true; if (obj != null && obj is GenericRecord) { GenericRecord other = obj as GenericRecord; return Schema.Equals(other.Schema) && areEqual(contents, other.contents); } return false; } private static bool areEqual(IDictionary d1, IDictionary d2) { if (d1.Count == d2.Count) { foreach (KeyValuePair kv in d1) { object o; if (!d2.TryGetValue(kv.Key, out o)) return false; if (!areEqual(o, kv.Value)) return false; } return true; } return false; } private static bool areEqual(object o1, object o2) { if (o1 == null) return o2 == null; if (o2 == null) return false; if (o1 is Array) { if (!(o2 is Array)) return false; return areEqual(o1 as Array, o1 as Array); } else if (o1 is IDictionary) { if (!(o2 is IDictionary)) return false; return areEqual(o1 as IDictionary, o1 as IDictionary); } return o1.Equals(o2); } private static bool areEqual(Array a1, Array a2) { if (a1.Length != a2.Length) return false; for (int i = 0; i < a1.Length; i++) { if (!areEqual(a1.GetValue(i), a2.GetValue(i))) return false; } return true; } public override int GetHashCode() { return 31 * contents.GetHashCode()/* + 29 * Schema.GetHashCode()*/; } public override string ToString() { StringBuilder sb = new StringBuilder(); sb.Append("Schema: "); sb.Append(Schema); sb.Append(", contents: "); sb.Append("{ "); foreach (KeyValuePair kv in contents) { sb.Append(kv.Key); sb.Append(": "); sb.Append(kv.Value); sb.Append(", "); } sb.Append("}"); return sb.ToString(); } } }