/** * Reads this attribute's data from the given RawInputStream. * * @param in the RawInputStream containing attribute data * @throws IOException if an I/O error occurs */ protected void read(RawInputStream in) throws IOException { RawInputStream ris = new RawInputStream(in); // a new copy each time! Object o = null; // first handle special attributes switch (this.ID) { case attAttachRenddata: o = new RendData(ris); break; case attFrom: o = new TRPAddress(ris); break; case attOwner: case attSentFor: o = new Address(ris); break; case attRecipTable: // recipients are represented by a counted list of // MAPI property rows. int count = (int) ris.readU32(); MAPIProps[] recipients = new MAPIProps[count]; for (int i = 0; i < count; i++) { recipients[i] = new MAPIProps(ris); } o = recipients; break; case attMAPIProps: o = new MAPIProps(ris); break; } // handle generic types if (o == null) switch (type) { case atpByte: o = ris; break; case atpShort: o = new Short((short) ris.readU16()); break; case atpDword: o = new Long(ris.readU32()); break; case atpLong: o = new Long(ris.readU32()); break; case atpString: case atpText: case atpWord: // apparently used only in attMessageClass, as a string and not a word o = ris.readString(length); break; case atpDate: if (ris.getLength() >= 14) { // TNEF time is 7 16-bit fields Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); cal.set( ris.readU16(), // Calendar.YEAR ris.readU16() - 1, // Calendar.MONTH ris.readU16(), // Calendar.DATE ris.readU16(), // Calendar.HOUR ris.readU16(), // Calendar.MINUTE ris.readU16()); // Calendar.SECOND // Calendar.DAY_OF_WEEK in bytes 12-13 is not needed. cal.set(Calendar.MILLISECOND, 0); o = cal.getTime(); } break; case atpTriples: o = new TRPAddress(ris); break; } this.data = o; }