Example #1
0
unsigned int _pSLpack_compute_size (char *format)
{
   unsigned int n;

   n = 0;
   (void) compute_size_for_format (format, &n);
   return n;
}
Example #2
0
File: slpack.c Project: parke/slang
SLstrlen_Type _pSLpack_compute_size (char *format)
{
   SLstrlen_Type n;

   n = 0;
   (void) compute_size_for_format (format, &n);
   return n;
}
Example #3
0
void _pSLpack_pad_format (char *format)
{
   unsigned int len, max_len;
   Format_Type ft;
   char *buf, *b;

   check_native_byte_order ();

   /* Just check the syntax */
   if (-1 == compute_size_for_format (format, &max_len))
     return;

   /* This should be sufficient to handle any needed xyy padding characters.
    * I cannot see how this will be overrun
    */
   max_len = 4 * (strlen (format) + 1);
   if (NULL == (buf = SLmalloc (max_len + 1)))
     return;

   b = buf;
   len = 0;
   while (1 == parse_a_format (&format, &ft))
     {
	struct { char a; short b; } s_h;
	struct { char a; int b; } s_i;
	struct { char a; long b; } s_l;
	struct { char a; float b; } s_f;
	struct { char a; double b; } s_d;
	unsigned int pad;

	if (ft.repeat == 0)
	  continue;

	if (ft.data_type == 0)
	  {			       /* pad */
	     sprintf (b, "x%u", ft.repeat);
	     b += strlen (b);
	     len += ft.repeat;
	     continue;
	  }

	switch (ft.data_type)
	  {
	   default:
	   case SLANG_STRING_TYPE:
	   case SLANG_BSTRING_TYPE:
	   case SLANG_CHAR_TYPE:
	   case SLANG_UCHAR_TYPE:
	     pad = 0;
	     break;

	   case SLANG_SHORT_TYPE:
	   case SLANG_USHORT_TYPE:
	     pad = ((unsigned int) ((char *)&s_h.b - (char *)&s_h.a));
	     break;

	   case SLANG_INT_TYPE:
	   case SLANG_UINT_TYPE:
	     pad = ((unsigned int) ((char *)&s_i.b - (char *)&s_i.a));
	     break;

	   case SLANG_LONG_TYPE:
	   case SLANG_ULONG_TYPE:
	     pad = ((unsigned int) ((char *)&s_l.b - (char *)&s_l.a));
	     break;

	   case SLANG_FLOAT_TYPE:
	     pad = ((unsigned int) ((char *)&s_f.b - (char *)&s_f.a));
	     break;

	   case SLANG_DOUBLE_TYPE:
	     pad = ((unsigned int) ((char *)&s_d.b - (char *)&s_d.a));
	     break;
	  }

	/* Pad to a length that is an integer multiple of pad. */
	if (pad)
	  pad = pad * ((len + pad - 1)/pad) - len;

	if (pad)
	  {
	     sprintf (b, "x%u", pad);
	     b += strlen (b);
	     len += pad;
	  }

	*b++ = ft.format_type;
	if (ft.repeat > 1)
	  {
	     sprintf (b, "%u", ft.repeat);
	     b += strlen (b);
	  }

	len += ft.repeat * ft.sizeof_type;
     }
   *b = 0;

   (void) SLang_push_malloced_string (buf);
}
Example #4
0
void _pSLunpack (char *format, SLang_BString_Type *bs)
{
   Format_Type ft;
   unsigned char *b;
   unsigned int len;
   unsigned int num_bytes;

   check_native_byte_order ();

   if (-1 == compute_size_for_format (format, &num_bytes))
     return;

   b = SLbstring_get_pointer (bs, &len);
   if (b == NULL)
     return;

   if (len < num_bytes)
     {
	_pSLang_verror (SL_INVALID_PARM,
		      "unpack format %s is too large for input string",
		      format);
	return;
     }

   while (1 == parse_a_format (&format, &ft))
     {
	char *str, *s;

	if (ft.repeat == 0)
	  continue;

	if (ft.data_type == 0)
	  {			       /* skip padding */
	     b += ft.repeat;
	     continue;
	  }

	if (ft.is_scalar)
	  {
	     SLang_Array_Type *at;
	     SLindex_Type dims;

	     if (ft.repeat == 1)
	       {
		  SLang_Class_Type *cl;

		  cl = _pSLclass_get_class (ft.data_type);
		  memcpy ((char *)cl->cl_transfer_buf, (char *)b, ft.sizeof_type);
		  if (ft.byteorder != NATIVE_ORDER)
		    byteswap (ft.byteorder, (unsigned char *)cl->cl_transfer_buf, ft.sizeof_type, 1);

		  if (-1 == (cl->cl_apush (ft.data_type, cl->cl_transfer_buf)))
		    return;
		  b += ft.sizeof_type;
		  continue;
	       }

	     dims = (SLindex_Type) ft.repeat;
	     at = SLang_create_array (ft.data_type, 0, NULL, &dims, 1);
	     if (at == NULL)
	       return;

	     num_bytes = ft.repeat * ft.sizeof_type;
	     memcpy ((char *)at->data, (char *)b, num_bytes);
	     if (ft.byteorder != NATIVE_ORDER)
	       byteswap (ft.byteorder, (unsigned char *)at->data, ft.sizeof_type, ft.repeat);

	     if (-1 == SLang_push_array (at, 1))
	       return;

	     b += num_bytes;
	     continue;
	  }
	
	/* string type: s, S, or Z */
	if (ft.format_type == 's')
	  len = ft.repeat;
	else
	  len = get_unpadded_strlen ((char *)b, ft.pad, ft.repeat);

	str = SLmalloc (len + 1);
	if (str == NULL)
	  return;
	memcpy ((char *) str, (char *)b, len);
	str [len] = 0;

	/* Avoid a bstring if possible */
	s = SLmemchr (str, 0, len);
	if (s == NULL)
	  {
	     if (-1 == SLang_push_malloced_string (str))
	       return;
	  }
	else
	  {
	     SLang_BString_Type *new_bs;

	     new_bs = SLbstring_create_malloced ((unsigned char *)str, len, 1);
	     if (new_bs == NULL)
	       return;

	     if (-1 == SLang_push_bstring (new_bs))
	       {
		  SLfree (str);
		  return;
	       }
	     SLbstring_free (new_bs);
	  }

	b += ft.repeat;
     }
}
Example #5
0
static SLang_BString_Type *
pack_according_to_format (char *format, unsigned int nitems)
{
   unsigned int size, num;
   unsigned char *buf, *b;
   SLang_BString_Type *bs;
   Format_Type ft;

   buf = NULL;

   if (-1 == compute_size_for_format (format, &size))
     goto return_error;

   if (NULL == (buf = (unsigned char *) SLmalloc (size + 1)))
     goto return_error;

   b = buf;

   while (1 == parse_a_format (&format, &ft))
     {
	unsigned char *ptr;
	unsigned int repeat;

	repeat = ft.repeat;
	if (ft.data_type == 0)
	  {
	     memset ((char *) b, ft.pad, repeat);
	     b += repeat;
	     continue;
	  }

	if (ft.is_scalar)
	  {
	     unsigned char *bstart;
	     num = repeat;

	     bstart = b;
	     while (repeat != 0)
	       {
		  unsigned int nelements;
		  SLang_Array_Type *at;

		  if (nitems == 0)
		    {
		       _pSLang_verror (SL_INVALID_PARM,
				     "Not enough items for pack format");
		       goto return_error;
		    }

		  if (-1 == SLang_pop_array_of_type (&at, ft.data_type))
		    goto return_error;

		  nelements = at->num_elements;
		  if (repeat < nelements)
		    nelements = repeat;
		  repeat -= nelements;

		  nelements = nelements * ft.sizeof_type;
		  memcpy ((char *)b, (char *)at->data, nelements);

		  b += nelements;
		  SLang_free_array (at);
		  nitems--;
	       }

	     if (ft.byteorder != NATIVE_ORDER)
	       byteswap (ft.byteorder, bstart, ft.sizeof_type, num);

	     continue;
	  }

	/* Otherwise we have a string */
	if (-1 == SLang_pop_bstring (&bs))
	  goto return_error;

	ptr = SLbstring_get_pointer (bs, &num);
	if (repeat < num) num = repeat;
	memcpy ((char *)b, (char *)ptr, num);
	b += num;
	repeat -= num;
	if ((repeat == 0) && (ft.format_type == 'z'))
	  {
	     if (num) *(b-1) = 0;
	  }
	else memset ((char *)b, ft.pad, repeat);
	SLbstring_free (bs);
	b += repeat;
	nitems--;
     }

   *b = 0;
   bs = SLbstring_create_malloced (buf, size, 0);
   if (bs == NULL)
     goto return_error;

   SLdo_pop_n (nitems);
   return bs;

   return_error:
   SLdo_pop_n (nitems);
   if (buf != NULL)
     SLfree ((char *) buf);

   return NULL;
}