рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдФрд░ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдХреЙрдореНрдкреНрд▓реЗрдХреНрд╕ рдХреЛ рд╡рд┐рдХрд╕рд┐рдд рдХрд░рддреЗ рд╕рдордп, рдПрдХ рдХреНрд▓рд╛рдЗрдВрдЯ рдбрд┐рд╡рд╛рдЗрд╕ рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛, рдЬреЛ рдЕрдиреНрдп рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдирд┐рдпрдорд┐рдд рдпреВрдПрд╕рдмреА рдлреНрд▓реИрд╢ рдбреНрд░рд╛рдЗрд╡ рдХреА рддрд░рд╣ рджрд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрд╛, рдЕрдзрд┐рдХ рдФрдкрдЪрд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ, рдПрдХ рдпреВрдПрд╕рдмреА рдорд╛рд╕ рд╕реНрдЯреЛрд░реЗрдЬ рдбрд┐рд╡рд╛рдЗрд╕ред рдпрд╣ рдЙрдкрдХрд░рдг рдЕрд╕рд╛рдорд╛рдиреНрдп рд╣реИ рдХрд┐ рдпрд╣ рдмрд╛рд╣рд░реА рджреБрдирд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд░реВрдк рд╕реЗ рдмрдбрд╝реЗ рдЖрдХрд╛рд░ (2GB рдпрд╛ рдЕрдзрд┐рдХ) рдХреА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде FAT рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдЗрд╕ рддрдереНрдп рдХреЗ рдмрд╛рд╡рдЬреВрдж рдХрд┐ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдлрд╝рд╛рдЗрд▓реЗрдВ рд╕реНрд╡рдпрдВ, рдЕрдиреБрдкрд╕реНрдерд┐рдд рд╣реИрдВ рдФрд░ рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рд╣реИрдВред рд╡реИрд╕реЗ рднреА, рдпреЗ рдлрд╛рдЗрд▓реЗрдВ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рдСрдбрд┐рдпреЛ рд╕реНрдЯреНрд░реАрдо рд╣реИрдВред
рдХрд╛рд░реНрдп, рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рд╕рд░рд▓ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдмреНрд▓реЙрдХ (SCSI рдХрдорд╛рдВрдб) рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рд╣рдо рдЗрд╕ рдмреНрд▓реЙрдХ рдХреА рд╕рд╛рдордЧреНрд░реА рджреЗрддреЗ рд╣реИрдВред рдПрдХ рдмреНрд▓реЙрдХ рдпрд╛ рддреЛ рдХрд┐рд╕реА рднреА "рдлрд╛рдЗрд▓" рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдЙрд╕рдореЗрдВ FAT рдУрд╡рд░рд╣реЗрдб рдЬрд╛рдирдХрд╛рд░реА рд╣реЛ рд╕рдХрддреА рд╣реИред
рдкрд╣рд▓рд╛ рд╡рд┐рдЪрд╛рд░, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, FAT рдЫрд╡рд┐ рдХреЛ рдкреИрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдерд╛, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, bzip2 рдФрд░ рдЗрд╕реЗ рдЖрд╡рд╢реНрдпрдХрддрд╛рдиреБрд╕рд╛рд░ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдЕрдирдкреИрдХ рдХрд░реЗрдВред рддреАрди рд╕рдорд╕реНрдпрд╛рдПрдВ рддреБрд░рдВрдд рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВ:
- 100 рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рдХрдИ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреА рдПрдбрд╝реА рд╕реЗ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреА рдПрдХ рд╕рдВрдХреБрдЪрд┐рдд рдЫрд╡рд┐ 125Kb рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреБрдЫ рд▓реЗрддреА рд╣реИ, рдЬреЛ рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рд░реИрдо рдХреА рдорд╛рддреНрд░рд╛ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред
- Bzip2, рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░, рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рдФрд░ рдкреНрд░рд╡рд╛рд╣ рдХреЗ рд╕реНрддрд░ рдкрд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рд╕реЗрдХреНрдЯрд░-рджрд░-рд╕реЗрдХреНрдЯрд░ рдХреЛ рдкреИрдХ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЫрд╡рд┐ рдХрд╛ рдЖрдХрд╛рд░ рдмрд┐рд▓реНрдХреБрд▓ рдЕрдкрдорд╛рдирдЬрдирдХ рд╣реЛрдЧрд╛: рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЫреЛрдЯреЗ рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд╕рд╛рде рдкреИрдХрд┐рдВрдЧ рдХрд░рдирд╛ рд▓рд╛рднрд╣реАрди рд╣реИ - рд╕рдВрдкреАрдбрд╝рди рд╕реЗ рд▓рд╛рдн рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдУрд╡рд░рд╣реЗрдб рдмрдбрд╝рд╛ рд╣реИред
- рдЫрд╡рд┐ рддреИрдпрд╛рд░ рдХрд░рдирд╛ (рдПрдХ рдЦрд╛рд▓реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдмрдврд╝рд╛рдирд╛, рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдирд╛, рдкреИрдХрд┐рдВрдЧ рдХрд░рдирд╛) рдореЗрдВ рдмрд╣реБрдд рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рд╕рд░реНрд╡рд░ рдкрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рд╢рд╛рдпрдж рд╣реА рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЕрдиреБрдорд╛рдирд┐рдд рд╣рдЬрд╛рд░реЛрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╣реЛрддреЗ рд╣реИрдВред рдФрд░ рдирд┐рд░реНрдорд╛рдг рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рдЫрд╡рд┐ рдХреЛ рдХреБрдЫ рдХрд╛рдлреА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдбрд┐рд╕реНрдХ рд╕реНрдерд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдЗрд╕ рддрдереНрдп рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдирд╣реАрдВ рдХрд░рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рд▓рд┐рдП bzip2 рдХреЛ рдкреЛрд░реНрдЯ рдХрд░рдирд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП рдХреБрдЫ рдФрд░ рдКрдкрд░ рдЖрдирд╛ рдкрдбрд╝рд╛ред
рд╕рдорд╕реНрдпрд╛ рдХреЛ рдирд┐рдореНрди рдкреНрд░рдХрд╛рд░ рд╕реЗ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ: рдПрдХ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдЬреЛ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдХреБрдЫ рд╡рд┐рд╡рд░рдг рдХреЛ рдХрд┐рд╕реА рди рдХрд┐рд╕реА рд░реВрдк рдореЗрдВ рдЗрдирдкреБрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдЧрд╛, рдФрд░ рд╕реЗрдХреНрдЯрд░ рдирдВрдмрд░ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЗрд╕рдХреА рд╕рд╛рдордЧреНрд░реА рд╡рд╛рдкрд╕ рдХрд░реЗрдЧрд╛ред рд╕рд╛рдордЧреНрд░реА рдпрд╛ рддреЛ рд╕реЗрд╡рд╛ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдпрд╛ рдлрд╝рд╛рдЗрд▓ рдбреЗрдЯрд╛ рд╣реИ, рдЬреЛ рдХрд┐рд╕реА рджрд┐рдП рдЧрдП URL рдкрд░ рд╕рдВрдмрдВрдзрд┐рдд рдСрдбрд┐рдпреЛ рд╕реНрдЯреНрд░реАрдо рд╕реЗ рд▓рд┐рдП рдЧрдП рд╣реИрдВред
рдкреНрд░рд╢реНрди рдХрд╛ рдпрд╣ рд╕реВрддреНрд░реАрдХрд░рдг рд╣рдореЗрдВ рдирд┐рдпрдореЛрдВ рдХреА рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ:
=>
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд╣рдо рд╕реЗрдХреНрдЯрд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рди рдХрд┐ "рдХреНрд▓рд╕реНрдЯрд░", рдХреНрдпреЛрдВрдХрд┐ рдХреНрд▓рд╕реНрдЯрд░ рдПрдХ рдПрдлрдПрдЯреА рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИред рдбрд┐рд╡рд╛рдЗрд╕ рдмреНрд▓реЙрдХ рд╕реНрддрд░ рдкрд░ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рд╡реЗ рднреА рд╕реЗрдХреНрдЯрд░ рд╣реИрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реА "рдкреНрд▓реЗрд▓рд┐рд╕реНрдЯ" рдореЗрдВ 2Gb рдХреА 10 "рдлрд╛рдЗрд▓реЗрдВ" рд╣реИрдВ (2Gb рдЕрдирдВрдд рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИ)ред рдпрджрд┐ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рдпрдо рдореЗрдВ рдПрдХ рдмрд╛рдЗрдЯ рдХрд╛ рдЖрдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЕрд╕рдВрднрд╡ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
2*1024*1024*1024 * 10 / 512 = 41 943 040
рд╕рднреА рдирд┐рдпрдореЛрдВ рдХреЗ рд▓рд┐рдП рдмрд╛рдЗрдЯред рдХреБрдЫ рд╣рдж рддрдХ рдЕрдзрд┐рдХ рдЙрдЪрд┐рдд рд╣реИред рд▓реЗрдХрд┐рди, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдирд┐рдпрдо рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдирд╣реАрдВ рд╣реИрдВред рд╣рдо рд╕реЗрдХреНрдЯрд░реЛрдВ рдХреА рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рдпрд╣ рд╣рдореЗрдВ рдирд┐рдпрдореЛрдВ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддрд╛ рд╣реИ:
(A) =>
(A,B) =>
рд╣рдо рд╕реНрд╡рдпрдВ рд╕реЗрдХреНрдЯрд░реЛрдВ рдХреЛ рдкреИрдХ рдХрд░рдиреЗ рдХрд╛ рднреА рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВрдЧреЗред рдЪреВрдВрдХрд┐ рд╣рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░реНрдп рд╕реЗ рд╕рд╛рдордирд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдбреЗрдЯрд╛ рд╕реНрд╡рдпрдВ рдбрд┐рд╡рд╛рдЗрд╕ рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╣реАрдВ рд╣реИ рдФрд░ рд╡реЗрдм рд╕реЗ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЖрдкрдХреЛ рдмрд╕ рдХрд┐рд╕реА рддрд░рд╣ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕реЗрд╡рд╛ рдбреЗрдЯрд╛ рдХреА рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рдХреЙрдореНрдкреИрдХреНрдЯ рдкреНрд░рд╕реНрддреБрддрд┐ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдкрд╣рд▓реА рдирдЬрд╝рд░ рдореЗрдВ, рдЗрд╕ рдбреЗрдЯрд╛ рдореЗрдВ рдХрдИ рджреЛрд╣рд░рд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЕрдиреБрдХреНрд░рдо рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдХреЛрдб рдХрд░реЗрдВрдЧреЗ: рджреЛрд╣рд░рд╛рдП рдЧрдП рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
( RLE, , )
рдХреЗ рд░реВрдк рдореЗрдВ рдЧреИрд░ рджреЛрд╣рд░рд╛рд╡ рджреГрд╢реНрдпреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреЗ рд╣реИрдВ
( Sequence, )
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЙрди рдЕрдиреБрдХреНрд░рдореЛрдВ рдХреЛ рдЬрд┐рдиреНрд╣реЗрдВ рд╣рдо рдкрд╣рд▓реЗ рд╣реА рдПрдиреНрдХреЛрдб рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ, рдпрд╛ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕рдореНрдорд┐рд▓рд┐рдд рдирд╣реАрдВ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЙрдиреНрд╣реЗрдВ рджреЗрдЦреЗрдВред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╢рд╛рдпрдж рдПрдХ рдФрд░ рдЕрдиреБрдХреНрд░рдо рд╣реИ
( , )
рд╢рд╛рдпрдж рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рджреМрд░рд╛рди, рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЗ рд▓рд┐рдП рдЕрдиреНрдп рдЕрдиреБрдХреНрд░рдо рджрд┐рдЦрд╛рдИ рджреЗ рд╕рдХрддреЗ рд╣реИрдВред
рдпрд╣ рд╕рдм рдПрдХ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдХрдорд╛рдВрдб рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╕рдорд╛рди рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рдХреЙрд▓ рд╣реЛрддреЗ рд╣реИрдВ, рдпрд╛рдиреА рд╕реНрдЯреИрдХред рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЬреНрдЮрд╛рдд рдЖрднрд╛рд╕реА рдорд╢реАрди рдПрдХ рдХрд┐рд▓реЗ рдХреА рдХрд┐рд╕реНрдореЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рд╡рд┐рдкрд░реАрдд рд╣реИред
рд╕реНрдЯреЗрд░реЙрдпрдб рдкрд░ рдкреЛрд▓рд┐рд╢ рд░рд┐рдХреЙрд░реНрдб, рдХреЙрд▓ рд╕реЗ рд╡рд╛рдкрд╕реА рдкрддреЗ рдХреЗ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдвреЗрд░ рдХреЗ рд╕рд╛рде, рдЬреЛ рд╕рдорд╛рд░реЛрд╣ рдХреЗ рдлреНрд░реЗрдо рдХреЛ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдкрд░реЗрд╢рд╛рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ: рд╕рдм рдХреБрдЫ рдмреЗрд╣рдж рд╕рд░рд▓ рд╣реИ - рд╣рдо рдЗрд╕реЗ рдХреЙрд▓ рд╕реЗ рд▓реМрдЯрдиреЗ рдкрд░ рд╣рдЯрд╛ рджреЗрддреЗ рд╣реИрдВ
рд╕реНрдЯреИрдХ рдЖрд░ рд╕реЗ рд╢реАрд░реНрд╖ рд╢рдмреНрдж рдФрд░ рдЙрд╕ рдкрддреЗ рдкрд░ рдЬрд╛рдПрдВ рдЬрд┐рд╕ рдкрд░ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рджреЛ-рд╕реНрдЯреИрдХ рдорд╢реАрди рдХреЗ рд▓рд┐рдП рдЯреЛрдХрди рдереНрд░реЗрдбреЗрдб рдХреЛрдб (рдФрд░ рдпрд╣ рдпрд╣ рд╣реЛрдЧрд╛) рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рдШрдирддреНрд╡ рд╣реИ, рдЬреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИред
рдРрд╕реЗ рдХреЛрдб рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░рдирд╛ рддреЗрдЬрд╝ рд╣реИ, рдпрд╣ рджреЗрд╢реА рдХреЛрдб рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдФрд╕рддрди рдкрд╛рдБрдЪ рдЧреБрдирд╛ рдзреАрдорд╛ рд╣реИ, рдФрд░ рдмрд╣реБрдд рд╕рд░рд▓ рднреА рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рдХреЛрдбрд┐рдВрдЧ рдкреНрд░рдгрд╛рд▓реА, рдирд┐рдпрдореЛрдВ рдХреА рдПрдХ рдкреНрд░рдгрд╛рд▓реА рдФрд░ рдХреБрдЫ рдкреНрд░рдХрд╛рд░ рдХреА рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рд╣реИрдВ, рдЬрд┐рди рдкрд░ рдЗрди рдирд┐рдпрдореЛрдВ рдХреЛ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдпрд╣ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╡рд┐рд╡рд░рдг рд╕реЗ рдЗрди рдирд┐рдпрдореЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдиреА рд╣реБрдИ рд╣реИ, рдПрдХ рдмрд╛рдИрдЯреЗрдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╢реАрди рд▓рд╛рдЧреВ рдХрд░реЗрдВред рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдХреНрдпрд╛ рд╣реБрдЖред
рдПрдХ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде, рд╕реНрдерд┐рддрд┐ рд╕рд░рд▓ рд╣реИ: рдпрд╣ рдХреНрд░рдорд╢рдГ рдПрдХ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛, рдпрд╣рд╛рдВ рдЕрдм рддрдХ рдХреЛрдИ рд╕реА рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реИрдВред рд╕рдЪ рд╣реИ, рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рд╡рд╣рд╛рдБ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ - рдпрд╣ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдЗрд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛
рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗред
рдЬреЛ рдХреБрдЫ рднреА рд░рд╣рддрд╛ рд╣реИ рд╡рд╣ рд╡рд┐рд╡рд░рдг, рд╡рд┐рд╡рд░рдг, рдХреЛрдб рдкреАрдврд╝реА рдФрд░ рдЗрд╕ рдХреЛрдб рдХреЗ рдЖрджреЗрд╢реЛрдВ рдХреЗ рд╡рд┐рд╡рд░рдг рд╕реЗ рдирд┐рдпрдо рдкреНрд░рдгрд╛рд▓реА рдХреА рдкреАрдврд╝реА рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдирд┐рдпрдореЛрдВ рдХреЛ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рддрд░реНрдХрд╕рдВрдЧрдд рд░реВрдк рд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛: рдлреЙрд░реНрдо рдореЗрдВ рдЪреЗрдХ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░реЗрдВ
рддреБрд▓рдирд╛рддреНрдордХ рд╡реГрдХреНрд╖, рддрд╛рдХрд┐ рдкреНрд░рддрд┐ рд╕реЗрдХреНрдЯрд░ рдХреА рддреБрд▓рдирд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рддреБрд▓рдирд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рд▓рдШреБрдЧрдгрдХ рдХреЗ рдХреНрд░рдо рдХреА рд╣реЛрдЧреАред
рд╣рдордиреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдкреВрд░рд╛ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ, рд╣рдореЗрдВ рдПрдХ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдмрдирд╛рдирд╛ рд╣реЛрдЧрд╛ рдФрд░ рджреЗрдЦрдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓рддрд╛ рд╣реИред
рд╣рдореЗрдВ рд╡рд┐рднрд┐рдиреНрди рдЖрдпрд╛рдореЛрдВ рдФрд░ рдПрдВрдбрд┐рдпрдирд╕реЗрд╕ (рдмрд╛рдЗрдирд░реА рд╕реЗрд╡рд╛ рдбреЗрдЯрд╛ рдХрдо-рдПрдВрдбрд┐рдпрди рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВ) рдХреЗ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдФрд░ рд╕рдВрднрд╡рддрдГ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдФрд░ рдиреЗрд╕реНрдЯреЗрдб рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдЗрд╕реЗ рдХрд┐рд╕ рдкрд░ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛? рд╕реА, рд╕реА ++ рдпрд╛ рд╢рд╛рдпрдж рдкрд╛рдпрдерди? рдпрд╛ рд░реВрдмреА? рдПрдХ рдЪреБрдЯрдХреБрд▓рд╛ред
рдмреЗрд╢рдХ, рд╣рдо рдЗрд╕реЗ рд╣рд╛рд╕реНрдХреЗрд▓ рдореЗрдВ рдХрд░реЗрдВрдЧреЗ: рдХрд╛рд░реНрдп рд╕рдмрд╕реЗ рд╕рд░рд▓ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдмрд╣реБрдд рдХрдо рд╕рдордп рд╣реЛрддрд╛ рд╣реИред рд╡реИрд╕реЗ рднреА, рдЗрд╕ рдХреЛрдб рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рд░реНрд╡рд░ рдХреЛ рднреА рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ
рд╣рд╛рд╕реНрдХреЗрд▓, рдЗрд╕рд▓рд┐рдП рдкрд╕рдВрдж рдХрд╛рдлреА рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд╣реИред
рдЪрд▓рд┐рдП рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдХреЗрдВрджреНрд░реАрдп рдЪреАрдЬ "рдирд┐рдпрдо" рд╣реИред рд╡реЗ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЙрдирд╕реЗ рдХреЛрдб рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рд╣рдо рдЙрдирдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ:
data Rule = REQ Int [Chunk] | RANGE Int Int [Chunk] deriving Show
data Chunk = SEQ BS.ByteString
| RLE Int Word8
deriving (Eq, Ord)
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рд╣реА рд╡рд┐рд╡рд░рдг рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдФрд░ рдлрд╛рдЗрд▓реЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рдПрдлрдПрдЯреА рдХреА рдХреБрдЫ рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛рдПрдВ рд╣реИрдВред
data Entry = DirRoot Int [Entry] | DirDot Int | DirDotDot Int | Dir Int String [Entry] | File Int String Int BS.ByteString deriving (Eq, Ord, Data, Typeable, Show)
data Entry = DirRoot Int [Entry] | DirDot Int | DirDotDot Int | Dir Int String [Entry] | File Int String Int BS.ByteString deriving (Eq, Ord, Data, Typeable, Show)
рдпрд╣рд╛рдБ рд╣рдо рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд░рд╣рддреЗ рд╣реИрдВред рдЕрдЬреАрдм рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдбрд┐рдбреЛрд░ рдФрд░ рдбрд┐рдЕрд░рдбреЙрдЯрдбреЙрдЯ '' 'рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдПрдБ рд╕реЗ рдЬреНрдпрд╛рджрд╛ рдХреБрдЫ рдирд╣реАрдВ рд╣реИрдВ рдФрд░ '..', рдЬреЛ - рдпрд╣рд╛рдБ рдПрдХ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ - рд╢реАрд░реНрд╖ рдкрд░ рд╣реИрдВ, рд╢рд╛рд░реАрд░рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд░реНрддрдорд╛рди рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ рд╡реЗ
рдХреЗрд╡рд▓ рд▓рд┐рдВрдХ рд╣реИрдВ рдФрд░ рд╕рдореВрд╣реЛрдВ рдХреЗ рдЖрд╡рдВрдЯрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред
рдЕрдиреНрдпрдерд╛, рд╕рдм рдХреБрдЫ рдмрд╣реБрдд рд╕реНрдкрд╖реНрдЯ рд╣реИ: рдкреНрд░рдХрд╛рд░ рдХреЗ рдирд┐рд░реНрдорд╛рдгрдХрд░реНрддрд╛рдУрдВ рдХреА рдкрд╣рд▓реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдлрд░реНрдорд╡реЗрдпрд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдбреЗрдЯрд╛ "рдлрд╝рд╛рдЗрд▓" рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рджреВрд╕рд░реА рд╡рд┐рд╢реЗрд╖рддрд╛ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╣реИред рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдЙрд╕рдХрд╛ рдЖрдХрд╛рд░ рдФрд░ рдбреЗрдЯрд╛ рднреА рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред рдпрд╣, рдЬрд╝рд╛рд╣рд┐рд░ рд╣реИ, рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдбреЗрдЯрд╛ рд╣реА рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рдлрд░реНрдорд╡реЗрдпрд░ рдХреЗ рдХреБрдЫ рд╕рдВрдХреЗрдд рд╣реИрдВ рдЬрд╣рд╛рдВ рдпрд╣ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред рд╡рд╣рд╛рдБ рдЖрдк рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ sshsh рд╕рдВрд░рдЪрдирд╛ рдпрд╛ рд╕реНрдЯреНрд░реАрдо URLред рдЗрд╕рд▓рд┐рдП рдмрд╛рдЗрдЯрд╕реНрдЯреНрд░реАрдорд┐рдВрдЧред
рдЕрдм рд╣рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рд╕реЗ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдПрдВрдЯреНрд░реА рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛, рд░реВрдЯ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЛ рджрд░реНрдЬ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред '' рдФрд░ '..', рдЙрдиреНрд╣реЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП
рд╕рдорд╛рди рд░рд┐рдХреЙрд░реНрдб рдирд╛рдо, рдирд╛рдореЛрдВ рдореЗрдВ рдирд┐рд╖рд┐рджреНрдз рд╡рд░реНрдг рдФрд░ рдЗрддрдиреЗ рдкрд░ рдФрд░ рдЖрдЧреЗ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдмрдирд╛рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реИ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдкреАрдЖрдИ рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЗрд╕рд╕реЗ рдирд┐рдкрдЯрдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рд╡рд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдХреБрдЫ рдорд┐рд▓рд╛рдПрдЧрд╛ рдФрд░ рд╕рдм рдХреБрдЫ рдЯреВрдЯ рдЬрд╛рдПрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЧрдВрднреАрд░ рдорд╛рдорд▓рд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдПрдВрдЯреНрд░реА-рдкреНрд░рдХрд╛рд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЗ рдЖрдпрд╛рдд рдХреЛ рд░реЛрдХрдирд╛ рдмреЗрд╣рддрд░ рд╣реИ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреБрдЫ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдФрд░ рддреНрд░реБрдЯрд┐-рд╕реБрд░рдХреНрд╖рд┐рдд рд╕рдорд╛рдзрд╛рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:
fileContents = ... fatSample2 = filesystem $ do file "file0" (16384) fileContents dir "A" $ do file "file1" (megs 100) fileContents dir "C" $ do file "file3" (megs 100) fileContents file "file4" (megs 100) fileContents file "file5" (megs 100) fileContents dir "E" $ emptyDir dir "B" $ do file "file2" (megs 50) emptyFile
fileContents = ... fatSample2 = filesystem $ do file "file0" (16384) fileContents dir "A" $ do file "file1" (megs 100) fileContents dir "C" $ do file "file3" (megs 100) fileContents file "file4" (megs 100) fileContents file "file5" (megs 100) fileContents dir "E" $ emptyDir dir "B" $ do file "file2" (megs 50) emptyFile
рдпрд╣ рдЕрдЪреНрдЫрд╛ рд▓рдЧ рд░рд╣рд╛ рд╣реИ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЬреЛ рднрд╛рд╖рд╛ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИ рд╡рд╣ рд╕рдордЭ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдХреНрдпрд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИред
рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реИ: рдХреБрдЫ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд╣рд▓реЗ рд╕реЗ рддреИрдпрд╛рд░ рдореЛрдирд╛рдб рд▓реЗрдЦрдХ рд╣реИред
рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛рдУрдВ рдХреЛ рд╡рд┐рддрд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЗрд╕рд▓рд┐рдП рд░рд╛рдЬреНрдп рднреА рдЙрдкрдпреЛрдЧреА рд╣реИ, рдЬрд╣рд╛рдВ рд╣рдо рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХрд╛ рдХрд╛рдЙрдВрдЯрд░ рд▓рдЧрд╛рддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рд╣рдо рд╕реНрдЯреЗрдЯ рдФрд░ рд░рд╛рдЗрдЯрд░ рдХреЛ рдкрд╛рд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореЛрдирдб рдЯреНрд░рд╛рдВрд╕рдлрд╛рд░реНрдорд░ рд╣рдореЗрдВ рдиреБрдХрд╕рд╛рди рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛рдПрдЧрд╛ред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:
newtype EntryIdT ma = EntryIdT { runF :: (WriterT [Entry] (StateT (Int, Int) m)) a } deriving (Monad, MonadWriter [Entry], MonadState (Int, Int)) type EntryIdM = EntryIdT Identity runEntryIdM :: (Int, Int) -> EntryIdM a -> ([Entry], (Int, Int)) runEntryIdM init f = runState (execWriterT (runF f)) init filesystem :: EntryIdM () -> Entry filesystem f = DirRoot 0 dirs where dirs = fst $ runEntryIdM (1,0) f dir :: String -> EntryIdM () -> EntryIdM () file :: String -> Int -> (EntryInfo -> BS.ByteString) -> EntryIdM ()
newtype EntryIdT ma = EntryIdT { runF :: (WriterT [Entry] (StateT (Int, Int) m)) a } deriving (Monad, MonadWriter [Entry], MonadState (Int, Int)) type EntryIdM = EntryIdT Identity runEntryIdM :: (Int, Int) -> EntryIdM a -> ([Entry], (Int, Int)) runEntryIdM init f = runState (execWriterT (runF f)) init filesystem :: EntryIdM () -> Entry filesystem f = DirRoot 0 dirs where dirs = fst $ runEntryIdM (1,0) f dir :: String -> EntryIdM () -> EntryIdM () file :: String -> Int -> (EntryInfo -> BS.ByteString) -> EntryIdM ()
рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдиреЗрд╕реНрдЯреЗрдб рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╛рдо, рдЖрдХрд╛рд░ рдФрд░ рдПрдХ рдЕрдиреНрдп рдорд╛рдирдж рдорд╛рди рдЬреИрд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рд▓реЗрддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдРрд╕реА рдЧрдгрдирд╛ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦрдХ рдореЗрдВ рдЪрд▓рд╛рдИ рдЬрд╛рдПрдЧреА, рдФрд░ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╛рдЬреНрдп рдХреЛ рдШрд╕реАрдЯрд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЕрджреНрд╡рд┐рддреАрдп рд╣реИрдВред
рдЗрд╕рд▓рд┐рдП, рд╣рдордиреЗ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕рдВрд░рдЪрдирд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рд╣реИ, рдЕрдм рд╣рдореЗрдВ рдХрд┐рд╕реА рднреА рддрд░рд╣ рд╕реЗ рдирд┐рдпрдореЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рддрд░рд╣ рдбреЗрдЯрд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдФрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ "рдбрд┐рд╕реНрдХ" рдкрд░ рд░рдЦреЗрдВред
рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдЙрдиреНрд╣реЗрдВ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ, рдкрд╣рд▓реЗ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ, рдлрд┐рд░ рдлрд╛рдЗрд▓реЛрдВ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ:
data AllocEntry = AllocEntry { beginSect :: Int , endSect :: Int , entry :: Entry } deriving (Show) allocate :: ClustSize32 -> Int -> Entry -> [AllocEntry] allocate cl from = eFix . eAlloc . eOrder . filter eFilt . universe where eFilt (File _ _ _ _) = True eFilt (Dir _ _ _) = True eFilt (DirRoot _ _) = True eFilt _ = False eOrder = uncurry (++) . partition (not.isFile) eAlloc = reverse . snd . foldl fentry (from, []) fentry (n, xs) e = let sectors = entryLen cl e `div` fatSectLen begin = n end = begin + sectors - 1 n' = n + sectors allocated = AllocEntry begin end e in (n', allocated : xs) eFix = id
data AllocEntry = AllocEntry { beginSect :: Int , endSect :: Int , entry :: Entry } deriving (Show) allocate :: ClustSize32 -> Int -> Entry -> [AllocEntry] allocate cl from = eFix . eAlloc . eOrder . filter eFilt . universe where eFilt (File _ _ _ _) = True eFilt (Dir _ _ _) = True eFilt (DirRoot _ _) = True eFilt _ = False eOrder = uncurry (++) . partition (not.isFile) eAlloc = reverse . snd . foldl fentry (from, []) fentry (n, xs) e = let sectors = entryLen cl e `div` fatSectLen begin = n end = begin + sectors - 1 n' = n + sectors allocated = AllocEntry begin end e in (n', allocated : xs) eFix = id
рдПрдХ рдкреВрд░реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХреЛрдб рдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рд╣реИ: рд╣рдо рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рд▓реЗрддреЗ рд╣реИрдВ, 'рд╣рдЯрд╛рдПрдВ'ред рдФрд░ '..' рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХреНрд▓рд╕реНрдЯрд░ рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдЕрдЬрдирдмрд┐рдпреЛрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╣рдо рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЛ рдкрд╣рд▓реЗ рдмрдирд╛рддреЗ рд╣реИрдВ, рдлрд┐рд░ рдлрд╛рдЗрд▓реЗрдВ (рдХреЛрдИ рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдзрд┐рдХ рддрд╛рд░реНрдХрд┐рдХ рд╣реИ,)
рдФрд░ рд╡реЙрд▓реНрдпреВрдо рдХреА рд╕рд╛рдордЧреНрд░реА рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рддреЗрдЬрд╝ рд╣реЛ рдЬрд╛рдПрдЧреА), рд╣рдо рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ (рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ, "рдХреНрд▓рд╕реНрдЯрд░" рдПрдХ рдХреГрддреНрд░рд┐рдо рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИ) рдФрд░ рд╡рд╣ рд╕рдм рд╣реИред
рдпрд╣ рдпреВрдирд┐рд▓реЗрдЯ рдореЙрдбреНрдпреВрд▓ рд╕реЗ рдмреНрд░рд╣реНрдорд╛рдВрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИред рдпрд╣ рдЖрдкрдХреЛ рдПрдХ рд╕реВрдЪреА рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ (рдпрджрд┐ рд╡рд╛рдВрдЫрд┐рдд, рд╕реВрдЪреА рд╕рдордЭ рдХреЗ рд╕рд╛рде) рдкреБрдирд░рд╛рд╡рд░реНрддреА рдЯреНрд░реИрд╡рд░реНрд╕рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рдирд┐рдпрдорд┐рдд рд▓реЗрдЦрди рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдПред
рдпрд╣ рдЙрд╕рдХреА рдЦрд╛рддрд┐рд░ рд╣реИ рдХрд┐ рд╣рдордиреЗ рдКрдкрд░ рдПрдВрдЯреНрд░реА рд╡реНрдпреБрддреНрдкрдиреНрди (рдбреЗрдЯрд╛, рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдпреЛрдЧреНрдп) рдкреНрд░рдХрд╛рд░ рдХреА рдШреЛрд╖рдгрд╛ рдХреАред
рд╕реЗрдХреНрдЯрд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рд░рдЦреА рдЧрдИ рдлрд╛рдЗрд▓реЗрдВ рд╣реЛрдиреЗ рд╕реЗ, рдЙрдирдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдХреБрдЫ рднреА рдЦрд░реНрдЪ рдирд╣реАрдВ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ:
generateData :: Maybe CalendarTime -> ClustSize32 -> [AllocEntry] -> [Rule] generateData ct cl es = mergeRules $ execWriter $ do forM_ es $ \(AllocEntry {beginSect = a, endSect = b, entry = e}) -> do case e of DirRoot _ es -> writeEntries ab es Dir _ _ es -> writeEntries ab es File _ _ _ bs -> tell [RANGE ab (encodeBlock (BS.take (fatSectLen) bs))] where ...
generateData :: Maybe CalendarTime -> ClustSize32 -> [AllocEntry] -> [Rule] generateData ct cl es = mergeRules $ execWriter $ do forM_ es $ \(AllocEntry {beginSect = a, endSect = b, entry = e}) -> do case e of DirRoot _ es -> writeEntries ab es Dir _ _ es -> writeEntries ab es File _ _ _ bs -> tell [RANGE ab (encodeBlock (BS.take (fatSectLen) bs))] where ...
рдПрдиреНрдХреЛрдбрдмреНрд▓реЙрдХ рдлрд╝рдВрдХреНрд╢рди рдпрд╣рд╛рдБ рдирд┐рдпрдореЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдПрдХ рдмрд╛рдЗрдЯрд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдПрдирдХреЛрдб рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд░рд╛рдЗрдЯрдПрдиреНрдЯреНрд░реА рдбрд╛рдпрд░реЗрдХреНрдЯрд░реА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдПрдирдХреЛрдб рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдорд░реНрдЬрд░реНрдпреВрд▓рд░ рдХреНрд░рдорд┐рдХ рдирд┐рдпрдореЛрдВ рдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд╕реАрдорд╛ рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реИред
рдПрдХрд▓ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдмрдирд╛рдирд╛ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
entryRecordShort :: String -> Int -> Int -> Maybe CalendarTime -> [ATTR] -> BS.ByteString entryRecordShort nm size clust clk a = runPut $ do putNameASCII nm
entryRecordShort :: String -> Int -> Int -> Maybe CalendarTime -> [ATTR] -> BS.ByteString entryRecordShort nm size clust clk a = runPut $ do putNameASCII nm -- Name putWord8 (fatAttrB a) -- Attr putWord8 0 -- NTRes putWord8 0 -- CrtTimeTenth putWord16le cT -- CrtTime putWord16le cD -- CrtDate putWord16le cD -- LstAccDate putWord16le cHi -- FstClusHI putWord16le cT -- WrtTime putWord16le cD -- WrdDate putWord16le cLo -- FstClusLO putWord32le (fromIntegral size) -- FileSize where ...
рдпрд╣рд╛рдВ рд╣рдо Data.Binary.Put рд╕реЗ рдЕрд╕рд╛рдзрд╛рд░рдг рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧреА PutM monad рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЖрд▓рд╕реА рдмрд╛рдЗрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рднреА рдмрд┐рдЯ рдбреЗрдкреНрде рдФрд░ рдПрдВрдбрд┐рдпрдирд┐рдЯреА рдХрд╛ рдбреЗрдЯрд╛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдлрдПрдЯреА рд╡реЙрд▓реНрдпреВрдо рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рд╕рдВрд░рдЪрдирд╛ рд╣реИ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реЗрдХреНрдЯрд░ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдирд┐рдпрдореЛрдВ рджреНрд╡рд╛рд░рд╛ рдЙрдирдХрд╛ рдЖрд╡рдВрдЯрди рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рдмрдЪрд╛ рд╣реИ?
рдпрд╣рд╛рдВ рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдкреАрдЫреЗ рд╣рдЯрдиреЗ рдФрд░ FAT рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдпрд╛рдж рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд┐рд╡рд░рдгреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВ рдЬреЛ рд╡реЗрдм рдкрд░ рдФрд░ рд╕рд╛рд╣рд┐рддреНрдп рдореЗрдВ рд╡реНрдпрд╛рдкрдХ рд░реВрдк рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реИрдВ, рддреЛ FAT32 рдЗрд╕ рддрд░рд╣ рд╕реЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
| рдмреВрдЯрд╕реЗрдХреНрдЯ | FAT32 рдЬрд╛рдирдХрд╛рд░реА | FAT1 | FAT2 | DATA |
рдЕрдм рддрдХ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреЗрд╡рд▓ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рд╣реИрдВред FAT1 рдФрд░ FAT2 рдХреНрд▓рд╕реНрдЯрд░ рдЖрд╡рдВрдЯрди рддрд╛рд▓рд┐рдХрд╛рдПрдБ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рд╛рдЗрд▓ рдпрд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ (рдЬреЛ рдПрдХ рдлрд╝рд╛рдЗрд▓ рднреА рд╣реИ) рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХреНрд▓рд╕реНрдЯрд░ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░ рд▓реЗрддреА рд╣реИ, рдФрд░ рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд▓рд╕реНрдЯрд░ рдХреЛ FAT1 рдФрд░ FAT2 (рд╡реЗ рд╕рдорд╛рди рд╣реИрдВ) рдореЗрдВ 32-рдмрд┐рдЯ рдорд╛рди рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ FAT рд╕реЗрд▓ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдЧрд▓реЗ рдХреНрд▓рд╕реНрдЯрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реЛрддреА рд╣реИ, рдЕрдВрддрд┐рдо рдХреНрд▓рд╕реНрдЯрд░ рдХреЛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдкрд╣рд▓реЗ рдХреНрд▓рд╕реНрдЯрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЗрдВрдЧрд┐рдд рдХреА рдЧрдИ рд╣реИред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬреЛ рдбреЗрдЯрд╛ рд╣реИ рд╡рд╣ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рддрд╛рдХрд┐ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд▓ рдореЗрдВ рдирдВрдмрд░ N + 1 рд▓рд┐рдЦрд╛ рдЬрд╛рдП, рдЬрд╣рд╛рдВ N рдкрд┐рдЫрд▓рд╛ рдорд╛рди рд╣реИред
рдпрд╣рд╛рдВ рдкрд╣рд▓реА рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ: рд╣рдорд╛рд░реА рдЧрдгрдирд╛ рдХреА рдЧрдИ 10 x 20Gb рдХреЗ рд▓рд┐рдП, рдпрд╣ рддрд╛рд▓рд┐рдХрд╛ 655360 32-рдмрд┐рдЯ рдорд╛рдиреЛрдВ рдкрд░ рдХрдмреНрдЬрд╛ рдХрд░реЗрдЧреА, рдЬреЛ рдлрд┐рд░ рд╕реЗ рдЙрдкрд▓рдмреНрдз рд░реИрдо рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрди рдирд┐рдпрдореЛрдВ рдХреЛ рд╕рдВрдкреАрдбрд╝рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рд╣рдорд╛рд░реЗ рдЖрджрд┐рдо RLE рдкреИрдХрд┐рдВрдЧ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо, рдХреНрдпреЛрдВрдХрд┐ рдХреЛрдИ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдорд╛рди рдирд╣реАрдВ рд╣реИрдВред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЪреВрдВрдХрд┐ рд╣рдо рдЗрд╕ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдПрдХ рдмрд╛рд░ рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдереЗ, рд╣рдо рд╢рд╛рдпрдж рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ, рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбрд┐рд╡рд╛рдЗрд╕ рдкрд░ рдЬрдирд░реЗрдЯ рдХрд░ рдкрд╛рдПрдВрдЧреЗред
рдПрдХ рдирдЬрд╝рджреАрдХреА рдирдЬрд╝рд░ рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рдХрд┐ рдЖрд╡рдВрдЯрди рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдореВрд▓реНрдп рдкрд┐рдЫрд▓реЗ рдПрдХ рдореЗрдВ рдЕрдзрд┐рдХрддрдо рдореВрд▓реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдЕрдиреБрдХреНрд░рдо рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:
рдирд╛ = рдмреЗрд╕ + (рд╕рд╕реНрдЯреЗрдХреНрдЯ - рдПрдо) * рд╕реНрдЯреЗрдк
рдиреА <- [рдирд╛, рдирд╛ + рез ..]
рдЬрд╣рд╛рдБ Na рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдореВрд▓реНрдп рд╣реИ, рд╕рд╕реНрдЯреЗрдХреНрдЯ рдЕрдиреБрд░реЛрдзрд┐рдд рдХреНрд╖реЗрддреНрд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ (рдпрд╣ рд╣рдорд╛рд░реЗ рдХрд┐рд▓реЗ рдорд╢реАрди рдХреЗ рдвреЗрд░ рдХреЗ рдКрдкрд░ рд╣реЛрдЧрд╛), M, BASE рдФрд░ STEP рд╕реНрдерд┐рд░ рд░реВрдк рд╕реЗ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╕реНрдерд┐рд░рд╛рдВрдХ рд╣реИрдВ, Ni рдЕрдиреБрдХреНрд░рдо рдХреА i-th рд╕рдВрдЦреНрдпрд╛ рд╣реИ, рдФрд░ рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░ рдЗрд╕ рдХреНрд╖реЗрддреНрд░ рдореЗрдВред рдЬрд╛рд╣рд┐рд░ рд╣реИ 512/4ред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдордиреЗ рдПрдХ рдирдпрд╛ рдЕрдиреБрдХреНрд░рдо рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рд╣реИ рдЬреЛ рдЧрддрд┐рд╢реАрд▓ рдбреЗрдЯрд╛ (рдХреНрд╖реЗрддреНрд░ рд╕рдВрдЦреНрдпрд╛) рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореВрд▓реНрдпреЛрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдХреНрд░рдо рдФрд░ рдЖрд╕рдиреНрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрд╛рд░ рдЬреЛрдбрд╝реЗрдВ:
data Chunk = SEQ BS.ByteString | RLE Int Word8 | SER Word32 Word32 | NSER Word32 Int Word32
data Chunk = SEQ BS.ByteString | RLE Int Word8 | SER Word32 Word32 | NSER Word32 Int Word32 -- base offset step | CALLBACK Word8 deriving (Eq, Ord)
рдЖрдЧреЗ рджреЗрдЦрддреЗ рд╣реБрдП, рд╣рдо рдХреЙрд▓рдмреИрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдФрд░ рдирд┐рдпрдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рдлрд╝рд╛рдЗрд▓ рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдХреА рдкреАрдврд╝реА рдХреЗ рдмрд╛рдж рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рддрд╛рдХрд┐ рдбрд┐рд╡рд╛рдЗрд╕ рдлрд░реНрдорд╡реЗрдпрд░ рдПрдХ рдмрдлрд░ рд▓реЗ рдФрд░ рдЗрд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рд╕реЗ рднрд░ рджреЗред
рдирд┐рдпрдореЛрдВ рдХреЗ рдПрдХ рд╕реЗрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рддреБрд░рдВрдд рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХрд╛рд░рдг рдХреЗ рд▓рд┐рдП рдореБрдЭреЗ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рд░реВрдк рдореЗрдВ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереА, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдмрд╛рдЗрдирд░реА рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЛ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбреАрдмрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдХрд╛рд░реНрдп рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпрдХреНрд╖ рдкреАрдврд╝реА рдореЗрдВ рдпрд╣ рдЖрд╕рд╛рди рд╣реИ
рдЧрд▓рддрд┐рдпрд╛рдБ рдХрд░рдирд╛ред
рдпрд╣ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛рдлреА рдмрдбрд╝реА рд╣реИ, рдФрд░ рдПрдХ рдмрдбрд╝реЗ рдбреЗрдЯрд╛ рдХреНрд╖реЗрддреНрд░ рдФрд░ рдПрдХ рдЫреЛрдЯреЗ рдХреНрд▓рд╕реНрдЯрд░ рдЖрдХрд╛рд░ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЧрд░реАрдм рд╣рд╛рд╕реНрдХреЗрд▓ рдХреЗ рдкрд╛рд╕ рдПрдХ рдХрдард┐рди рд╕рдордп рд╣реИред
рдХреБрдЫ рдмрд┐рдВрджреБ рдкрд░, рдПрдХ рдмрдбрд╝реА рдЖрд▓рд╕реА Word32 рд╕реВрдЪреА рд╕реЗ, рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмреБрд░рд╛ рд▓рдЧрд╛, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдЬрд▓реНрджреА рд╕реЗ рдЗрд╕реЗ рдЖрд▓рд╕реА рдмрд╛рдЗрдЯ-рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдкрдбрд╝рд╛ рдФрд░ 32-рдмрд┐рдЯ рдорд╛рдиреЛрдВ рдХреЛ рд╡рд╣рд╛рдВ рд▓рдЧрд╛рдиреЗ рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкреБрдирдГ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП runPut / runGet рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрдбрд╝рд╛ред
рд╣реИрд░рд╛рдиреА рдХреА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдЗрд╕рд╕реЗ рд▓рдЧрднрдЧ рджрд╕ рдЧреБрдирд╛ рдХрд╛ рддреНрд╡рд░рдг рд╣реБрдЖ рдФрд░ рд╕рдм рдХреБрдЫ рдПрдХ рд╕реНрд╡реАрдХрд╛рд░реНрдп рдЧрддрд┐ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рд▓рдЧрд╛, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЖрдкрдХреЛ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬреИрд╕реЗ рдХрд┐ рддреБрд░рдВрдд рдирд┐рдпрдо рдмрдирд╛рдиреЗ рдФрд░ рдбреЗрдЯрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВред
рд▓реЗрдХрд┐рди рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╣реЛрдЧрд╛ред
рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдкреАрдврд╝реА рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдирд┐рдпрдореЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рд╡реЗ рдХрд╛рдлреА рдмрдбрд╝реЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рдХрд╛рдлреА рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ:
type ClusterTable = BS.ByteString genFAT :: ClustSize32 -> Int -> [AllocEntry] -> ClusterTable encodeFAT :: Int -> ClusterTable -> [Rule]
type ClusterTable = BS.ByteString genFAT :: ClustSize32 -> Int -> [AllocEntry] -> ClusterTable encodeFAT :: Int -> ClusterTable -> [Rule]
рддрд╛рд▓рд┐рдХрд╛ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдкрд╣рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрдХреНрдЯрд░ рдХреЛ рдПрдХ рдирд┐рдпрдо REQ a (NSER _ _ _) рдХреЗ рд╕рд╛рде рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдлрд┐рд░ рдЬреЛрдбрд╝реЗ рдореЗрдВ рд╕реЗрдХреНрдЯрд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рджреЛ рд╕реЗрдХреНрдЯрд░ рдорд╛рдиреЛрдВ рдХрд╛ рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдЕрдиреБрдХреНрд░рдо рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕реЗрдХреНрдЯрд░ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдХреЛ рд╕реЗрдХреНрдЯрд░реЛрдВ рдХреА рд╢реНрд░реЗрдгреА рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рд╕реЗ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХрд╛рдлреА рдХреЙрдореНрдкреИрдХреНрдЯ рд╣реЛрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдВ рд▓рд╛ рд╕рдХреЗрдВ:
REQ 32 [SEQ [F8], RLE 2 255, SEQ [0F], RLE 3 255, SEQ [0F],
RLE 3 255, SEQ [0F], RLE 3 255, SEQ [0F], RLE 3 255,
SEQ [0F], RLE 3 255, SEQ [0F], RLE 3 255, SEQ [0F],
SEQ [08], RLE 3 0, SEQ [09], RLE 3 0, SEQ [0A],
RLE 3 0, RLE 3 255, SEQ [0F], SER 12 128]
рд░реЗрдВрдЬ 33,231 [рдПрдирдПрд╕рдИрдЖрд░ 129 33 128]
REQ 232 [SER 25601 25610, RLE 3 255, SEQ [0F], SER 25612 25728]
рд░реЗрдВрдЬ 233 431 [рдПрдирдПрд╕рдИрдЖрд░ 25729 233 128]
REQ 432 [SER 51201 51210, RLE 3 255, SEQ [0F], SER 51212 51328]
рд░реЗрдВрдЬ 433 631 [NSER 51329 433 128]
REQ 632 [SER 76801 76810, RLE 3 255, SEQ [0F], SER 76812 76928]
рд░реЗрдВрдЬ 633 831 [рдПрдирдПрд╕рдИрдЖрд░ 76929 633 128]
REQ 832 [SER 102401 102410, RLE 3 255, SEQ [0F], SER 102412 102528]
RANGE 833 931 [NSER 102529 833 128]
REQ 932 [SER 115201 115210, RLE 3 255, SEQ [0F], RLE 468 0]
Range 933 1056 [RLE 512 0]
рдпрд╣ рдПрдХ рджреЛ рдореЗрдЧрд╛рдмрд╛рдЗрдЯ рдбреЗрдЯрд╛ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмреЗрд╣рддрд░ рд▓рдЧ рд░рд╣рд╛ рд╣реИред
рддрд╛рд▓рд┐рдХрд╛ рдХреА рджреВрд╕рд░реА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рд╕реНрдерд┐рд░рд╛рдВрдХ рдХреЗ рд▓рд┐рдП рд╕рдЯреАрдХ рд╣реИ, рдЗрд╕рд▓рд┐рдП рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдЖрдк рдЗрд╕ рдХреНрд░рдо рдХреЛ рдСрдлрд╕реЗрдЯ рд╕реЗ рдирд┐рд░рдВрддрд░ рдШрдЯрд╛рдХрд░ рдФрд░ рдкрд╣рд▓реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╡рд╣ рдмрд╛рдж рдореЗрдВред
рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ FAT1, FAT2 рдФрд░ DATA рд╣реИрдВред рдпрд╣ рдХреЗрд╡рд▓ BootSect рдФрд░ FAT32 рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИред рдпрд╣ рд╕реНрдереИрддрд┐рдХ рдмрд╛рдЗрдирд░реА рдбреЗрдЯрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдлрд┐рд░ рд╕реЗ Data.Binary.Put рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рд╣рдо рдЗрд╕реЗ рдирд┐рдпрдореЛрдВ рдореЗрдВ рдкреИрдХ рдХрд░рддреЗ рд╣реИрдВред
рдпреЗ рджреЛ рдореЙрдбреНрдпреВрд▓ (рдкреБрдЯ рдФрд░ рдЧреЗрдЯ) рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рдЕрдкрд░рд┐рд╣рд╛рд░реНрдп рд╣реИрдВ рдФрд░ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореИрдВ рдЙрдиреНрд╣реЗрдВ рдЕрд░реНрд▓рдВрдЧ рдореЗрдВ рджреНрд╡рд┐рдЖрдзрд╛рд░реА рдкреИрдЯрд░реНрди рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрдзрд┐рдХ рдмреЛрд▓реА рджреЗрддрд╛ рд╣реВрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рд╡реНрдпрдХреНрддрд┐рдкрд░рдХ рд╣реИред
fatGenBoot32 :: FAT32GenInfo -> BS.ByteString fatGenBoot32 info = addRsvd $ runPut $ do
fatGenBoot32 :: FAT32GenInfo -> BS.ByteString fatGenBoot32 info = addRsvd $ runPut $ do -- BOOT AREA sect0 putBytes [0xEB, 0x58, 0x90] -- 0 JmpBoot putBytes bsOEMName -- OEMName putWord16le bps -- BytesPerSec putWord8 spc -- SectPerClust putWord16le rsvd -- ReservedSecCnt putWord8 2 -- NumFATs putWord16le 0 -- RootEntCnt putWord16le 0 -- TotSec16 putWord8 0xF8 -- Media putWord16le 0 -- FAT16Sz putWord16le 0x3F -- SectPerTract putWord16le 0xFF -- NumHeads putWord32le 0 -- HiddSec putWord32le sectNum -- TotSec32 -- FAT32 Structure putWord32le fsect -- FATSz32 -- ... --
рд╣рдо рдЕрдкрдиреЗ рдкреИрдХрд░ рдХреЛ рдкрд░рд┐рдгрд╛рдо рдкрд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ, рдирд┐рдпрдореЛрдВ рдХреЛ рд╢реНрд░реЗрдгрд┐рдпреЛрдВ рдореЗрдВ рд╡рд┐рд▓рдп рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдирд┐рдпрдореЛрдВ рдХреА рдЕрдВрддрд┐рдо рд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реА рдкреВрд░реА рдлрд╛рдЗрд▓ рдкреНрд░рдгрд╛рд▓реА рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдирд┐рдпрдореЛрдВ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реИред рдпрд╣ рдЙрдирдХреЗ рд▓рд┐рдП рдПрдХ рддреБрд▓рдирд╛ рд╡реГрдХреНрд╖ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрдирд╛ рд╣реБрдЖ рд╣реИ рдФрд░
рдпрд╣ рд╕рдм рдмрд╛рдпрдЯреЗрдХреЛрдб рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВред
рдЖрдЗрдП рдкреЗрдбрд╝ рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВ:
data CmpTree = GEQ Int CmpTree CmpTree | CODE [Rule] deriving (Show) mkCmpTree :: [Rule] -> CmpTree mkCmpTree r = mkTree' rulemap where rulemap = M.fromList $ map (\x -> (fsect x, x)) r splitGeq nm = let (a, b, c) = M.splitLookup nm in (a, c `M.union` (maybe M.empty (M.singleton n) b)) mkTree' xs | M.null xs = CODE [] | M.size xs < 3 = CODE (map snd (M.toList xs)) | otherwise = let ks = map fst $ M.toAscList xs n = ks !! (length ks `div` 2) (le, geq) = splitGeq n xs in GEQ n (mkTree' le) (mkTree' geq)
data CmpTree = GEQ Int CmpTree CmpTree | CODE [Rule] deriving (Show) mkCmpTree :: [Rule] -> CmpTree mkCmpTree r = mkTree' rulemap where rulemap = M.fromList $ map (\x -> (fsect x, x)) r splitGeq nm = let (a, b, c) = M.splitLookup nm in (a, c `M.union` (maybe M.empty (M.singleton n) b)) mkTree' xs | M.null xs = CODE [] | M.size xs < 3 = CODE (map snd (M.toList xs)) | otherwise = let ks = map fst $ M.toAscList xs n = ks !! (length ks `div` 2) (le, geq) = splitGeq n xs in GEQ n (mkTree' le) (mkTree' geq)
рдпрд╣ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдХрд▓реНрдк рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдирд┐рдпрдо рд╕реМ рд╕реЗ рдХрдо рд╣реЛ рдЧрдП рд╣реИрдВ, рдЖрдк рдЕрднреА рддрдХ рдЪрд┐рдВрддрд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред
рдпрд╣ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди, рдХрдорд╛рдВрдб рдХреЗ рд╕реЗрдЯ рдФрд░ рдХрдВрдкрд╛рдЗрд▓рд░ рдкрд░ рдирд┐рд░реНрднрд░ рд╣реИ:
- , - class OpcodeCL a where isRLE :: a -> Bool arity0 :: a -> Bool arity1 :: a -> Bool arity2 :: a -> Bool arity3 :: a -> Bool firstCode :: a lastCode :: a data Opcode = DUP | DROP | CONST | CRNG | JNZ | JZ | JGQ | JNE | JMP | CALLT | CALL | RET | NOT | EQ | NEQ | GT | LE | GQ | LQ | RNG | LOADS2 | LOADS3 | LOADS4 | LOADS5 | LOADS6 | LOADS7 | LOADS8 | LOADS9 | LOADS10 | LOADSN | SER | NSER | NSER128 | RLE1 | RLE2 | RLE3 | RLE4 | RLE5 | RLE6 | RLE7 | RLE8 | RLE16 | RLE32 | RLE64 | RLE128 | RLE256 | RLE512 | RLEN | OUTLE | OUTBE | OUTB | NOP | CALLN | DEBUG | EXIT deriving (Eq, Ord, Enum, Show) data CmdArg = W32 Word32 | W16 Word16 | W8 Word8 | ADDR Addr data Addr = ALabel Label | AOffset Int data Cmd = Cmd0 Opcode | CmdConst Word32 | Cmd1 Opcode CmdArg | Cmd2 Opcode CmdArg CmdArg | Cmd3 Opcode CmdArg CmdArg CmdArg | CmdJmp Opcode Addr | CmdCondJmp Opcode Addr | CmdLabel Label | RawByte Word8 type Label = Int type Block = (Label, [Cmd])
- , - class OpcodeCL a where isRLE :: a -> Bool arity0 :: a -> Bool arity1 :: a -> Bool arity2 :: a -> Bool arity3 :: a -> Bool firstCode :: a lastCode :: a data Opcode = DUP | DROP | CONST | CRNG | JNZ | JZ | JGQ | JNE | JMP | CALLT | CALL | RET | NOT | EQ | NEQ | GT | LE | GQ | LQ | RNG | LOADS2 | LOADS3 | LOADS4 | LOADS5 | LOADS6 | LOADS7 | LOADS8 | LOADS9 | LOADS10 | LOADSN | SER | NSER | NSER128 | RLE1 | RLE2 | RLE3 | RLE4 | RLE5 | RLE6 | RLE7 | RLE8 | RLE16 | RLE32 | RLE64 | RLE128 | RLE256 | RLE512 | RLEN | OUTLE | OUTBE | OUTB | NOP | CALLN | DEBUG | EXIT deriving (Eq, Ord, Enum, Show) data CmdArg = W32 Word32 | W16 Word16 | W8 Word8 | ADDR Addr data Addr = ALabel Label | AOffset Int data Cmd = Cmd0 Opcode | CmdConst Word32 | Cmd1 Opcode CmdArg | Cmd2 Opcode CmdArg CmdArg | Cmd3 Opcode CmdArg CmdArg CmdArg | CmdJmp Opcode Addr | CmdCondJmp Opcode Addr | CmdLabel Label | RawByte Word8 type Label = Int type Block = (Label, [Cmd])
рдХрд╛рд╢, рдпрд╣рд╛рдБ рдПрдХ рд╕рд░рд▓ рд╣рд╛рд╕реНрдХреЗрд▓ рдЯрд╛рдЗрдк рд╕рд┐рд╕реНрдЯрдо рдпрд╛рдж рдХрд┐рдпрд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ: рдореИрдВ рдХрдорд╛рдВрдбреНрд╕ рдФрд░ рдЙрдирдХреА рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рдВрдХрд▓рди-рд╕рдордп рдХреЗ рд╣рдорд▓рд╛рд╡рд░реЛрдВ рдХреЛ рд╕реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рддрд╛рдХрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЧрд▓рдд рдУрдкреЛрдб рдХреЗ рд╕рд╛рде рдПрдХ рдЯреАрдо рдмрдирд╛рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛред рд▓реЗрдХрд┐рди рдЖрдк рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдк рдкреНрд░рддреНрдпреЗрдХ рдУрдкрдХреЛрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдкреНрд░рдХрд╛рд░ рдХрд╛ рдкрд░рд┐рдЪрдп рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдХрдорд╛рдВрдб рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рдЪрд▓рд┐рдд рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░ рд╣реИ рдФрд░ рдлрд┐рд░ рднреА opcodes рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдмреЗрд╣рддрд░ рд╕рдордп рддрдХ рдЗрд╕реЗ рдмрдВрдж рд░рдЦреЗрдВ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЬреЛ рд╣реИ рдЙрд╕рдХреЗ рд╕рд╛рде рдЪрд▓реЛред рд╡реИрд╕реЗ рднреА, рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рдЗрд╕рд▓рд┐рдП рдЬреЛ рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╕рд╛рдордиреЗ рдЖрдПрдВрдЧреА, рд╡реЗ рд╡рд╣рд╛рдВ рдкреЙрдк рдЕрдк рд╣реЛрдВрдЧреАред
рддреЛ, рдПрдХ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХрдорд╛рдВрдб рд╕рд┐рд╕реНрдЯрдо рд╣реИ, рдЕрдм рд╣рдореЗрдВ рдЕрдкрдиреЗ рдирд┐рдпрдореЛрдВ рд╕реЗ рдирд┐рд░реНрдорд┐рдд рддреБрд▓рдирд╛рддреНрдордХ рдкреЗрдбрд╝ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
mkVMCode :: CmpTree -> [Block] mkVMCode xs = normalize maxl code -- skip scanT :: CmpTree -> GenM () scanT (GEQ n left right) = do s <- newLabel l <- runGen' (scanT left) >>= withLabel r <- runGen' (scanT right) >>= withLabel _ex <- newLabel label s dup cnst n jgq (labelOf r) block l >> jmp _ex block r >> label _ex scanT (CODE []) = op0 EXIT scanT (CODE rules) = mapM_ scanR rules scanR :: Rule -> GenM () scanR ( REQ n code ) = do s <- newLabel code' <- runGen' (scanmC code) >>= withLabel ex <- newLabel label s dup cnst n jne ex block code' label ex scanR ( RANGE ab code ) = do s <- newLabel code' <- runGen' (scanmC code) >>= withLabel ex <- newLabel label s dup crng ab jz ex block code' label ex -- skip
mkVMCode :: CmpTree -> [Block] mkVMCode xs = normalize maxl code -- skip scanT :: CmpTree -> GenM () scanT (GEQ n left right) = do s <- newLabel l <- runGen' (scanT left) >>= withLabel r <- runGen' (scanT right) >>= withLabel _ex <- newLabel label s dup cnst n jgq (labelOf r) block l >> jmp _ex block r >> label _ex scanT (CODE []) = op0 EXIT scanT (CODE rules) = mapM_ scanR rules scanR :: Rule -> GenM () scanR ( REQ n code ) = do s <- newLabel code' <- runGen' (scanmC code) >>= withLabel ex <- newLabel label s dup cnst n jne ex block code' label ex scanR ( RANGE ab code ) = do s <- newLabel code' <- runGen' (scanmC code) >>= withLabel ex <- newLabel label s dup crng ab jz ex block code' label ex -- skip
рдпрд╣рд╛рдВ рд▓реЗрдЦрдХ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдИрдбреАрдПрд╕рдПрд▓ рдХреЗ рд╕рд╛рде рд╕рд╛рдорд╛рди рддреИрдпрд╛рд░ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рд▓реЗрдЦрдХ рдореЛрдирд╛рдж рдХреЗ рдКрдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рддреБрд▓рдирд╛рддреНрдордХ рдкреЗрдбрд╝ рд╕реЗ рдлреНрд▓реИрдЯ рдХреЛрдб рдХреА рдкреАрдврд╝реА рдмрд╣реБрдд рд╕реЗ "рд╕реНрдиреЙрдЯ" рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдмреНрд▓реЙрдХ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдХреА рд▓рдВрдмреА рд╢реНрд░реГрдВрдЦрд▓рд╛рдУрдВ рдХреЗ рд▓рд┐рдП:
L1: ... JMP L2 L2: JMP L3 L3: JMP L4 L4: EXIT
L1: ... JMP L2 L2: JMP L3 L3: JMP L4 L4: EXIT
рдЕрдЧрд▓реЗ рдмреНрд▓реЙрдХ рдореЗрдВ рдХреВрджрдирд╛ рдФрд░ рдЗрддрдиреЗ рдкрд░ред рд╕рд╛рдорд╛рдиреНрдпрдХреГрдд рдЗрди рд╡рд┐рд░реЛрдзрд╛рднрд╛рд╕реЛрдВ рдХреЛ рд╕рдорд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдХреЛрдб рдХреЛ рдмреНрд▓реЙрдХ рдореЗрдВ рддреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдПрдХ рд▓реЗрдмрд▓ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд▓реЗ рдмреНрд▓реЙрдХ рдХрдорд╛рдВрдб рдореЗрдВ рдмрд┐рдирд╛ рд╢рд░реНрдд рдХреВрдж рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдХреЛрдИ рд╕рд╢рд░реНрдд рдпрд╛ рдмрд┐рдирд╛ рд╢рд░реНрдд рдХреВрдж рдХрдорд╛рдВрдб рдирд╣реАрдВ рд╣реИрдВ, рд╡реЗ рдХреЗрд╡рд▓ рдЕрдВрдд рдореЗрдВ рдорд╛рдиреНрдп рд╣реИрдВред рд▓реЗрдмрд▓ рдСрдлрд╝рд╕реЗрдЯ рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдРрд╕реЗ рдмреНрд▓реЙрдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдмрд╛рдж, рдЖрдк рдмреНрд▓реЙрдХ рдХреЛ рдорд░реНрдЬ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рдВрдХреНрд░рдордгреЛрдВ рд╕реЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рд╣рдо рд╕реБрдВрджрд░ рдХрд┐рд▓реЗ рдЫрдкрд╛рдИ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреЗ рдмрд╛рдпреЛрдЯреЗрдХ рдХреЗ рд▓рд┐рдП рд╢реЛ рдХрд╛ рдЙрджрд╛рд╣рд░рдг рд▓рд┐рдЦреЗрдВрдЧреЗ рдФрд░ рджреЗрдЦреЗрдВ рдХрд┐ рдмреНрд▓реЙрдХ рдХреЗ рдЕрдиреБрдХреВрд▓рди рдХреЗ рдмрд╛рдж рд╣рдореЗрдВ рдХреНрдпрд╛ рдорд┐рд▓реЗрдЧрд╛:
... L215: DUP CONST 2122 JGQ L220 DUP CRNG 00000843 00000849 JZ L235 RLE512 00 EXIT L220: DUP CRNG 0000084A 000C8869 JZ L223 LOADS2 BYTE 48 BYTE 45 RLE2 4C LOADS7 BYTE 4F BYTE 20 BYTE 57 BYTE 4F BYTE 52 BYTE 4C BYTE 44 RLE2 21 CALLN 00 EXIT L223: DUP CRNG 000C886A 000E1869 JZ L235 RLE512 00 CALLN 00 ;; --- , EXIT ;; L235: EXIT ... L0: LOADS5 BYTE 02 BYTE 08 BYTE 20 BYTE 00 BYTE 02 RET ...
... L215: DUP CONST 2122 JGQ L220 DUP CRNG 00000843 00000849 JZ L235 RLE512 00 EXIT L220: DUP CRNG 0000084A 000C8869 JZ L223 LOADS2 BYTE 48 BYTE 45 RLE2 4C LOADS7 BYTE 4F BYTE 20 BYTE 57 BYTE 4F BYTE 52 BYTE 4C BYTE 44 RLE2 21 CALLN 00 EXIT L223: DUP CRNG 000C886A 000E1869 JZ L235 RLE512 00 CALLN 00 ;; --- , EXIT ;; L235: EXIT ... L0: LOADS5 BYTE 02 BYTE 08 BYTE 20 BYTE 00 BYTE 02 RET ...
, , , . рдпрд╣ рдХрд░ рджреЗрдЧрд╛ред
- , , , .
, , , , . , , vm , . . -eDSL , , .
Writer, тАж
stubs :: String stubs = envFile $ do comment "top of the file" put "#include <stdint.h>" put "#include \"emufatstubs.h\"" defines ... stmt (pt codeType ++ op `assign` "code") endl push a "n" put "for(;;)" braces $ indented $ do put "switch(*op)" braces $ do forM_ codes $ \op -> do put (printf "case %s:" (show op)) indented $ decode op endl put "default:" indented $ exit exitLabel indented $ stmt "return 0" ... decode (CRNG) = do skip "1" stmt (tmp0 `assign` pop a) stmt (tmp1 `assign` decode32) >> skip "4" stmt (tmp2 `assign` decode32) >> skip "4" push a ( _and (tmp0 `gq` tmp1) (tmp0 `lq` tmp2) ) next decode (CALL) = do skip "1" stmt (tmp0 `assign` decode32) >> skip "4" stmt (push' r pc') jump tmp0 ...
stubs :: String stubs = envFile $ do comment "top of the file" put "#include <stdint.h>" put "#include \"emufatstubs.h\"" defines ... stmt (pt codeType ++ op `assign` "code") endl push a "n" put "for(;;)" braces $ indented $ do put "switch(*op)" braces $ do forM_ codes $ \op -> do put (printf "case %s:" (show op)) indented $ decode op endl put "default:" indented $ exit exitLabel indented $ stmt "return 0" ... decode (CRNG) = do skip "1" stmt (tmp0 `assign` pop a) stmt (tmp1 `assign` decode32) >> skip "4" stmt (tmp2 `assign` decode32) >> skip "4" push a ( _and (tmp0 `gq` tmp1) (tmp0 `lq` tmp2) ) next decode (CALL) = do skip "1" stmt (tmp0 `assign` decode32) >> skip "4" stmt (push' r pc') jump tmp0 ...
, :
#define DEFSTACK(n, t, l) ... #define RESET(a) ... #define PTOP(a) ... #define TOP(a) ... #define POP(a) ... #define PUSH(a,v) ... #define NEXT(x) ... #define JUMP(x, b, o) ... #define SKIP(x, n) ... #define PC(x, b) ... #define DECODE32(op) ... #define DECODE8(op) ... ... DEFSTACK(a, uint32_t, 16); DEFSTACK(r, uint32_t, 8); uint32_t tmp0; uint32_t tmp1; uint32_t tmp2; uint32_t tmp3; ... uint8_t *op = code; PUSH(a, n); for(;;) { switch(*op) { ... case CRNG: SKIP(op, (1)); tmp0 = POP(a); tmp1 = DECODE32(op); SKIP(op, (4)); tmp2 = DECODE32(op); SKIP(op, (4)); PUSH(a, ((tmp0 >= tmp1) && (tmp0 <= tmp2))); NEXT(op); ... case CALL: SKIP(op, (1)); tmp0 = DECODE32(op); SKIP(op, (4)); PUSH(r, PC(op, code)); JUMP(op, code, tmp0); ... case EXIT: goto _exit; default: goto _exit; } } _exit: return 0; ...
#define DEFSTACK(n, t, l) ... #define RESET(a) ... #define PTOP(a) ... #define TOP(a) ... #define POP(a) ... #define PUSH(a,v) ... #define NEXT(x) ... #define JUMP(x, b, o) ... #define SKIP(x, n) ... #define PC(x, b) ... #define DECODE32(op) ... #define DECODE8(op) ... ... DEFSTACK(a, uint32_t, 16); DEFSTACK(r, uint32_t, 8); uint32_t tmp0; uint32_t tmp1; uint32_t tmp2; uint32_t tmp3; ... uint8_t *op = code; PUSH(a, n); for(;;) { switch(*op) { ... case CRNG: SKIP(op, (1)); tmp0 = POP(a); tmp1 = DECODE32(op); SKIP(op, (4)); tmp2 = DECODE32(op); SKIP(op, (4)); PUSH(a, ((tmp0 >= tmp1) && (tmp0 <= tmp2))); NEXT(op); ... case CALL: SKIP(op, (1)); tmp0 = DECODE32(op); SKIP(op, (4)); PUSH(r, PC(op, code)); JUMP(op, code, tmp0); ... case EXIT: goto _exit; default: goto _exit; } } _exit: return 0; ...
, . : switch , , . , , . , . Enum Opcode (. ).
, , , , GCC . GCC, switch-based .
. . тАФ VM , . , , , .
тАж
testJne = makeTest $ do [l1, l2] <- replicateM 2 newLabel cnst 1 cnst 2 jne l1 exit label l1 cnst 0xCAFEBABE -- 1 outle cnst 1 cnst 1 jne l2 cnst 0xCAFEBABE -- 2 outle exit label l2 cnst 0xFFFFFFFF outle
testJne = makeTest $ do [l1, l2] <- replicateM 2 newLabel cnst 1 cnst 2 jne l1 exit label l1 cnst 0xCAFEBABE -- 1 outle cnst 1 cnst 1 jne l2 cnst 0xCAFEBABE -- 2 outle exit label l2 cnst 0xFFFFFFFF outle
тАж -:
tests = testSuite $ do ... test "testJne" testJne (assert $ do a <- getWord32le b <- getWord32le return $ a == 0xCAFEBABE && b == 0xCAFEBABE)
tests = testSuite $ do ... test "testJne" testJne (assert $ do a <- getWord32le b <- getWord32le return $ a == 0xCAFEBABE && b == 0xCAFEBABE)
:
runTest :: String -> Test -> IO Bool runTest path (T{tname=nm, tcode=code, tcheck = tc})= do let bin = toBinary code (inp,out,err,pid) <- runInteractiveProcess path [] Nothing Nothing BS.hPut inp bin hClose inp res <- BS.hGetContents out let r = tc res hPutStrLn stderr (printf "test %-24s : %s" nm (if r then "PASSED" else "FAILED !")) return r ... case args of ... ... -> mapM_ (runTest path) tests ... ...
runTest :: String -> Test -> IO Bool runTest path (T{tname=nm, tcode=code, tcheck = tc})= do let bin = toBinary code (inp,out,err,pid) <- runInteractiveProcess path [] Nothing Nothing BS.hPut inp bin hClose inp res <- BS.hGetContents out let r = tc res hPutStrLn stderr (printf "test %-24s : %s" nm (if r then "PASSED" else "FAILED !")) return r ... case args of ... ... -> mapM_ (runTest path) tests ... ...
, core ( )
... test testJgq : PASSED test testJne : PASSED test testCallRet1 : PASSED ...
... test testJgq : PASSED test testJne : PASSED test testCallRet1 : PASSED ...
:
... helloFile = const $ BS8.pack "HELLO WORLD!!" fatSample2 = filesystem $ do file "file0" (16384) helloFile dir "A" $ do file "file1" (megs 100) helloFile dir "C" $ do file "file3" (megs 100) helloFile file "file4" (megs 100) helloFile file "file5" (megs 100) helloFile dir "E" $ emptyDir dir "B" $ do file "file2" (megs 50) emptyFile ... $ ./FatGen bin | cbits/genfat 1000000 > fat.img 521106 / 1000000 ( 13027 kb/s) $ fsck.vfat ./fat.img dosfsck 3.0.9, 31 Jan 2010, FAT32, LFN Free cluster summary uninitialized (should be 15863) ./fat.img: 10 files, 115209/131072 clusters $ sudo mount -o loop ./fat.img /mnt/test2/ $ find /mnt/test2/ /mnt/test2/ /mnt/test2/FILE0 /mnt/test2/A /mnt/test2/A/FILE1 /mnt/test2/A/C /mnt/test2/A/C/FILE3 /mnt/test2/A/C/FILE4 /mnt/test2/A/C/FILE5 /mnt/test2/A/C/E /mnt/test2/B /mnt/test2/B/FILE2
... helloFile = const $ BS8.pack "HELLO WORLD!!" fatSample2 = filesystem $ do file "file0" (16384) helloFile dir "A" $ do file "file1" (megs 100) helloFile dir "C" $ do file "file3" (megs 100) helloFile file "file4" (megs 100) helloFile file "file5" (megs 100) helloFile dir "E" $ emptyDir dir "B" $ do file "file2" (megs 50) emptyFile ... $ ./FatGen bin | cbits/genfat 1000000 > fat.img 521106 / 1000000 ( 13027 kb/s) $ fsck.vfat ./fat.img dosfsck 3.0.9, 31 Jan 2010, FAT32, LFN Free cluster summary uninitialized (should be 15863) ./fat.img: 10 files, 115209/131072 clusters $ sudo mount -o loop ./fat.img /mnt/test2/ $ find /mnt/test2/ /mnt/test2/ /mnt/test2/FILE0 /mnt/test2/A /mnt/test2/A/FILE1 /mnt/test2/A/C /mnt/test2/A/C/FILE3 /mnt/test2/A/C/FILE4 /mnt/test2/A/C/FILE5 /mnt/test2/A/C/E /mnt/test2/B /mnt/test2/B/FILE2
: , . eDSL.
2Kb , 2Kb GSM/EDGE, 3G.
, , .
.