Arduino IDEでのIniファイル読込

ESP32やESP8266の小物を作っていると、WiFi導入部は毎回同じ記述になってきました。
しかし、サーバーアプリなどはhostnameを別物にしないと名前解決できません。
とは言えソースコードにhostnameを直接埋めると、混乱するし・・・・・
てなわけでinifile形式でデータを読み込むライブラリを作成しました。

#必要な機能
　SPIFFS / FS等のファイルアクセスの設定
　FTPは推奨

#使い方
ソースはこんな風にします。　

```Arduino:usage.ino
#include <fs.h>
#include <inifile.h>

const char *iniFileName = "\SETUP.ini";
const char *iniHeader = "HEADER";
unsigned char *stringData;
bool boolData;
int integerData;

void setup( void ){
  File fp = SPIFFS.open( iniFileName, "r" );
  stringData= inifileString( fp, (char *)iniHeader, "STRING", "default" );
  boolData= inifileBool( fp, (char *)iniHeader, "BOOL", true );
  integerData= inifileInteger( fp, (char *)iniHeader, "integer", -1 );
  fp.close();
}
```

データファイルはこんな風に作成します。

```Arduino:SETUP.ini
[HEADER]
STRING=stringdata
BOOL=false
integer=100
```


#ソースコード
```Arduino:inifile.h
#ifndef INIFILE_H
#define INIFILE_H

#if defined(ESP8266)
#include <FS.h>
#else
#include <SPIFFS.h>
#endif
#include <string.h>

char *inifileString( File fp, char *header, char *detail, char *defaultData=NULL ){
int  position, length, index = 0;
char str[256], *output = NULL;
bool hit, headerHit = false;
  if( !fp ){
    return defaultData;
  }
  fp.seek( 0 );
#ifdef DEBUG
  Serial.print( header );  Serial.print( ":" );  Serial.print( detail );  Serial.print( ":" );
#endif
  while ( fp.available() ){
    str[index] = fp.read();
    if( !(str[index]==0x0d || str[index]==0x0a ) ){
      if( index!=255 )
        index++;
      continue;
    }
    str[index] = 0x00;
    if( str[0]=='[' ){
      if( strchr( str, ']' )!=NULL ){
        headerHit = false;
        for( int i=0 ; ; i++ ){
          if( header[i]==0 ){
            if( str[1+i]==']' )  headerHit = true;
            break;
          }
          if( toupper(str[1+i])!=toupper(header[i]) )  break;
        }
      }
    }
    if( headerHit==true ){
      char *strpos = strchr( str, '=' );
      if( strpos!=NULL ){
        position = (strpos - str);
        if( position==strlen( detail ) ){
          hit = true;
          for( int i=0 ; i<position ; i++ ){
            if( toupper(str[i])!=toupper(detail[i]) ){
              hit=false;
              break;
            }
          }
          if( hit==true ){
            length = strlen( &str[position+1] );
            if( output!=NULL )  free( output );
            output = (char *)malloc( length+1 );
            memcpy( output, &str[position+1], length );
            output[length] = 0;
            break;
          }
        }
      }
    }
    index = 0;
  }
  if( output==NULL ){
#ifdef DEBUG
    Serial.print( "(none)" );
#endif
    if( defaultData!=NULL ){
#ifdef DEBUG
      Serial.println( defaultData );
#endif
      output = (char*)malloc( strlen(defaultData)+1 );
      strcpy( output, defaultData );
    }
    return defaultData;
  }
#ifdef DEBUG
  Serial.println( output );
#endif
  return output;
}


int inifileInteger( File fp, char *header, char *detail, int defaultData=-1 ){
char *str = inifileString( fp, header, detail, NULL );
  if( str==NULL ){
#ifdef DEBUG
    Serial.println( defaultData );
#endif
    return defaultData;
  }
  int num = atoi( str );
  free( str );
  return num;
}


bool inifileBool( File fp, char *header, char *detail, bool defaultData=false ){
char *str = inifileString( fp, header, detail, NULL );
  if( str==NULL ){
#ifdef DEBUG
    Serial.println( defaultData );
#endif
    return defaultData;
  }
  int num = strcasecmp( str, "true" );
  free( str );
  return ( (num==0)?true:false );
}
#endif
```