2222package fs
2323
2424import (
25- "github.com/rabbitstack/fibratus/pkg/sys"
2625 "os"
2726 "strings"
27+ "sync"
28+
29+ "github.com/rabbitstack/fibratus/pkg/sys"
2830)
2931
3032const deviceOffset = 8
3133const vmsmbDevice = `\Device\vmsmb`
3234
33- // DevMapper is the minimal interface for the device converters.
34- type DevMapper interface {
35- // Convert receives the fully qualified file path and replaces the DOS device name with a drive letter.
36- Convert (filename string ) string
35+ var (
36+ devMapper * DevMapper
37+ onceDevMapper sync.Once
38+ )
39+
40+ // GetDevMapper builds and returns the singleton dev mapper instance.
41+ func GetDevMapper () * DevMapper {
42+ onceDevMapper .Do (func () {
43+ devMapper = newDevMapper ()
44+ })
45+ return devMapper
3746}
3847
39- type mapper struct {
48+ // DevMapper converts the fully qualified file path and
49+ // replaces the DOS device name with a drive letter.
50+ type DevMapper struct {
4051 cache map [string ]string
4152 sysroot string
4253}
4354
44- // NewDevMapper creates a new instance of the DOS device replacer.
45- func NewDevMapper () DevMapper {
46- m := & mapper {
55+ // newDevMapper creates a new instance of the DOS device replacer.
56+ func newDevMapper () * DevMapper {
57+ m := & DevMapper {
4758 cache : make (map [string ]string ),
4859 }
4960
@@ -65,39 +76,39 @@ func NewDevMapper() DevMapper {
6576 return m
6677}
6778
68- func (m * mapper ) Convert (filename string ) string {
69- if filename == "" || len (filename ) < deviceOffset {
70- return filename
79+ func (m * DevMapper ) Convert (path string ) string {
80+ if path == "" || len (path ) < deviceOffset {
81+ return path
7182 }
7283
7384 // find the backslash index
74- n := strings .Index (filename [deviceOffset :], "\\ " )
85+ n := strings .Index (path [deviceOffset :], "\\ " )
7586 if n < 0 {
76- if f , ok := m .cache [filename ]; ok {
87+ if f , ok := m .cache [path ]; ok {
7788 return f
7889 }
79- return filename
90+ return path
8091 }
8192
82- dev := filename [:n + deviceOffset ]
93+ dev := path [:n + deviceOffset ]
8394 if drive , ok := m .cache [dev ]; ok {
8495 // the mapping for the DOS device exists
85- return strings .Replace (filename , dev , drive , 1 )
96+ return strings .Replace (path , dev , drive , 1 )
8697 }
8798
8899 switch {
89100 case dev == vmsmbDevice :
90101 // convert Windows Sandbox path to native path
91- if n := strings .Index (filename , "os" ); n > 0 {
92- return "C:" + filename [n + 2 :]
102+ if n := strings .Index (path , "os" ); n > 0 {
103+ return "C:" + path [n + 2 :]
93104 }
94- case strings .HasPrefix (filename , "\\ SystemRoot" ):
105+ case strings .HasPrefix (path , "\\ SystemRoot" ):
95106 // normalize paths starting with SystemRoot
96- return strings .Replace (filename , "\\ SystemRoot" , m .sysroot , 1 )
97- case strings .HasPrefix (filename , "\\ SYSTEMROOT" ):
107+ return strings .Replace (path , "\\ SystemRoot" , m .sysroot , 1 )
108+ case strings .HasPrefix (path , "\\ SYSTEMROOT" ):
98109 // normalize paths starting with SYSTEMROOT
99- return strings .Replace (filename , "\\ SYSTEMROOT" , m .sysroot , 1 )
110+ return strings .Replace (path , "\\ SYSTEMROOT" , m .sysroot , 1 )
100111 }
101112
102- return filename
113+ return path
103114}
0 commit comments