143 x |
143 x |
144 } |
144 } |
145 |
145 |
146 private def trim_bytes(s: String): String = new String(s.toCharArray) |
146 private def trim_bytes(s: String): String = new String(s.toCharArray) |
147 |
147 |
148 private def _cache_string(x: String): String = |
148 private def cache_string(x: String): String = |
149 lookup(x) match { |
149 lookup(x) match { |
150 case Some(y) => y |
150 case Some(y) => y |
151 case None => |
151 case None => |
152 val z = trim_bytes(x) |
152 val z = trim_bytes(x) |
153 if (z.length > max_string) z else store(z) |
153 if (z.length > max_string) z else store(z) |
154 } |
154 } |
155 private def _cache_props(x: Properties.T): Properties.T = |
155 private def cache_props(x: Properties.T): Properties.T = |
156 if (x.isEmpty) x |
156 if (x.isEmpty) x |
157 else |
157 else |
158 lookup(x) match { |
158 lookup(x) match { |
159 case Some(y) => y |
159 case Some(y) => y |
160 case None => store(x.map(p => (trim_bytes(p._1).intern, _cache_string(p._2)))) |
160 case None => store(x.map(p => (trim_bytes(p._1).intern, cache_string(p._2)))) |
161 } |
161 } |
162 private def _cache_markup(x: Markup): Markup = |
162 private def cache_markup(x: Markup): Markup = |
163 lookup(x) match { |
163 lookup(x) match { |
164 case Some(y) => y |
164 case Some(y) => y |
165 case None => |
165 case None => |
166 x match { |
166 x match { |
167 case Markup(name, props) => |
167 case Markup(name, props) => |
168 store(Markup(_cache_string(name), _cache_props(props))) |
168 store(Markup(cache_string(name), cache_props(props))) |
169 } |
169 } |
170 } |
170 } |
171 private def _cache_tree(x: XML.Tree): XML.Tree = |
171 private def cache_tree(x: XML.Tree): XML.Tree = |
172 lookup(x) match { |
172 lookup(x) match { |
173 case Some(y) => y |
173 case Some(y) => y |
174 case None => |
174 case None => |
175 x match { |
175 x match { |
176 case XML.Elem(markup, body) => |
176 case XML.Elem(markup, body) => |
177 store(XML.Elem(_cache_markup(markup), _cache_body(body))) |
177 store(XML.Elem(cache_markup(markup), cache_body(body))) |
178 case XML.Text(text) => store(XML.Text(_cache_string(text))) |
178 case XML.Text(text) => store(XML.Text(cache_string(text))) |
179 } |
179 } |
180 } |
180 } |
181 private def _cache_body(x: XML.Body): XML.Body = |
181 private def cache_body(x: XML.Body): XML.Body = |
182 if (x.isEmpty) x |
182 if (x.isEmpty) x |
183 else |
183 else |
184 lookup(x) match { |
184 lookup(x) match { |
185 case Some(y) => y |
185 case Some(y) => y |
186 case None => x.map(_cache_tree(_)) |
186 case None => x.map(cache_tree(_)) |
187 } |
187 } |
188 |
188 |
189 // main methods |
189 // main methods |
190 def cache_string(x: String): String = synchronized { _cache_string(x) } |
190 def string(x: String): String = synchronized { cache_string(x) } |
191 def cache_props(x: Properties.T): Properties.T = synchronized { _cache_props(x) } |
191 def props(x: Properties.T): Properties.T = synchronized { cache_props(x) } |
192 def cache_markup(x: Markup): Markup = synchronized { _cache_markup(x) } |
192 def markup(x: Markup): Markup = synchronized { cache_markup(x) } |
193 def cache_tree(x: XML.Tree): XML.Tree = synchronized { _cache_tree(x) } |
193 def tree(x: XML.Tree): XML.Tree = synchronized { cache_tree(x) } |
194 def cache_body(x: XML.Body): XML.Body = synchronized { _cache_body(x) } |
194 def body(x: XML.Body): XML.Body = synchronized { cache_body(x) } |
|
195 def elem(x: XML.Elem): XML.Elem = synchronized { cache_tree(x).asInstanceOf[XML.Elem] } |
195 } |
196 } |
196 |
197 |
197 |
198 |
198 |
199 |
199 /** XML as data representation language **/ |
200 /** XML as data representation language **/ |