diff --git a/src/Makefile.am b/src/Makefile.am index 445f3c8..8a92f49 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,8 +40,13 @@ google/protobuf/compiler/c/c_file.h \ google/protobuf/compiler/c/c_field.h \ google/protobuf/compiler/c/c_message.h \ google/protobuf/compiler/c/c_generator.h \ -google/protobuf/compiler/c/c_bytes_field.h +google/protobuf/compiler/c/c_bytes_field.h \ +google/protobuf-c/protobuf-c-data-buffer.h \ +google/protobuf-c/gskrbtreemacros.h \ +google/protobuf-c/gsklistmacros.h protobufcinclude_HEADERS = \ google/protobuf-c/protobuf-c.h \ -google/protobuf-c/protobuf-c-private.h +google/protobuf-c/protobuf-c-private.h \ +google/protobuf-c/protobuf-c-dispatch.h \ +google/protobuf-c/protobuf-c-rpc.h diff --git a/src/google/protobuf-c/protobuf-c-dispatch.c b/src/google/protobuf-c/protobuf-c-dispatch.c index d057b77..2eeea64 100644 --- a/src/google/protobuf-c/protobuf-c-dispatch.c +++ b/src/google/protobuf-c/protobuf-c-dispatch.c @@ -239,8 +239,8 @@ allocate_change_index (RealDispatch *d) { ProtobufCAllocator *allocator = d->allocator; unsigned new_size = d->changes_alloced * 2; - ProtobufC_FDNotify *n = ALLOC (new_size * sizeof (ProtobufC_FDNotify)); - memcpy (n, d->base.changes, d->changes_alloced * sizeof (ProtobufC_FDNotify)); + ProtobufC_FDNotifyChange *n = ALLOC (new_size * sizeof (ProtobufC_FDNotifyChange)); + memcpy (n, d->base.changes, d->changes_alloced * sizeof (ProtobufC_FDNotifyChange)); FREE (d->base.changes); d->base.changes = n; d->changes_alloced = new_size; @@ -299,6 +299,7 @@ protobuf_c_dispatch_watch_fd (ProtobufCDispatch *dispatch, RealDispatch *d = (RealDispatch *) dispatch; unsigned f = fd; /* avoid tiring compiler warnings: "comparison of signed versus unsigned" */ unsigned nd_ind, change_ind; + unsigned old_events; #if DEBUG_DISPATCH fprintf (stderr, "dispatch: watch_fd: %d, %s%s\n", fd, @@ -314,9 +315,11 @@ protobuf_c_dispatch_watch_fd (ProtobufCDispatch *dispatch, { if (callback != NULL) nd_ind = d->fd_map[f].notify_desired_index = allocate_notifies_desired_index (d); + old_events = 0; } else { + old_events = dispatch->notifies_desired[d->fd_map[f].notify_desired_index].events; if (callback == NULL) deallocate_notify_desired_index (d, f); else @@ -325,16 +328,24 @@ protobuf_c_dispatch_watch_fd (ProtobufCDispatch *dispatch, if (callback == NULL) { if (d->fd_map[f].change_index == -1) - d->fd_map[f].change_index = allocate_change_index (d); - change_ind = d->fd_map[f].change_index; + { + change_ind = d->fd_map[f].change_index = allocate_change_index (d); + dispatch->changes[change_ind].old_events = old_events; + } + else + change_ind = d->fd_map[f].change_index; d->base.changes[change_ind].fd = f; d->base.changes[change_ind].events = 0; return; } assert (callback != NULL && events != 0); if (d->fd_map[f].change_index == -1) - d->fd_map[f].change_index = allocate_change_index (d); - change_ind = d->fd_map[f].change_index; + { + change_ind = d->fd_map[f].change_index = allocate_change_index (d); + dispatch->changes[change_ind].old_events = old_events; + } + else + change_ind = d->fd_map[f].change_index; d->base.changes[change_ind].fd = fd; d->base.changes[change_ind].events = events; @@ -407,6 +418,11 @@ protobuf_c_dispatch_dispatch (ProtobufCDispatch *dispatch, } } + /* clear changes */ + for (i = 0; i < dispatch->n_changes; i++) + d->fd_map[dispatch->changes[i].fd].change_index = -1; + dispatch->n_changes = 0; + /* handle idle functions */ while (d->first_idle != NULL) { @@ -704,8 +720,8 @@ void protobuf_c_dispatch_destroy_default (void) { if (def) { - ProtobufCDispatch *kill = def; + ProtobufCDispatch *to_kill = def; def = NULL; - protobuf_c_dispatch_free (kill); + protobuf_c_dispatch_free (to_kill); } } diff --git a/src/google/protobuf-c/protobuf-c.c b/src/google/protobuf-c/protobuf-c.c index 1da81f4..3187f42 100644 --- a/src/google/protobuf-c/protobuf-c.c +++ b/src/google/protobuf-c/protobuf-c.c @@ -247,7 +247,8 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field, return rv + uint32_size (*(const uint32_t *) member); case PROTOBUF_C_TYPE_STRING: { - size_t len = strlen (*(char * const *) member); + const char *str = *(char * const *) member; + size_t len = str ? strlen (str) : 0; return rv + uint32_size (len) + len; } case PROTOBUF_C_TYPE_BYTES: @@ -258,7 +259,8 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field, //case PROTOBUF_C_TYPE_GROUP: case PROTOBUF_C_TYPE_MESSAGE: { - size_t subrv = protobuf_c_message_get_packed_size (*(ProtobufCMessage * const *) member); + const ProtobufCMessage *msg = * (ProtobufCMessage * const *) member; + size_t subrv = msg ? protobuf_c_message_get_packed_size (msg) : 0; return rv + uint32_size (subrv) + subrv; } } @@ -501,10 +503,18 @@ static inline size_t boolean_pack (protobuf_c_boolean value, uint8_t *out) } static inline size_t string_pack (const char * str, uint8_t *out) { - size_t len = strlen (str); - size_t rv = uint32_pack (len, out); - memcpy (out + rv, str, len); - return rv + len; + if (str == NULL) + { + out[0] = 0; + return 1; + } + else + { + size_t len = strlen (str); + size_t rv = uint32_pack (len, out); + memcpy (out + rv, str, len); + return rv + len; + } } static inline size_t binary_data_pack (const ProtobufCBinaryData *bd, uint8_t *out) { @@ -517,11 +527,19 @@ static inline size_t binary_data_pack (const ProtobufCBinaryData *bd, uint8_t *o static inline size_t prefixed_message_pack (const ProtobufCMessage *message, uint8_t *out) { - size_t rv = protobuf_c_message_pack (message, out + 1); - uint32_t rv_packed_size = uint32_size (rv); - if (rv_packed_size != 1) - memmove (out + rv_packed_size, out + 1, rv); - return uint32_pack (rv, out) + rv; + if (message == NULL) + { + out[0] = 0; + return 1; + } + else + { + size_t rv = protobuf_c_message_pack (message, out + 1); + uint32_t rv_packed_size = uint32_size (rv); + if (rv_packed_size != 1) + memmove (out + rv_packed_size, out + 1, rv); + return uint32_pack (rv, out) + rv; + } } /* wire-type will be added in required_field_pack() */ @@ -757,11 +775,12 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field, break; case PROTOBUF_C_TYPE_STRING: { - size_t sublen = strlen (*(char * const *) member); + const char *str = *(char * const *) member; + size_t sublen = str ? strlen (str) : 0; scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; rv += uint32_pack (sublen, scratch + rv); buffer->append (buffer, rv, scratch); - buffer->append (buffer, sublen, *(uint8_t * const *)member); + buffer->append (buffer, sublen, (const uint8_t *) str); rv += sublen; break; } @@ -784,9 +803,12 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field, size_t sublen; ProtobufCBufferSimple simple_buffer = PROTOBUF_C_BUFFER_SIMPLE_INIT (simple_buffer_scratch); + const ProtobufCMessage *msg = *(ProtobufCMessage * const *) member; scratch[0] |= PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED; - sublen = protobuf_c_message_pack_to_buffer (*(ProtobufCMessage * const *) member, - &simple_buffer.base); + if (msg == NULL) + sublen = 0; + else + sublen = protobuf_c_message_pack_to_buffer (msg, &simple_buffer.base); rv += uint32_pack (sublen, scratch + rv); buffer->append (buffer, rv, scratch); buffer->append (buffer, sublen, simple_buffer.data);