Logo Search packages:      
Sourcecode: dbus-java version File versions  Download package

Object org::freedesktop::dbus::Message::extractone ( byte[]  sigb,
byte[]  buf,
int[]  ofs,
boolean  contained 
) throws DBusException [inline, private]

Demarshall one value from a buffer.

Parameters:
sigb A buffer of the D-Bus signature.
buf The buffer to demarshall from.
ofs An array of two ints, the offset into the signature buffer and the offset into the data buffer. These values will be updated to the start of the next value ofter demarshalling.
contained converts nested arrays to Lists
Returns:
The demarshalled value.

Definition at line 804 of file Message.java.

References align(), demarshallint(), extract(), getAlignment(), and getSource().

Referenced by extract().

   {
      if (Debug.debug) Debug.print(Debug.VERBOSE, "Extracting type: "+((char)sigb[ofs[0]])+" from offset "+ofs[1]);
      Object rv = null;
      ofs[1] = align(ofs[1], sigb[ofs[0]]);
      switch (sigb[ofs[0]]) {
         case ArgumentType.BYTE:
            rv = buf[ofs[1]++];
            break;
         case ArgumentType.UINT32:
            rv = new UInt32(demarshallint(buf, ofs[1], 4));
            ofs[1] += 4;
            break;
         case ArgumentType.INT32:
            rv = (int) demarshallint(buf, ofs[1], 4);
            ofs[1] += 4;
            break;
         case ArgumentType.INT16:
            rv = (short) demarshallint(buf, ofs[1], 2);
            ofs[1] += 2;
            break;
         case ArgumentType.UINT16:
            rv = new UInt16((int) demarshallint(buf, ofs[1], 2));
            ofs[1] += 2;
            break;
         case ArgumentType.INT64:
            rv = demarshallint(buf, ofs[1], 8);
            ofs[1] += 8;
            break;
         case ArgumentType.UINT64:
            long top;
            long bottom;
            if (big) {
               top = demarshallint(buf, ofs[1], 4);
               ofs[1] += 4;
               bottom = demarshallint(buf, ofs[1], 4);
            } else {
               bottom = demarshallint(buf, ofs[1], 4);
               ofs[1] += 4;
               top = demarshallint(buf, ofs[1], 4);
            }
            rv = new UInt64(top, bottom);
            ofs[1] += 4;
            break;
         case ArgumentType.DOUBLE:
            long l = demarshallint(buf, ofs[1], 8);
            ofs[1] += 8;
            rv = Double.longBitsToDouble(l);
            break;
         case ArgumentType.FLOAT:
            int rf = (int) demarshallint(buf, ofs[1], 4);
            ofs[1] += 4;
            rv = Float.intBitsToFloat(rf);
            break;
         case ArgumentType.BOOLEAN:
            rf = (int) demarshallint(buf, ofs[1], 4);
            ofs[1] += 4;
            rv = (1==rf)?Boolean.TRUE:Boolean.FALSE;
            break;
         case ArgumentType.ARRAY:
            long size = demarshallint(buf, ofs[1], 4);
            if (Debug.debug) Debug.print(Debug.VERBOSE, "Reading array of size: "+size);
            ofs[1] += 4;
            byte algn = (byte) getAlignment(sigb[++ofs[0]]);
            ofs[1] = align(ofs[1], sigb[ofs[0]]);
            int length = (int) (size / algn);
            if (length > DBusConnection.MAX_ARRAY_LENGTH)
               throw new MarshallingException(_("Arrays must not exceed ")+DBusConnection.MAX_ARRAY_LENGTH);
            // optimise primatives
            switch (sigb[ofs[0]]) {
               case ArgumentType.BYTE:
                  rv = new byte[length];
                  System.arraycopy(buf, ofs[1], rv, 0, length);
                  ofs[1] += size;
                  break;
               case ArgumentType.INT16:
                  rv = new short[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((short[]) rv)[j] = (short) demarshallint(buf, ofs[1], algn);
                  break;
               case ArgumentType.INT32:
                  rv = new int[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((int[]) rv)[j] = (int) demarshallint(buf, ofs[1], algn);
                  break;
               case ArgumentType.INT64:
                  rv = new long[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((long[]) rv)[j] = demarshallint(buf, ofs[1], algn);
                  break;
               case ArgumentType.BOOLEAN:
                  rv = new boolean[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((boolean[]) rv)[j] = (1 == demarshallint(buf, ofs[1], algn));
                  break;
               case ArgumentType.FLOAT:
                  rv = new float[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((float[]) rv)[j] =
                        Float.intBitsToFloat((int)demarshallint(buf, ofs[1], algn));
                  break;
               case ArgumentType.DOUBLE:
                  rv = new double[length];
                  for (int j = 0; j < length; j++, ofs[1] += algn) 
                     ((double[]) rv)[j] =
                        Double.longBitsToDouble(demarshallint(buf, ofs[1], algn));
                  break;
               case ArgumentType.DICT_ENTRY1:
                  if (0 == size) {
                     // advance the type parser even on 0-size arrays.
                     Vector<Type> temp = new Vector<Type>();
                     byte[] temp2 = new byte[sigb.length-ofs[0]];
                     System.arraycopy(sigb, ofs[0], temp2, 0, temp2.length);
                     String temp3 = new String(temp2);
                     // ofs[0] gets incremented anyway. Leave one character on the stack
                     int temp4 = Marshalling.getJavaType(temp3, temp, 1) - 1;
                     ofs[0] += temp4;
                     if (Debug.debug) Debug.print(Debug.VERBOSE, "Aligned type: "+temp3+" "+temp4+" "+ofs[0]);
                  }
                  int ofssave = ofs[0];
                  long end = ofs[1]+size;
                  Vector<Object[]> entries = new Vector<Object[]>();
                  while (ofs[1] < end) {
                     ofs[0] = ofssave;
                     entries.add((Object[]) extractone(sigb, buf, ofs, true));
                  }
                  rv = new DBusMap<Object, Object>(entries.toArray(new Object[0][]));
                  break;
               default:
                  if (0 == size) {
                     // advance the type parser even on 0-size arrays.
                     Vector<Type> temp = new Vector<Type>();
                     byte[] temp2 = new byte[sigb.length-ofs[0]];
                     System.arraycopy(sigb, ofs[0], temp2, 0, temp2.length);
                     String temp3 = new String(temp2);
                     // ofs[0] gets incremented anyway. Leave one character on the stack
                     int temp4 = Marshalling.getJavaType(temp3, temp, 1) - 1;
                     ofs[0] += temp4;
                     if (Debug.debug) Debug.print(Debug.VERBOSE, "Aligned type: "+temp3+" "+temp4+" "+ofs[0]);
                  }
                  ofssave = ofs[0];
                  end = ofs[1]+size;
                  Vector<Object> contents = new Vector<Object>();
                  while (ofs[1] < end) {
                     ofs[0] = ofssave;
                     contents.add(extractone(sigb, buf, ofs, true));
                  }
                  rv = contents;
            }
            if (contained && !(rv instanceof List) && !(rv instanceof Map))
               rv = ArrayFrob.listify(rv);
            break;
         case ArgumentType.STRUCT1:
            Vector<Object> contents = new Vector<Object>();
            while (sigb[++ofs[0]] != ArgumentType.STRUCT2)
               contents.add(extractone(sigb, buf, ofs, true));
            rv = contents.toArray();
            break;
         case ArgumentType.DICT_ENTRY1:
            Object[] decontents = new Object[2];
            if (Debug.debug) Debug.print(Debug.VERBOSE, "Extracting Dict Entry ("+Hexdump.toAscii(sigb,ofs[0],sigb.length-ofs[0])+") from: "+Hexdump.toHex(buf,ofs[1],buf.length-ofs[1]));
            ofs[0]++;
            decontents[0] = extractone(sigb, buf, ofs, true);
            ofs[0]++;
            decontents[1] = extractone(sigb, buf, ofs, true);
            ofs[0]++;
            rv = decontents;
            break;
         case ArgumentType.VARIANT:
            int[] newofs = new int[] { 0, ofs[1] };
            String sig = (String) extract(ArgumentType.SIGNATURE_STRING, buf, newofs)[0];
            newofs[0] = 0;
            rv = new Variant<Object>(extract(sig, buf, newofs)[0] , sig);
            ofs[1] = newofs[1];
            break;
         case ArgumentType.STRING:
            length = (int) demarshallint(buf, ofs[1], 4);
            ofs[1] += 4;
            try {
               rv = new String(buf, ofs[1], length, "UTF-8");
            } catch (UnsupportedEncodingException UEe) {
               if (AbstractConnection.EXCEPTION_DEBUG && Debug.debug) Debug.print(UEe);
               throw new DBusException(_("System does not support UTF-8 encoding"));
            }
            ofs[1] += length + 1;
            break;
         case ArgumentType.OBJECT_PATH:
            length = (int) demarshallint(buf, ofs[1], 4);
            ofs[1] += 4;
            rv = new ObjectPath(getSource(), new String(buf, ofs[1], length));
            ofs[1] += length + 1;
            break;
         case ArgumentType.SIGNATURE:
            length = (buf[ofs[1]++] & 0xFF);
            rv = new String(buf, ofs[1], length);
            ofs[1] += length + 1;
            break;
         default: 
            throw new UnknownTypeCodeException(sigb[ofs[0]]);
      }
      if (Debug.debug) if (rv instanceof Object[])
         Debug.print(Debug.VERBOSE, "Extracted: "+Arrays.deepToString((Object[]) rv)+" (now at "+ofs[1]+")");
      else
         Debug.print(Debug.VERBOSE, "Extracted: "+rv+" (now at "+ofs[1]+")");
      return rv;
   }


Generated by  Doxygen 1.6.0   Back to index