Ejemplo n.º 1
0
static void roadmap_http_async_has_data_cb (RoadMapIO *io) {

	HttpAsyncContext *context = (HttpAsyncContext *)io->context;
   RoadMapHttpAsyncCallbacks *callbacks = context->callbacks;
   char buffer[ROADMAP_HTTP_MAX_CHUNK + 1];

   int res;

   if (!context->is_parsing_headers) {
		int read_size = context->content_length - context->download_size_current;
		if (read_size > ROADMAP_HTTP_MAX_CHUNK) {
			read_size = ROADMAP_HTTP_MAX_CHUNK;
		}
		res = roadmap_io_read(io, buffer, read_size);
		if (res < 0) {
         roadmap_log(ROADMAP_ERROR, "roadmap_http_async_has_data_cb(): error receiving http data (%d/%d)", context->download_size_current,
            context->content_length);
		}
   } else {
      /* we're still parsing headers and may have left overs to append */
      int leftover_size = strlen(context->header_buffer);
      res = roadmap_io_read(io, buffer + leftover_size, ROADMAP_HTTP_MAX_CHUNK - leftover_size);
      if (res > 0) {
         if (leftover_size) {
         	memcpy(buffer, context->header_buffer, leftover_size);
         	context->header_buffer[0] = '\0';
         }
         res = roadmap_http_async_decode_header(context, buffer, res + leftover_size);
         if ( context->is_parsing_headers ) {
            if ( res == 0 ) { /* Need more header data - keep listening.
                               * Other res values are handled further (actually can't be positive in this state ... */
               if (strlen(buffer) && (strlen(buffer) < sizeof(context->header_buffer)))
                              strcpy(context->header_buffer, buffer);
               return;
            }
         } else {
            /* we just finished parsing the headers - check size callback for the received content length */
            if (!callbacks->size(context->cb_context, context->content_length)) {
               res = -1;
            }
            if ( res == 0 ) { /* Size is Ok and there is no download data to process after checking the headers - keep listening
                               * Other res values will be handled further */
               return;
            }
         }
      } else if (res < 0) {
         roadmap_log (ROADMAP_ERROR, "roadmap_http_async_has_data_cb(): error receiving http header (%d)", leftover_size);
		} else  /* res == 0 */ {
         roadmap_log (ROADMAP_ERROR, "roadmap_http_async_has_data_cb(): error receiving http header. Read zero bytes. (%d)", leftover_size );
         res = -1;
      }
   }

   if (res > 0) {
      context->download_size_current += res;
      callbacks->progress (context->cb_context, buffer, res);
   }

   if ((res <= 0) || (context->download_size_current >= context->content_length)) {
      roadmap_main_remove_input(io);
      roadmap_io_close(&context->io);

      if ( ( res >= 0 ) && ( context->content_length > 0 ) && ( context->download_size_current == context->content_length ) ) {
         callbacks->done(context->cb_context, context->last_modified_buffer);
      }
      else {
         roadmap_log (ROADMAP_WARNING, "Http download error. Res: %d. Content length: %d. Downloaded: %d",
                                             res, context->content_length, context->download_size_current );
         if ( context->content_length > 0 && context->download_size_current > context->content_length ) {
            roadmap_log (ROADMAP_ERROR, "Too many bytes for http download (%d/%d)", context->download_size_current, context->content_length);
         }
         callbacks->error (context->cb_context, 0, "roadmap_http_async_has_data_cb() failed" );
      }
      /*
       * Context deallocation. Be aware to NULL references in "error" and "done" callbacks
       */
      free (context);
   }
}
Ejemplo n.º 2
0
int roadmap_input (RoadMapInputContext *context) {

   int result;
   int received;
   int is_binary = context->is_binary;

   char *line_start;
   char *data_end;


   /* Receive more data if available. */

   if (context->cursor < (int)sizeof(context->data) - 1) {

      received =
         roadmap_io_read (context->io,
                          context->data + context->cursor,
                          sizeof(context->data) - context->cursor - 1);

      if (received < 0) {

         /* We lost that connection. */
         roadmap_log (ROADMAP_INFO, "lost %s", context->title);
         return -1;

      } else {
         context->cursor += received;
      }
   }

   if (!is_binary) context->data[context->cursor] = 0;


   /* Remove the leading end of line characters, if any.
    * We do the same in between lines (see end of loop).
    */
   line_start = context->data;
   data_end   = context->data + context->cursor;

   if (!is_binary) {
      while ((line_start < data_end) && (*line_start < ' ')) ++line_start;
   }


   /* process each complete line in this buffer. */

   result = 0;

   while (line_start < data_end) {

      int cur_res;
      char *line_end = data_end;

      if (!is_binary) {
         char *new_line;
         char *carriage_return;


         /* Find the first end of line character coming after this line. */

         new_line = strchr (line_start, '\n');
         carriage_return = strchr (line_start, '\r');

         if (new_line == NULL) {
            line_end = carriage_return;
         } else if (carriage_return == NULL) {
            line_end = new_line;
         } else if (new_line < carriage_return) {
            line_end = new_line;
         } else {
            line_end = carriage_return;
         }

         if (line_end == NULL) {

            /* This line is not complete: shift the remaining data
             * to the beginning of the buffer and then stop.
             */

            if (line_start + strlen(line_start) != data_end) {
               roadmap_log (ROADMAP_WARNING, "GPS input has null characters.");
               roadmap_input_shift_to_next_line
                  (context, line_start + strlen(line_start) + 1);

               line_start = context->data;
               data_end   = context->data + context->cursor;
               while ((line_start < data_end) && (*line_start < ' ')) ++line_start;
               continue;
            } else {
               roadmap_input_shift_to_next_line (context, line_start);
            }
            return result;
         }

         /* Process this line. */

         *line_end = 0; /* Separate this line from the next. */
      }

      if (context->logger != NULL) {
         context->logger (line_start);
      }

      cur_res = context->decoder (context->user_context,
                                  context->decoder_context, line_start,
                                  line_end - line_start);

      if (is_binary) {
         line_start += cur_res;
         context->cursor -= cur_res;

         if (context->cursor) {
            memmove (context->data, line_start, context->cursor);
         }

         return 0;
      }

      result |= cur_res;

      /* Move to the next line. */

      line_start = line_end + 1;
      while ((*line_start < ' ') && (line_start < data_end)) ++line_start;
   }


   context->cursor = 0; /* The buffer is now empty. */
   return result;
}