if (Debug.debug) Debug.print(Debug.VERBOSE, "Appending String of length "+payload.length()); appendint(payload.length(), 4); appendBytes(payload.getBytes());
byte[] payloadbytes = null; try { payloadbytes = payload.getBytes("UTF-8"); } catch (UnsupportedEncodingException UEe) { if (DBusConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(UEe); throw new DBusException("System does not support UTF-8 encoding"); } if (Debug.debug) Debug.print(Debug.VERBOSE, "Appending String of length "+payloadbytes.length); appendint(payloadbytes.length, 4); appendBytes(payloadbytes);
   private int appendone(byte[] sigb, int sigofs, Object data) throws DBusException   {      try {         int i = sigofs;         if (Debug.debug) Debug.print((int) Debug.VERBOSE, (Object) bytecounter);         if (Debug.debug) Debug.print(Debug.VERBOSE, "Appending type: "+((char)sigb[i])+" value: "+data);         // pad to the alignment of this type.         pad(sigb[i]);         switch (sigb[i]) {            case ArgumentType.BYTE:               appendByte(((Number) data).byteValue());               break;            case ArgumentType.BOOLEAN:               appendint(((Boolean) data).booleanValue() ? 1 : 0, 4);               break;            case ArgumentType.DOUBLE:               long l = Double.doubleToLongBits((Double) data);               appendint(l, 8);               break;            case ArgumentType.FLOAT:               int rf = Float.floatToIntBits((Float) data);               appendint(rf, 4);               break;            case ArgumentType.UINT32:               appendint(((Number) data).longValue(), 4);               break;            case ArgumentType.INT64:               appendint(((Number) data).longValue(), 8);               break;            case ArgumentType.UINT64:               if (big) {                  appendint(((UInt64) data).top(), 4);                  appendint(((UInt64) data).bottom(), 4);               } else {                  appendint(((UInt64) data).bottom(), 4);                  appendint(((UInt64) data).top(), 4);               }               break;            case ArgumentType.INT32:               appendint(((Number) data).intValue(), 4);               break;            case ArgumentType.UINT16:               appendint(((Number) data).intValue(), 2);               break;            case ArgumentType.INT16:               appendint(((Number) data).shortValue(), 2);               break;            case ArgumentType.STRING:            case ArgumentType.OBJECT_PATH:               // Strings are marshalled as a UInt32 with the length,               // followed by the String, followed by a null byte.               String payload = data.toString();               if (Debug.debug) Debug.print(Debug.VERBOSE, "Appending String of length "+payload.length());               appendint(payload.length(), 4);               appendBytes(payload.getBytes());               appendBytes(padding[1]);               //pad(ArgumentType.STRING);? do we need this?               break;            case ArgumentType.SIGNATURE:               // Signatures are marshalled as a byte with the length,               // followed by the String, followed by a null byte.               // Signatures are generally short, so preallocate the array               // for the string, length and null byte.               if (data instanceof Type[])                  payload = Marshalling.getDBusType((Type[]) data);               else                  payload = (String) data;               byte[] pbytes = payload.getBytes();               preallocate(2+pbytes.length);               appendByte((byte) pbytes.length);               appendBytes(pbytes);               appendByte((byte) 0);               break;            case ArgumentType.ARRAY:               // Arrays are given as a UInt32 for the length in bytes,               // padding to the element alignment, then elements in               // order. The length is the length from the end of the               // initial padding to the end of the last element.               if (Debug.debug) {                  if (data instanceof Object[])                     Debug.print(Debug.VERBOSE, "Appending array: "+Arrays.deepToString((Object[])data));               }               byte[] alen = new byte[4];               appendBytes(alen);               pad(sigb[++i]);               long c = bytecounter;               // optimise primatives               if (data.getClass().isArray() &&                      data.getClass().getComponentType().isPrimitive()) {                  byte[] primbuf;                  int algn = getAlignment(sigb[i]);                  int len = Array.getLength(data);                  switch (sigb[i]) {                     case ArgumentType.BYTE:                        primbuf = (byte[]) data;                        break;                     case ArgumentType.INT16:                     case ArgumentType.INT32:                     case ArgumentType.INT64:                     case ArgumentType.BOOLEAN:                        primbuf = new byte[len*algn];                        for (int j = 0, k = 0; j < len; j++, k += algn)                           marshallint(Array.getLong(data, j), primbuf, k, algn);                        break;                     case ArgumentType.DOUBLE:                        primbuf = new byte[len*algn];                        for (int j = 0, k = 0; j < len; j++, k += algn)                           marshallint(                                 Double.doubleToRawLongBits(((double[])data)[j]),                                 primbuf, k, algn);                        break;                     case ArgumentType.FLOAT:                        primbuf = new byte[len*algn];                        for (int j = 0, k = 0; j < len; j++, k += algn)                           marshallint(                                 Float.floatToRawIntBits(((float[])data)[j]),                                 primbuf, k, algn);                        break;                     default:                        throw new MarshallingException("Primative array being sent as non-primative array.");                  }                  appendBytes(primbuf);                  i++;               } else if (data instanceof List) {                  Object[] contents = ((List) data).toArray();                  int diff = i;                  for (Object o: contents)                      diff = appendone(sigb, i, o);                  i = diff;               } else if (data instanceof Map) {                  int diff = i;                  for (Map.Entry<Object,Object> o: ((Map<Object,Object>) data).entrySet())                     diff = appendone(sigb, i, o);                  i = diff;               } else {                  Object[] contents = (Object[]) data;                  int diff = i;                  for (Object o: contents)                      diff = appendone(sigb, i, o);                  i = diff;               }               if (Debug.debug) Debug.print(Debug.VERBOSE, "start: "+c+" end: "+bytecounter+" length: "+(bytecounter-c));               marshallint(bytecounter-c, alen, 0, 4);               break;            case ArgumentType.STRUCT1:               // Structs are aligned to 8 bytes               // and simply contain each element marshalled in order               Object[] contents;               if (data instanceof Container)                   contents = ((Container) data).getParameters();               else                  contents = (Object[]) data;               int j = 0;               for (i++; sigb[i] != ArgumentType.STRUCT2; i++)                  i = appendone(sigb, i, contents[j++]);               break;            case ArgumentType.DICT_ENTRY1:               // Dict entries are the same as structs.               if (data instanceof Map.Entry) {                  i++;                  i = appendone(sigb, i, ((Map.Entry) data).getKey());                  i++;                  i = appendone(sigb, i, ((Map.Entry) data).getValue());                  i++;               } else {                  contents = (Object[]) data;                  j = 0;                  for (i++; sigb[i] != ArgumentType.DICT_ENTRY2; i++)                     i = appendone(sigb, i, contents[j++]);               }               break;            case ArgumentType.VARIANT:               // Variants are marshalled as a signature               // followed by the value.               if (data instanceof Variant) {                  Variant var = (Variant) data;                  appendone(new byte[] {ArgumentType.SIGNATURE}, 0, var.getSig());                  appendone((var.getSig()).getBytes(), 0, var.getValue());               } else if (data instanceof Object[]) {                  contents = (Object[]) data;                  appendone(new byte[] {ArgumentType.SIGNATURE}, 0, contents[0]);                  appendone(((String) contents[0]).getBytes(), 0, contents[1]);               } else {                  String sig = Marshalling.getDBusType(data.getClass())[0];                  appendone(new byte[] {ArgumentType.SIGNATURE}, 0, sig);                  appendone((sig).getBytes(), 0, data);               }               break;         }         return i;      } catch (ClassCastException CCe) {         if (DBusConnection.EXCEPTION_DEBUG) CCe.printStackTrace();         throw new MarshallingException("Trying to marshall to unconvertable type (from "+data.getClass().getName()+" to "+sigb[sigofs]+")");      }   }