int parcel_w_string(struct parcel *p, const char *str) { gunichar2 *gs16; glong gs16_len; size_t len; size_t gs16_size; if (str == NULL) { parcel_w_int32(p, -1); return 0; } gs16 = g_utf8_to_utf16(str, -1, NULL, &gs16_len, NULL); if (parcel_w_int32(p, gs16_len) == -1) return -1; gs16_size = gs16_len * sizeof(char16_t); len = gs16_size + sizeof(char16_t); for (;;) { size_t padded = PAD_SIZE(len); if (p->offset + len < p->capacity) { /* There's enough space */ memcpy(p->data + p->offset, gs16, gs16_size); *((char16_t *) (void *) (p->data + p->offset + gs16_size)) = 0; p->offset += padded; p->size += padded; if (padded != len) { #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 *) (void *) (p->data + p->offset - 4)) &= mask[padded - len]; } break; } else { /* Grow data and retry */ parcel_grow(p, padded); } } g_free(gs16); return 0; }
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; }
int parcel_w_int32(struct parcel *p, int32_t val) { for (;;) { if (p->offset + sizeof(int32_t) < p->capacity) { /* There's enough space */ *((int32_t *) (void *) (p->data + p->offset)) = val; p->offset += sizeof(int32_t); p->size += sizeof(int32_t); break; } else { /* Grow data and retry */ parcel_grow(p, sizeof(int32_t)); } } return 0; }
int parcel_w_int32(struct parcel *p, int32_t val) { for (;;) { DBG("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n", val, (int) p->offset, (int) p->capacity, (int) p->size); if (p->offset + sizeof(int32_t) < p->capacity) { /* There's enough space */ *((int32_t *) (p->data + p->offset)) = val; p->offset += sizeof(int32_t); p->size += sizeof(int32_t); break; } else { /* Grow data and retry */ parcel_grow(p, sizeof(int32_t)); } } return 0; }
int parcel_w_int32(struct parcel *p, int32_t val) { for(;;) { /* printf("parcel_w_int32(%d): offset = %d, cap = %d, size = %d\n", val, p->offset, p->capacity, p->size);*/ if(p->offset + sizeof(int32_t) < p->capacity) { // There's enough space *((int32_t *) (p->data + p->offset)) = val; p->offset += sizeof(int32_t); p->size += sizeof(int32_t); break; } else { // Grow data and retry if(parcel_grow(p, sizeof(int32_t)) == -1) { return -1; } } } return 0; }
int parcel_w_raw(struct parcel *p, const void *data, size_t len) { if (data == NULL) { parcel_w_int32(p, -1); return 0; } parcel_w_int32(p, len); for (;;) { if (p->offset + len < p->capacity) { /* There's enough space */ memcpy(p->data + p->offset, data, len); p->offset += len; p->size += len; break; } else { /* Grow data and retry */ parcel_grow(p, len); } } return 0; }