blob: de6b604ae9c2dc547faa17c0e139de01cd9e7945 [file] [log] [blame]
Andreas Wundsam40e14f72013-05-06 14:49:08 -07001package org.openflow.types;
2
Andreas Wundsam40e14f72013-05-06 14:49:08 -07003
Yotam Harchol161a5d52013-07-25 17:17:48 -07004
5public class Masked<T extends OFValueType> implements OFValueType {
6 private T value;
7 private T mask;
8
9 private Masked(T value, T mask) {
10 this.value = value;
11 this.mask = mask;
12 }
13
14 public T getValue() {
15 return value;
16 }
17
18 public T getMask() {
19 return mask;
20 }
21
22 @Override
23 public int getLength() {
24 return this.value.getLength() + this.mask.getLength();
25 }
26
27 volatile byte[] bytesCache = null;
28
29 @Override
30 public byte[] getBytes() {
31 if (bytesCache == null) {
32 synchronized(this) {
33 if (bytesCache == null) {
34 byte[] bytesValue = this.value.getBytes();
35 byte[] bytesMask = this.mask.getBytes();
36 bytesCache = new byte[bytesValue.length + bytesMask.length];
37 System.arraycopy(bytesValue, 0, bytesCache, 0, bytesValue.length);
38 System.arraycopy(bytesMask, 0, bytesCache, bytesValue.length, bytesMask.length);
39 }
40 }
41 }
42 return bytesCache;
43 }
44
45 public static <T extends OFValueType> Masked<T> of(T value, T mask) {
46 return new Masked<T>(value, mask);
47 }
48
49 @Override
50 public boolean equals(Object obj) {
51 if (!(obj instanceof Masked<?>))
52 return false;
53 Masked<?> mobj = (Masked<?>)obj;
54 return this.value.equals(mobj.value) && this.mask.equals(mobj.mask);
55 }
56
57 @Override
58 public int hashCode() {
59 final int prime = 59;
60 int result = 1;
61 result = prime * result + this.value.hashCode();
62 result = prime * result + this.mask.hashCode();
63 return result;
64 }
65
66 @Override
67 public String toString() {
68 if (value.getClass() == IPv4.class) {
69 // TODO: How to output the mask when not in CIDR notation?
70 StringBuilder res = new StringBuilder();
71 res.append(((IPv4)value).toString());
72
73 int maskint = ((IPv4)mask).getInt();
74 if (Integer.bitCount((~maskint) + 1) == 1) {
75 // CIDR notation
76 res.append('/');
77 res.append(Integer.bitCount(maskint));
78 } else {
79 // Arbitrary mask not in CIDR notation
80 // TODO: HERE?
81 }
82
83 return res.toString();
84 } else if (value.getClass() == IPv6.class) {
85 // TODO: Return IPv6 string
86 StringBuilder sb = new StringBuilder();
87 sb.append(value.toString()).append('/').append(mask.toString());
88 return sb.toString();
89 } else {
90 // General representation: value/mask
91 StringBuilder sb = new StringBuilder();
92 sb.append(value.toString()).append('/').append(mask.toString());
93 return sb.toString();
94 }
95 }
96
Andreas Wundsam40e14f72013-05-06 14:49:08 -070097}