2014年1月28日火曜日

ArduinoをWindowsにつないでGmailの未読メールの数を表示する (2)

前回記事
の続き.前回の記事ではlibcurlを使って,未読メール一覧を取得してchar型配列に格納するところまでやった.今回の記事では,文字列処理を行って未読メール数を取得するところまでをみていく.

以下にソースを示す.

#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>

#include <curl/curl.h>
#include <string.h>

typedef struct
{
    char* memory;
    size_t size;
} Memory;

size_t write_memory_callback(void* ptr, size_t size, size_t nmemb, void* data)
{
    if (size * nmemb == 0){
        return 0;
 }
    size_t realsize = size * nmemb;
    Memory* mem = (Memory*)data;
    
    mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1);
    if (mem->memory) {
        memcpy(&(mem->memory[mem->size]), ptr, realsize);
        mem->size += realsize;
        mem->memory[mem->size] = 0;
    }

    return realsize;
}

int main(void)
{
    CURL *curl;
    CURLcode res;
    char* start;
    char* end;
    //未読数が囲まれているタグを定義
    char start_str[] = "<fullcount>";
    char end_str[] = "</fullcount>";
    //タグ部分の切り出し
    char unread[100];
    Memory* mem = (Memory* )malloc(sizeof(Memory*));
    int startposition,endposition;
 int unreadNum = 0;
    
 while(1){
  mem->size = 0;
  mem->memory = NULL;
  curl = curl_easy_init();
 
  if(curl)
  {
       curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE);
       //ユーザ名・パスワード設定
       curl_easy_setopt(curl, CURLOPT_USERPWD, "username:password");
       curl_easy_setopt(curl, CURLOPT_URL,"https://mail.google.com/mail/feed/atom");
       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback);
       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)mem);

       res = curl_easy_perform(curl);

       //エラーチェック 
       if(res != CURLE_OK){
          fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
    }
       //クリーンアップ
       curl_easy_cleanup(curl);
  }

  start = strstr(mem->memory,start_str); 
  end = strstr(mem->memory,end_str);
  startposition = (int)(start-mem->memory);
  endposition = (int)(end-mem->memory);
  strncpy_s(unread, mem->memory+startposition,endposition-startposition);
  
  //数字の抜き出し
  int arrayIndex = 0;
  char unreadNumStr[10]={0};
  for(int i=0; i<strlen(unread); i++){
   if(isalnum((int)unread[i]) != 0){
    if(isalpha((int)unread[i]) == 0){
     unreadNumStr[arrayIndex] = unread[i];
     arrayIndex++;
    }
   }
  }

  unreadNum = atoi(unreadNumStr);
  printf("%d\n",unreadNum);
 }
    return 0;
}

簡単に説明すると,

1. strstr関数を使って,<fullcount>,</fullcount>を探し,そこから切り出しを始める.
 例えば,処理前の文字列が<fullcount>1</fullcount>asdfaklsufkashdf.....
だとすると,
startは<fullcount>1</fullcount>asdfaklsufkashdf.....
となり,
endは</fullcount>asdfaklsufkashdf.....
となる.この操作によって,欲しい文字列<fullcount>1</fullcount>の始まりと終わりのポインタがわかる.

2. 何文字目から何文字目までを切り出すのかを明確にする

3. strncpy_s関数を使って文字列を切り出す.
コピーのはじめと終わりの位置を指定してコピーすることで新しい文字列に目的の文字列を切り出します.

4. isalnum , isalpha関数を使って数字部分のみを取り出す.

5. atoi関数を使って文字列を数値に変換する.

という流れになっている.

0 件のコメント:

コメントを投稿