OSDN Git Service

初回コミット
[nmecab/NMeCabRepo2.git] / src / LibNMeCab / Core / StrUtils.cs
1 using System;\r
2 using System.Collections.Generic;\r
3 using System.Text;\r
4 #if MMF_DIC\r
5 using System.IO.MemoryMappedFiles;\r
6 #endif\r
7 \r
8 namespace NMeCab.Core\r
9 {\r
10     public static class StrUtils\r
11     {\r
12         private const byte Nul = (byte)0;\r
13 \r
14         /// <summary>\r
15         /// バイト配列の中から終端が\0で表された文字列を取り出す。\r
16         /// </summary>\r
17         /// <remarks>\r
18         /// バイト配列の長さはInt32.MaxValueを超えていても良い。\r
19         /// </remarks>\r
20         /// <param name="bytes">バイト配列</param>\r
21         /// <param name="enc">文字エンコーディング</param>\r
22         /// <returns>文字列(\0は含まない)</returns>\r
23         public static string GetString(byte[] bytes, Encoding enc)\r
24         {\r
25             return StrUtils.GetString(bytes, 0L, enc);\r
26         }\r
27 \r
28         /// <summary>\r
29         /// バイト配列の中から終端が\0で表された文字列を取り出す。\r
30         /// </summary>\r
31         /// <remarks>\r
32         /// バイト配列の長さはInt32.MaxValueを超えていても良い。\r
33         /// </remarks>\r
34         /// <param name="bytes">バイト配列</param>\r
35         /// <param name="offset">オフセット位置</param>\r
36         /// <param name="enc">文字エンコーディング</param>\r
37         /// <returns>文字列(\0は含まない)</returns>\r
38         public unsafe static string GetString(byte[] bytes, long offset, Encoding enc)\r
39         {\r
40             fixed (byte* pBytes = bytes)\r
41                 return StrUtils.GetString(pBytes + offset, enc);\r
42         }\r
43 \r
44         /// <summary>\r
45         /// バイト配列の中から終端が\0で表された文字列を取り出す。\r
46         /// </summary>\r
47         /// <remarks>\r
48         /// バイト配列の長さはInt32.MaxValueを超えていても良い。\r
49         /// </remarks>\r
50         /// <param name="bytes">デコードする最初のバイトへのポインタ</param>\r
51         /// <param name="enc">文字エンコーディング</param>\r
52         /// <returns>文字列(\0は含まない)</returns>\r
53         public unsafe static string GetString(byte* bytes, Encoding enc)\r
54         {\r
55             //バイト長のカウント\r
56             int byteCount = 0;\r
57             while (*bytes != Nul) //終端\0に到達するまでシーク\r
58             {\r
59                 checked { byteCount++; } //文字列のバイト長がInt32.MaxValueを超えたならエラー\r
60                 bytes++;\r
61             }\r
62             bytes -= byteCount;\r
63 \r
64             //生成されうる最大文字数のバッファを確保\r
65             int maxCharCount = enc.GetMaxCharCount(byteCount);\r
66             fixed (char* buff = new char[maxCharCount])\r
67             {\r
68                 //バイト配列を文字列にデコード\r
69                 int len = enc.GetChars(bytes, byteCount, buff, maxCharCount);\r
70                 return new string(buff, 0, len);\r
71             }\r
72         }\r
73 \r
74 #if MMF_DIC\r
75 \r
76         /// <summary>\r
77         /// MemoryMappedViewAccessorから終端が\0で表された文字列を取り出す。\r
78         /// </summary>\r
79         /// <remarks>\r
80         /// MemoryMappedViewAccessorの容量はInt32.MaxValueを超えていても良い。\r
81         /// </remarks>\r
82         /// <param name="accessor">MemoryMappedViewAccessor</param>\r
83         /// <param name="index">オフセット位置</param>\r
84         /// <param name="enc">文字エンコーディング</param>\r
85         /// <param name="buffSize">内部で使用するバッファの初期サイズ</param>\r
86         /// <returns>文字列(\0は含まない)</returns>\r
87         public static string GetString(MemoryMappedViewAccessor accessor, long offset, Encoding enc,\r
88                                         int buffSize = 128)\r
89         {\r
90             byte[] buff = new byte[buffSize]; //IO回数削減のためのバッファ配列\r
91             accessor.ReadArray<byte>(offset, buff, 0, buffSize); //初期読込\r
92 \r
93             //バイト長のカウント\r
94             int byteCount = 0;\r
95             while (buff[byteCount] != Nul) //終端\0に到達するまでシーク\r
96             {\r
97                 byteCount++;\r
98 \r
99                 if (byteCount == buffSize) //バッファ配列の終端\r
100                 {\r
101                     //バッファ配列の拡張と追加読込\r
102                     checked { buffSize *= 2; } //Int32.MaxValueを超えたならエラー\r
103                     byte[] newBuff = new byte[buffSize];\r
104                     Buffer.BlockCopy(buff, 0, newBuff, 0, byteCount);\r
105                     accessor.ReadArray<byte>(offset + byteCount, newBuff, byteCount, buffSize - byteCount);\r
106                     buff = newBuff;\r
107                 }\r
108             }\r
109 \r
110             //バッファ配列を文字列にデコード\r
111             return enc.GetString(buff, 0, byteCount);\r
112         }\r
113 \r
114 #endif\r
115 \r
116     }\r
117 }\r