日々適当にIT技術とか関係無いこととかをつらつらと。

AIRのIniファイルを操作するライブラリが見あたらなかったので作ってみました。
結構適当です。
Flexはまだまだ枯れてないせいもあってか、色々と基本的なものが足りていないです。

/**
 * PrivateProfile.as v.0.2
 * Author:    baado
 * Date:    2009/10/04
 * SDK:        flex_sdk_3
 * Usage:    import net.baado.util.PrivateProfile;
 *             PrivateProfile.GetPrivateProfileSection(...);
 * Description:
 *          AIR version PrivateProfile Functions (Windows native API).
 *          Arguments are different from the original functions,
 *          because of C++ and AIR have different type system. 
 * Property:
 *          errorMessage: Return error message.
 *          errorNo: Return error number.
 */
package net.baado.util
{
    public class PrivateProfile
    {
        import flash.filesystem.File;
        import flash.filesystem.FileMode;
        import flash.filesystem.FileStream;
        
        import flash.errors.IOError;
        
        public static var errorMessage:String;
        public static var errorNo:uint;
        
        public function PrivateProfile() {
        }
        public static function GetPrivateProfileSection(lpAppName:String, lpFileName:String):Object {
            var isTargetSection:Boolean = false;
            var splitIndex:uint;
            var lpKeyName:String, lpValue:String;
            
            var lineArray:Array;
            // セクション名には大括弧でくくられていればすべて許可
            var sectionPattern:RegExp = /^\[.+\]$/gi;
            var sectionObj:Object = new Object();
            
            if (!lpFileName) {
                PrivateProfile.errorNo = 4;
                PrivateProfile.errorMessage = "ファイル名が空欄です。";
                return null;
            }
            
            if (!lpAppName) {
                PrivateProfile.errorNo = 5;
                PrivateProfile.errorMessage = "セクション名が空欄です。";
                return null;
            }
            
            lineArray = PrivateProfile.GetStringListFromFile(lpFileName);
            if (lineArray == null) {
                return null;
            }
            
            for (var i:uint = 0; i < lineArray.length; i ++) {
                if (!isTargetSection) {
                    if (lineArray[i] == "[" + lpAppName + "]") {
                        isTargetSection = true;
                    }
                } else {
                    // 最初のイコールで前後を「キー=値」のペアと判断
                    // キーは空欄を拒否、値は空欄を許可
                    splitIndex = lineArray[i].indexOf("=");
                    if (splitIndex > 0) {
                        sectionObj[lineArray[i].substr(0, splitIndex)] = lineArray[i].substr(splitIndex + 1);
                        lpKeyName = lineArray[i].substr(0, splitIndex);
                        lpValue = lineArray[i].substr(splitIndex + 1);
            
                        // 前後にダブルクォートが付いている場合は削除
                        if (lpValue.substr(0, 1) == "\"" && lpValue.substr(sectionObj[lpKeyName].length - 1) == "\"") {
                            sectionObj[lpKeyName] = lpValue.substr(1, sectionObj[lpKeyName].length - 2);
                        }
                    }
                    if (lineArray[i].search(sectionPattern) == 0) {
                        return sectionObj;
                    }
                }
            }
            
            if (!isTargetSection) {
                PrivateProfile.errorNo = 2;
                PrivateProfile.errorMessage = "セクション" + lpAppName + "が見つかりません。";
                return null;
            }
            return sectionObj;
        }
        public static function GetPrivateProfileString(lpAppName:String, lpKeyName:String, lpFileName:String):String {
            var sectionObj:Object;
            var lineArray:Array;
            
            if (!lpKeyName) {
                PrivateProfile.errorNo = 6;
                PrivateProfile.errorMessage = "キー名が空欄です。";
                return null;
            } else if (lpKeyName.indexOf("=") >= 0) {
                // キー名にイコールは不許可
                PrivateProfile.errorNo = 7;
                PrivateProfile.errorMessage = "キー名が不正です。";
                return null;
            }
            
            sectionObj = PrivateProfile.GetPrivateProfileSection(lpAppName, lpFileName);
            if (sectionObj === null) {
                return null;
            }
            
            if (sectionObj[lpKeyName] === null) {
                 PrivateProfile.errorNo = 3;
                PrivateProfile.errorMessage = "セクションは見つかりましたがキー" + lpKeyName + "が見つかりません。";
                return null;
            }
               PrivateProfile.errorNo = 0;
            PrivateProfile.errorMessage = "";
            
            return sectionObj[lpKeyName];
        }
        public static function GetPrivateProfileInt(lpAppName:String, lpKeyName:String, nDefault:int, lpFileName:String):int {
            // 文字列として得た値をInteger型に変換するだけ
            var str:String = PrivateProfile.GetPrivateProfileString(lpAppName, lpKeyName, lpFileName);
            
            if (str === null) {
                return nDefault;
            } else {
                return parseInt(str);
            }
        }
        public static function GetPrivateProfileSectionNames(lpFileName:String):Array {
            var sectionNames:Array = new Array();
            var lineArray:Array;
            // セクション名には大括弧でくくられていればすべて許可
            var sectionPattern:RegExp = /^\[(.+)\]$/gi;
            var sectionObj:Object = new Object();
            
            if (!lpFileName) {
                PrivateProfile.errorNo = 4;
                PrivateProfile.errorMessage = "ファイル名が空欄です。";
                return null;
            }
            
            lineArray = PrivateProfile.GetStringListFromFile(lpFileName);
            if (lineArray == null) {
                return null;
            }
            
            for (var i:uint = 0; i < lineArray.length; i ++) {
                if (lineArray[i].search(sectionPattern) == 0) {
                    sectionNames.push(lineArray[i].substr(1, lineArray[i].length - 2));
                }
            }
            return sectionNames;
        }
        public static function WritePrivateProfileSection(lpAppName:String, lpSection:Object, lpFileName:String):Boolean {
            // 関数ヘルプに書いてあるようにapplicationDirectoryにするとダメらしい。なんでやねん。
            // 参考:http://d.hatena.ne.jp/hororiholy/20071011/p1
            var file:File = File.applicationStorageDirectory;
            var fileBk:File = File.applicationStorageDirectory;
            var stream:FileStream = new FileStream();
            var aryWrote:Array = new Array(); 
            
            var isTargetSection:Boolean = false;
            var splitIndex:int;
            
            var lineArray:Array;
            // セクション名には大括弧でくくられていればすべて許可
            var sectionPattern:RegExp = /^\[.+\]$/gi;
            var sectionObj:Object = new Object();
            
            if (!lpFileName) {
                PrivateProfile.errorNo = 4;
                PrivateProfile.errorMessage = "ファイル名が空欄です。";
                return false;
            }
            
            if (!lpAppName) {
                PrivateProfile.errorNo = 5;
                PrivateProfile.errorMessage = "セクション名が空欄です。";
                return false;
            }
            
            lineArray = PrivateProfile.GetStringListFromFile(lpFileName);

            file = file.resolvePath(lpFileName);
            
            if (lineArray != null) {
                // バックアップ
                fileBk = fileBk.resolvePath("__bk.tmp");
                try {
                    file.copyTo(fileBk, true);
                } catch (e:IOError) {
                    PrivateProfile.errorNo = 9;
                    PrivateProfile.errorMessage = "ファイル" + lpFileName + "のコピーに失敗しました。";
                    return false;
                } catch (e:SecurityError) {
                    PrivateProfile.errorNo = 10;
                    PrivateProfile.errorMessage = "ファイル" + lpFileName + "をバックアップできません。ディレクトリのアクセス権を確認してください。";
                    return false;
                }
            }
            
            // 書き込み開始
            try {
                stream.open(file, FileMode.WRITE);
            } catch (e:IOError) {
                PrivateProfile.errorNo = 7;
                PrivateProfile.errorMessage = "ファイル" + lpFileName + "のオープンに失敗しました。";
                return false;
            } catch (e:SecurityError) {
                PrivateProfile.errorNo = 8;
                PrivateProfile.errorMessage = "ファイル" + lpFileName + "にアクセスできません。アクセス権を確認してください。";
                return false;
            }
            if (lineArray == null) {
                // ファイルが無ければ作ってしまう。
                PrivateProfile.WriteSectionToStream(lpAppName, lpSection, stream);
            } else {
                for (var i:uint = 0; i < lineArray.length; i ++) {
                    if (!isTargetSection) {
                        if (lineArray[i] == "[" + lpAppName + "]") {
                            isTargetSection = true;
                        }
                        stream.writeMultiByte(lineArray[i] + "\n", File.systemCharset);
                    } else {
                        // 最初のイコールで前後を「キー=値」のペアと判断
                        splitIndex = lineArray[i].indexOf("=");
                        if (splitIndex > 0) {
                            if (lpSection[lineArray[i].substr(0, splitIndex)]) {
                                stream.writeMultiByte(lineArray[i].substr(0, splitIndex) + "=\"" + lpSection[lineArray[i].substr(0, splitIndex)] + "\"\n", File.systemCharset);
                                aryWrote.push(lineArray[i].substr(0, splitIndex));
                            } else {
                                stream.writeMultiByte(lineArray[i] + "\n", File.systemCharset);
                            }
                        } else {
                            if (lineArray[i + 1].search(sectionPattern) == 0) {
                                // 次のセクションに行く前に、既存のファイルに無いキー=値のペアを追加
                                var isWrote:Boolean;
                                
                                for (var ind:String in lpSection) {
                                    isWrote = false;
                                    for (var j:uint = 0; j < aryWrote.length; j ++) {
                                        if (ind == aryWrote[j]) {
                                            isWrote = true;
                                            break;
                                        }
                                    }
                                    if (!isWrote) {
                                        stream.writeMultiByte(ind + "=\"" + lpSection[ind] + "\"\n", File.systemCharset);
                                    }
                                }
                                // 残りを全て書き込んで脱出
                                for (; i < lineArray.length; i ++) {
                                    stream.writeMultiByte(lineArray[i] + "\n", File.systemCharset);
                                }
                                break;
                            }
                            stream.writeMultiByte(lineArray[i] + "\n", File.systemCharset);
                        }
                    }
                }
                if (!isTargetSection) {
                    // セクションがなければ新規追加
                    PrivateProfile.WriteSectionToStream(lpAppName, lpSection, stream);
                }
            }
            stream.close();
            
               PrivateProfile.errorNo = 0;
            PrivateProfile.errorMessage = "";
            
            return true;
        }
        public static function WritePrivateProfileString(lpAppName:String, lpKeyName:String, lpString:String, lpFileName:String):Boolean {
            var secObj:Object = new Object();
            
            secObj[lpKeyName] = lpString;
            
            return PrivateProfile.WritePrivateProfileSection(lpAppName, secObj, lpFileName);
        }
        public static function WritePrivateProfileInt(lpAppName:String, lpKeyName:String, nValue:int, lpFileName:String):Boolean {
            return PrivateProfile.WritePrivateProfileString(lpAppName, lpKeyName, String(nValue), lpFileName);
        }
        
        private static function GetStringListFromFile(lpFileName:String):Array {
            // アプリのパスを得てからファイル名を相対パスで解決
            // 参考:http://studio-ensyu.com/life-style/2009/02/air.html
            var file:File = File.applicationStorageDirectory;
            var stream:FileStream = new FileStream();
            var str:String;
            var ary:Array = new Array();
            
            file = file.resolvePath(lpFileName);
            
            if (!file.exists) {
                PrivateProfile.errorNo = 1;
                PrivateProfile.errorMessage = "ファイル" + lpFileName + "が存在しません。";
                return null;
            }
            
            // 読み込み開始
            try {
                stream.open(file, FileMode.READ);
            } catch (e:IOError) {
                PrivateProfile.errorNo = 7;
                PrivateProfile.errorMessage = "ファイル" + lpFileName + "のオープンに失敗しました。";
                return null;
            } catch (e:SecurityError) {
                PrivateProfile.errorNo = 8;
                PrivateProfile.errorMessage = "ファイル" + lpFileName + "にアクセスできません。アクセス権を確認してください。";
                return null;
            }
            str = stream.readMultiByte(file.size, File.systemCharset);
            stream.close();
            
            ary = str.split("\n");
            
            // 空の行を削る
            for (var i:uint = ary.length - 1; i >= 0; i --) {
                if (ary[i]) {
                    break;
                } else {
                    ary.pop();
                }
            }
            
            return ary;
        }
        private static function WriteSectionToStream(lpAppName:String, lpSection:Object, stream:FileStream):Boolean {
            var paramStr:String = "";
            
            stream.writeMultiByte("[" + lpAppName + "]\n", File.systemCharset);
            
            for (var ind:String in lpSection) {
                paramStr += ind + "=\"" + lpSection[ind] + "\"\n";
            }
            stream.writeMultiByte(paramStr, File.systemCharset);
            
            return true;
        }
    }
}
タグ

このページへのコメント

eWIz3c I really liked your blog post.Really looking forward to read more. Really Great.

0
Posted by awesome things! 2014年01月23日(木) 16:39:13 返信

Enp8co Very good blog article. Really Great.

0
Posted by check it out 2013年12月31日(火) 05:54:36 返信

U6BX0t Say, you got a nice blog.Much thanks again. Keep writing.

0
Posted by watch for this 2013年12月21日(土) 01:04:15 返信

L2lafw <a href="http://vwzlbfqyspwn.com/">vwzlbfqyspwn</a>, [url=http://rgkrhdmrleho.com/]rgkrhdmrleho[/url], [link=http://mxtvshcwawzw.com/]mxtvshcwawzw[/link], http://vepfdiqgiadp.com/

0
Posted by dluxtvm 2013年11月21日(木) 17:11:03 返信

P9tUTz <a href="http://aylvatwiidmu.com/">aylvatwiidmu</a>, [url=http://kzspxflchpjz.com/]kzspxflchpjz[/url], [link=http://vifpvwwqmisd.com/]vifpvwwqmisd[/link], http://dlpzrflhwcvw.com/

0
Posted by wwbijffysx 2013年11月14日(木) 23:56:26 返信

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

フリーエリア

編集にはIDが必要です