Example #1
0
static config_file_t *config_file_new_internal(
      const char *path, unsigned depth, config_file_cb_t *cb)
{
   RFILE              *file = NULL;
   struct config_file *conf = (struct config_file*)malloc(sizeof(*conf));
   if (!conf)
      return NULL;

   conf->path                     = NULL;
   conf->entries                  = NULL;
   conf->tail                     = NULL;
   conf->last                     = NULL;
   conf->includes                 = NULL;
   conf->include_depth            = 0;
   conf->guaranteed_no_duplicates = false ;

   if (!path || !*path)
      return conf;

   if (path_is_directory(path))
      goto error;

   conf->path          = strdup(path);
   if (!conf->path)
      goto error;

   conf->include_depth = depth;
   file                = filestream_open(path,
         RETRO_VFS_FILE_ACCESS_READ,
         RETRO_VFS_FILE_ACCESS_HINT_NONE);

   if (!file)
   {
      free(conf->path);
      goto error;
   }

   while (!filestream_eof(file))
   {
      char *line                     = NULL;
      struct config_entry_list *list = (struct config_entry_list*)malloc(sizeof(*list));

      if (!list)
      {
         config_file_free(conf);
         filestream_close(file);
         return NULL;
      }

      list->readonly  = false;
      list->key       = NULL;
      list->value     = NULL;
      list->next      = NULL;

      line            = filestream_getline(file);

      if (!line)
      {
         free(list);
         continue;
      }

      if (*line && parse_line(conf, list, line, cb))
      {
         if (conf->entries)
            conf->tail->next = list;
         else
            conf->entries = list;

         conf->tail = list;

         if (cb != NULL && list->key != NULL && list->value != NULL)
            cb->config_file_new_entry_cb(list->key, list->value) ;
      }

      free(line);

      if (list != conf->tail)
         free(list);
   }

   filestream_close(file);

   return conf;

error:
   free(conf);

   return NULL;
}
int rfeof(RFILE* stream)
{
   return filestream_eof(stream);
}
Example #3
0
/* Parses log file referenced by runtime_log->path.
 * Does nothing if log file does not exist. */
static void runtime_log_read_file(runtime_log_t *runtime_log)
{
   unsigned runtime_hours = 0;
   unsigned runtime_minutes = 0;
   unsigned runtime_seconds = 0;
   
   unsigned last_played_year = 0;
   unsigned last_played_month = 0;
   unsigned last_played_day = 0;
   unsigned last_played_hour = 0;
   unsigned last_played_minute = 0;
   unsigned last_played_second = 0;
   
   RtlJSONContext context = {0};
   RFILE *file = NULL;
   int ret = 0;
   
   /* Check if log file exists */
   if (!filestream_exists(runtime_log->path))
      return;
   
   /* Attempt to open log file */
   file = filestream_open(runtime_log->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE);
   
   if (!file)
   {
      RARCH_ERR("Failed to open runtime log file: %s\n", runtime_log->path);
      return;
   }
   
   /* Initialise JSON parser */
   context.runtime_string = NULL;
   context.last_played_string = NULL;
   context.parser = JSON_Parser_Create(NULL);
   context.file = file;
   
   if (!context.parser)
   {
      RARCH_ERR("Failed to create JSON parser.\n");
      goto end;
   }
   
   /* Configure parser */
   JSON_Parser_SetAllowBOM(context.parser, JSON_True);
   JSON_Parser_SetStringHandler(context.parser, &RtlJSONStringHandler);
   JSON_Parser_SetObjectMemberHandler(context.parser, &RtlJSONObjectMemberHandler);
   JSON_Parser_SetUserData(context.parser, &context);
   
   /* Read file */
   while (!filestream_eof(file))
   {
      /* Runtime log files are tiny - use small chunk size */
      char chunk[128] = {0};
      int64_t length = filestream_read(file, chunk, sizeof(chunk));
      
      /* Error checking... */
      if (!length && !filestream_eof(file))
      {
         RARCH_ERR("Failed to read runtime log file: %s\n", runtime_log->path);
         JSON_Parser_Free(context.parser);
         goto end;
      }
      
      /* Parse chunk */
      if (!JSON_Parser_Parse(context.parser, chunk, length, JSON_False))
      {
         RARCH_ERR("Error parsing chunk of runtime log file: %s\n---snip---\n%s\n---snip---\n", runtime_log->path, chunk);
         RtlJSONLogError(&context);
         JSON_Parser_Free(context.parser);
         goto end;
      }
   }
   
   /* Finalise parsing */
   if (!JSON_Parser_Parse(context.parser, NULL, 0, JSON_True))
   {
      RARCH_WARN("Error parsing runtime log file: %s\n", runtime_log->path);
      RtlJSONLogError(&context);
      JSON_Parser_Free(context.parser);
      goto end;
   }
   
   /* Free parser */
   JSON_Parser_Free(context.parser);
   
   /* Process string values read from JSON file */
   
   /* Runtime */
   ret = 0;
   if (!string_is_empty(context.runtime_string))
      ret = sscanf(context.runtime_string, LOG_FILE_RUNTIME_FORMAT_STR,
                  &runtime_hours, &runtime_minutes, &runtime_seconds);
   
   if (ret != 3)
   {
      RARCH_ERR("Runtime log file - invalid 'runtime' entry detected: %s\n", runtime_log->path);
      goto end;
   }
   
   /* Last played */
   ret = 0;
   if (!string_is_empty(context.last_played_string))
      ret = sscanf(context.last_played_string, LOG_FILE_LAST_PLAYED_FORMAT_STR,
                  &last_played_year, &last_played_month, &last_played_day,
                  &last_played_hour, &last_played_minute, &last_played_second);
   
   if (ret != 6)
   {
      RARCH_ERR("Runtime log file - invalid 'last played' entry detected: %s\n", runtime_log->path);
      goto end;
   }
   
   /* If we reach this point then all is well
    * > Assign values to runtime_log object */
   runtime_log->runtime.hours = runtime_hours;
   runtime_log->runtime.minutes = runtime_minutes;
   runtime_log->runtime.seconds = runtime_seconds;
   
   runtime_log->last_played.year = last_played_year;
   runtime_log->last_played.month = last_played_month;
   runtime_log->last_played.day = last_played_day;
   runtime_log->last_played.hour = last_played_hour;
   runtime_log->last_played.minute = last_played_minute;
   runtime_log->last_played.second = last_played_second;
   
end:
   
   /* Clean up leftover strings */
   if (context.runtime_string)
      free(context.runtime_string);
   if (context.last_played_string)
      free(context.last_played_string);
   
   /* Close log file */
   filestream_close(file);
}