Blob.java 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package gnu.lists;
  2. import gnu.kawa.io.BinaryInPort;
  3. import java.nio.charset.Charset;
  4. /** Binary data which may represent text or other information.
  5. * It can be used for the contents of a Unix-style file or pipe,
  6. * which is commonly but not always text, so whether it should be
  7. * treated as bytes, text, or something else is context-dependent.
  8. * (Nowadays you'd want an associated MIME-type, but that is
  9. * not always provided.)
  10. * The acronym "blob" has been taken as "binary large object", but
  11. * in this case it isn't necessary large.
  12. */
  13. public class Blob
  14. extends U8Vector
  15. implements CharSequence
  16. {
  17. private String stringValue;
  18. Charset charset;
  19. public Blob(byte[] data) {
  20. super(data);
  21. }
  22. public Blob(byte[] data, Charset charset) {
  23. super(data);
  24. this.charset = charset;
  25. }
  26. public static Blob wrap(byte[] data, int size) {
  27. Blob blob = new Blob(data);
  28. blob.setInfoField(size, 0,
  29. SimpleVector.SUBRANGE_FLAG|SimpleVector.READ_ONLY_FLAG);
  30. return blob;
  31. }
  32. public U8Vector asPlainBytevector() {
  33. if (isVerySimple()) {
  34. return new U8Vector(data);
  35. } else {
  36. int sz = size();
  37. byte[] b = new byte[sz];
  38. U8Vector vec = new U8Vector(b);
  39. vec.copyFrom(0, this, 0, sz);
  40. return vec;
  41. }
  42. }
  43. public String toString() {
  44. synchronized (this) {
  45. if (stringValue == null) {
  46. BinaryInPort in = new BinaryInPort(data, super.length(), null);
  47. // Caching the string value may not be a good idea.
  48. // Especially if we're just printing it.
  49. StringBuilder buf = new StringBuilder();
  50. try {
  51. boolean bomSeen = false;
  52. if (charset != null)
  53. bomSeen = in.setFromByteOrderMark();
  54. if (! bomSeen)
  55. // FIXME should do some sniffing to guess encoding.
  56. in.setCharset(charset != null ? charset
  57. : Charset.defaultCharset());
  58. int ch;
  59. while ((ch = in.read()) >= 0) {
  60. buf.append((char) ch);
  61. }
  62. } catch (Exception ex) {
  63. buf.append("[unexpected exception: ");
  64. buf.append(ex);
  65. buf.append(']');
  66. }
  67. stringValue = buf.toString();
  68. }
  69. return stringValue;
  70. }
  71. }
  72. public char charAt(int index) { return toString().charAt(index); }
  73. public int length() { return toString().length(); }
  74. public CharSequence subSequence(int start, int end) {
  75. return toString().subSequence(start, end);
  76. }
  77. }