Ejemplo n.º 1
0
static uint32 GetMMessageFieldFlattenedSize(const MMessageField * f, MBool includeHeaders)
{
   uint32 sum = includeHeaders ? (sizeof(uint32) + f->nameBytes + sizeof(uint32) + sizeof(uint32)) : 0; /* Entry name length, entry name, string, type code, entry data length */
   if (IsTypeCodeVariableSize(f->typeCode))
   {
      uint32 numItems = f->numItems;
      uint32 i; 

      sum += (numItems*sizeof(uint32));  /* because each sub-item is preceded by its byte-count */
      if (f->typeCode == B_MESSAGE_TYPE)
      {
         /* Note that NULL entries will be flattened as empty Messages, since the protocol doesn't support them directly. */
         const MMessage ** msgs = (const MMessage **) f->data;
         for (i=0; i<numItems; i++) sum += msgs[i] ? MMGetFlattenedSize(msgs[i]) : (3*sizeof(uint32));
      }
      else
      {
         const MByteBuffer ** bufs = (const MByteBuffer **) f->data;
         sum += sizeof(uint32);  /* num-items-in-array field */
         for (i=0; i<numItems; i++) sum += bufs[i] ? bufs[i]->numBytes : 0;
      }
   }
   else sum += f->numItems*f->itemSize;  /* Entry data length and data items */

   return sum;
}
Ejemplo n.º 2
0
static uint32 FlattenMMessageField(const MMessageField * f, void * outBuf)
{
   /* 3. Entry name length (4 bytes)          */
   /* 4. Entry name string (flattened String) */
   /* 5. Entry type code (4 bytes)            */
   /* 6. Entry data length (4 bytes)          */
   /* 7. Entry data (n bytes)                 */

   /* Write entry name length */
   uint32 writeOffset = 0;
   uint8 * buffer = (uint8 *) outBuf;
   {
      uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(f->nameBytes);
      WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
   }

   /* Write entry name */
   memcpy(&buffer[writeOffset], f->name, f->nameBytes); writeOffset += f->nameBytes;

   /* Write entry type code */
   {
      uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(f->typeCode);
      WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
   }

   /* Write entry data length */
   {
      uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(GetMMessageFieldFlattenedSize(f, MFalse));
      WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
   }

   /* Write entry data */
   if (IsTypeCodeVariableSize(f->typeCode))
   {
      uint32 numItems = f->numItems;
      uint32 i; 

      if (f->typeCode == B_MESSAGE_TYPE)
      {
         /* Note that NULL entries will be flattened as empty Messages, since the protocol doesn't support them directly. */
         /* Note also that for this type the number-of-items-in-array field is NOT written into the buffer (sigh)         */
         const MMessage ** msgs = (const MMessage **) f->data;
         for (i=0; i<numItems; i++) 
         {
            const MMessage * subMsg = msgs[i];
            uint32 msgSize = subMsg ? MMGetFlattenedSize(subMsg) : (3*sizeof(uint32));
            uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(msgSize);
            WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
            if (subMsg) 
            {
               MMFlattenMessage(subMsg, &buffer[writeOffset]); writeOffset += msgSize;
            }
            else
            {
               /* No MMessage present?  Then we're going to have to fake one                          */
               /* Format:  0. Protocol revision number (4 bytes, always set to CURRENT_PROTOCOL_VERSION) */
               /*          1. 'what' code (4 bytes)                                                      */
               /*          2. Number of entries (4 bytes)                                                */

               /* Write current protocol version */
               uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(CURRENT_PROTOCOL_VERSION);
               WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));

               /* Write 'what' code (zero) */
               networkByteOrder = B_HOST_TO_LENDIAN_INT32(0);
               WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));

               /* Write number of entries (zero) */
               networkByteOrder = B_HOST_TO_LENDIAN_INT32(0);
               WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
            }
         }
      }
      else
      {
         const MByteBuffer ** bufs = (const MByteBuffer **) f->data;
         int i;

         /* Write the number of items in the array */
         uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(numItems);
         WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));

         for (i=0; i<numItems; i++) 
         {
            uint32 bufSize = bufs[i] ? bufs[i]->numBytes : 0;
            uint32 networkByteOrder = B_HOST_TO_LENDIAN_INT32(bufSize);
            WriteData(buffer, &writeOffset, &networkByteOrder, sizeof(networkByteOrder));
            memcpy(&buffer[writeOffset], &bufs[i]->bytes, bufSize); writeOffset += bufSize;
         }
      }
   }
   else 
   {
      uint32 dataSize = f->numItems*f->itemSize;
      MBool doMemcpy = MTrue;
      if (BYTE_ORDER != LITTLE_ENDIAN)
      {
         doMemcpy = MFalse;
         switch(f->typeCode)
         {
            case B_BOOL_TYPE: case B_INT8_TYPE: doMemcpy = MTrue;                                   break;
            case B_POINT_TYPE:  SwapCopy(&buffer[writeOffset], f->data, f->numItems*2, sizeof(float)); break;
            case B_RECT_TYPE:   SwapCopy(&buffer[writeOffset], f->data, f->numItems*4, sizeof(float)); break;
            default:            SwapCopy(&buffer[writeOffset], f->data, f->numItems, f->itemSize);     break;
         }
      }
      if (doMemcpy) memcpy(&buffer[writeOffset], f->data, dataSize);
      writeOffset += dataSize;
   }

   return writeOffset;
}
Ejemplo n.º 3
0
static void PrintMMessageToStreamAux(const MMessage * msg, FILE * file, int indent)
{
   /* Make a pretty type code string */
   char buf[5];
   MakePrettyTypeCodeString(msg->what, buf);

   fprintf(file, "MMessage:  msg=%p, what='%s' ("INT32_FORMAT_SPEC"), entryCount="INT32_FORMAT_SPEC", flatSize="UINT32_FORMAT_SPEC"\n", msg, buf, msg->what, msg->numFields, MMGetFlattenedSize(msg));

   indent += 2;
   {
      MMessageField * f = msg->firstField;
      while(f)
      {
         PrintMMessageFieldToStream(f, file, indent);
         f = f->nextField;
      }
   }
}
Ejemplo n.º 4
0
static void PrintMMessageToStreamAux(const MMessage * msg, int indent)
{
   /* Make a pretty type code string */
   char buf[5];
   MakePrettyTypeCodeString(msg->what, buf);

   dlog(DEBUG1, "MMessage:  msg=%p, what='%s' (%li/0x%lx), entryCount=%li, flatSize=%lu", msg, buf, msg->what, msg->what, msg->numFields, MMGetFlattenedSize(msg));

   indent += 2;
   {
      MMessageField * f = msg->firstField;
      while(f)
      {
         PrintMMessageFieldToStream(f, indent);
         f = f->nextField;
      }
   }
}