
1 // 2 // Copyright (c) 2006, Brian Frank and Andy Frank 3 // Licensed under the Academic Free License version 3.0 4 // 5 // History: 6 // 26 Dec 05 Brian Frank Creation 7 // 19 Aug 06 Brian Frank Ported from Java to Fan 8 // 9 10 ** 11 ** FTable is a 16-bit indexed lookup table for pod constants. 12 ** 13 class FTable 14 { 15 16 ////////////////////////////////////////////////////////////////////////// 17 // Factories 18 ////////////////////////////////////////////////////////////////////////// 19 20 static FTable makeStrs(FPod pod) 21 { 22 return make(pod, 23 |OutStream out, Obj obj| { out.writeUtf((Str)obj) }, 24 |InStream in->Obj| { return in.readUtf.intern }) 25 } 26 27 static FTable makeTypeRefs(FPod pod) 28 { 29 return make(pod, 30 |OutStream out, Obj obj| { ((FTypeRef)obj).write(out) }, 31 |InStream in->Obj| { return FTypeRef.read(in) }) 32 } 33 34 static FTable makeFieldRefs(FPod pod) 35 { 36 return make(pod, 37 |OutStream out, Obj obj| { ((FFieldRef)obj).write(out) }, 38 |InStream in->Obj| { return FFieldRef.read(in) }) 39 } 40 41 static FTable makeMethodRefs(FPod pod) 42 { 43 return make(pod, 44 |OutStream out, Obj obj| { ((FMethodRef)obj).write(out) }, 45 |InStream in->Obj| { return FMethodRef.read(in) }) 46 } 47 48 static FTable makeInts(FPod pod) 49 { 50 return make(pod, 51 |OutStream out, Obj obj| { out.writeI8((Int)obj) }, 52 |InStream in->Obj| { return in.readS8 }) 53 } 54 55 static FTable makeFloats(FPod pod) 56 { 57 return make(pod, 58 |OutStream out, Obj obj| { out.writeF8((Float)obj) }, 59 |InStream in->Obj| { return in.readF8 }) 60 } 61 62 static FTable makeDurations(FPod pod) 63 { 64 return make(pod, 65 |OutStream out, Obj obj| { out.writeI8(((Duration)obj).ticks) }, 66 |InStream in->Obj| { return Duration.make(in.readS8) }) 67 } 68 69 ////////////////////////////////////////////////////////////////////////// 70 // Constructor 71 ////////////////////////////////////////////////////////////////////////// 72 73 new make(FPod pod, |OutStream out, Obj obj| writter, |InStream in->Obj| reader) 74 { 75 this.pod = pod 76 this.writter = writter 77 this.reader = reader 78 this.table = [,] 79 this.reverse = Obj:Int[:] 80 } 81 82 ////////////////////////////////////////////////////////////////////////// 83 // Access 84 ////////////////////////////////////////////////////////////////////////// 85 86 ** 87 ** Return if this table is empty 88 ** 89 Bool isEmpty() 90 { 91 return table.isEmpty 92 } 93 94 ** 95 ** Get the object identified by the specified 16-bit index. 96 ** 97 Obj get(Int index) 98 { 99 return table[index] 100 } 101 102 ** 103 ** Perform a reverse lookup to map a value to it's index (only 104 ** available at compile time). If the value isn't in the table 105 ** yet, then add it. 106 ** 107 Int add(Obj val) 108 { 109 index := reverse[val] 110 if (index == null) 111 { 112 index = table.size 113 table.add(val) 114 reverse[val] = index 115 } 116 return index 117 } 118 119 ** 120 ** Serialize. 121 ** 122 FTable read(InStream in) 123 { 124 table = [,] 125 if (in == null) return this 126 in.readU2.times |,| { table.add(reader.call1(in)) } 127 in.close 128 return this 129 } 130 131 ** 132 ** Deserialize. 133 ** 134 Void write(OutStream out) 135 { 136 out.writeI2(table.size) 137 table.each |Obj obj| { writter.call2(out, obj) } 138 out.close 139 } 140 141 ////////////////////////////////////////////////////////////////////////// 142 // Fields 143 ////////////////////////////////////////////////////////////////////////// 144 145 FPod pod 146 Obj[] table 147 Obj:Int reverse 148 |OutStream out, Obj obj| writter 149 |InStream in->Obj| reader 150 }