1 19 20 package org.apache.cayenne.util; 21 22 import java.io.IOException ; 23 import java.io.InputStream ; 24 import java.io.StringReader ; 25 import java.sql.Clob ; 26 import java.sql.SQLException ; 27 28 import org.apache.cayenne.CayenneRuntimeException; 29 30 40 public class MemoryClob implements Clob { 41 42 volatile String data; 43 44 58 public MemoryClob(String data) { 59 60 if (data == null) { 61 throw new CayenneRuntimeException("Null data"); 62 } 63 64 this.data = data; 65 } 66 67 75 public long length() throws SQLException { 76 77 final String ldata = data; 78 79 return ldata.length(); 80 } 81 82 87 public String getSubString(long pos, final int length) throws SQLException { 88 89 final String ldata = data; 90 final int dlen = ldata.length(); 91 92 pos--; 93 94 if (pos < 0 || pos > dlen) { 95 new CayenneRuntimeException("Invalid position: " + (pos + 1L)); 96 } 97 98 if (length < 0 || length > dlen - pos) { 99 throw new CayenneRuntimeException("Invalid length: " + length); 100 } 101 102 if (pos == 0 && length == dlen) { 103 return ldata; 104 } 105 106 return ldata.substring((int) pos, (int) pos + length); 107 } 108 109 118 public java.io.Reader getCharacterStream() throws SQLException { 119 120 final String ldata = data; 121 122 return new StringReader (ldata); 123 } 124 125 134 public java.io.InputStream getAsciiStream() throws SQLException { 135 136 final String ldata = data; 137 138 return new AsciiStringInputStream(ldata); 139 } 140 141 154 public long position(final String searchstr, long start) throws SQLException { 155 156 if (searchstr == null || start > Integer.MAX_VALUE) { 157 return -1; 158 } 159 160 final String ldata = data; 161 final int pos = ldata.indexOf(searchstr, (int) --start); 162 163 return (pos < 0) ? -1 : pos + 1; 164 } 165 166 178 public long position(final Clob searchstr, long start) throws SQLException { 179 180 if (searchstr == null) { 181 return -1; 182 } 183 184 final String ldata = data; 185 final long dlen = ldata.length(); 186 final long sslen = searchstr.length(); 187 188 if (start > dlen - sslen) { 193 return -1; 194 } 195 196 String s; 198 199 if (searchstr instanceof MemoryClob) { 200 s = ((MemoryClob) searchstr).data; 201 } 202 else { 203 s = searchstr.getSubString(1L, (int) sslen); 204 } 205 206 final int pos = ldata.indexOf(s, (int) start); 207 208 return (pos < 0) ? -1 : pos + 1; 209 } 210 211 216 public int setString(long pos, String str) throws SQLException { 217 throw new CayenneRuntimeException("Not supported"); 218 } 219 220 226 public int setString(long pos, String str, int offset, int len) throws SQLException { 227 throw new CayenneRuntimeException("Not supported"); 228 } 229 230 237 public java.io.OutputStream setAsciiStream(long pos) throws SQLException { 238 throw new CayenneRuntimeException("Not supported"); 239 } 240 241 248 public java.io.Writer setCharacterStream(long pos) throws SQLException { 249 throw new CayenneRuntimeException("Not supported"); 250 } 251 252 257 public void truncate(final long len) throws SQLException { 258 259 final String ldata = data; 260 final long dlen = ldata.length(); 261 final long chars = len >> 1; 262 263 if (chars == dlen) { 264 265 } 267 else if (len < 0 || chars > dlen) { 268 throw new CayenneRuntimeException("Invalid length: " + len); 269 } 270 else { 271 272 data = new String (ldata.substring(0, (int) chars)); 274 } 275 } 276 277 class AsciiStringInputStream extends InputStream { 278 279 protected int strOffset = 0; 280 protected int charOffset = 0; 281 protected int available; 282 protected String str; 283 284 public AsciiStringInputStream(String s) { 285 str = s; 286 available = s.length() * 2; 287 } 288 289 public int doRead() throws IOException { 290 291 if (available == 0) { 292 return -1; 293 } 294 295 available--; 296 297 char c = str.charAt(strOffset); 298 299 if (charOffset == 0) { 300 charOffset = 1; 301 302 return (c & 0x0000ff00) >> 8; 303 } 304 else { 305 charOffset = 0; 306 strOffset++; 307 return c & 0x000000ff; 308 } 309 } 310 311 public int read() throws IOException { 312 doRead(); 313 return doRead(); 314 } 315 316 public int available() throws IOException { 317 return available / 2; 318 } 319 } 320 } 321 | Popular Tags |