示例#1
0
文件: parcel.c 项目: 8l/inferno
int
parcel_w_string(struct parcel *p, char *str)
{
	char16_t *s16;
	size_t s16_len;
	size_t len;

	if(str == NULL) {
		parcel_w_int32(p, -1);
		return 0;
	}
	s16_len = strlen8to16(str);
	s16 = malloc(sizeof(char16_t) * s16_len);
	strcpy8to16(s16, str, &s16_len);
	if(parcel_w_int32(p, s16_len) == -1) {
		return -1;
	}
	len = (s16_len + 1) * sizeof(char16_t);
	for(;;) {
		size_t padded = PAD_SIZE(len);
		/*printf("parcel_w_string(\"%s\"): offset %d, cap %d, size %d\n",
		  str, p->offset, p->capacity, p->size);*/
		if(p->offset + len < p->capacity) {
			// There's enough space
			memcpy(p->data + p->offset, s16, s16_len * sizeof(char16_t));
			*((char16_t *) (p->data + p->offset + len)) = 0;
			p->offset += padded;
			p->size += padded;
			if (padded != len) {
				//printf("Writing %ld bytes, padded to %ld\n", len, padded);
#if BYTE_ORDER == BIG_ENDIAN
				static const uint32_t mask[4] = {
					0x00000000, 0xffffff00, 0xffff0000, 0xff000000
				};
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
				static const uint32_t mask[4] = {
					0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff
				};
#endif
				*((uint32_t*)(p->data+p->offset+padded-4)) &= mask[padded-len];
			}
			break;
		} else {
			// Grow data and retry
			if(parcel_grow(p, padded) == -1) {
				free(s16);
				return -1;
			}
		}
	}
	free(s16);
	return 0;
}
extern char16_t * strdup8to16 (const char* s, size_t *out_len)
{
    char16_t *ret;
    size_t len;

    if (s == NULL) return NULL;

    len = strlen8to16(s);

    // no plus-one here. UTF-16 strings are not null terminated
    ret = (char16_t *) malloc (sizeof(char16_t) * len);

    return strcpy8to16 (ret, s, out_len);
}