package main /* #include */ import "C" import ( "encoding/json" "fmt" "io" "net/http" "os" "path/filepath" "strings" "unsafe" "gopkg.in/ini.v1" "gopkg.in/yaml.v3" ) // ConfigReader 配置文件读取器接口 type ConfigReader interface { ReadConfig(data []byte) (string, error) } // JSONConfigReader JSON配置文件读取器 type JSONConfigReader struct{} func (r *JSONConfigReader) ReadConfig(data []byte) (string, error) { var result map[string]interface{} if err := json.Unmarshal(data, &result); err != nil { if strings.Contains(err.Error(), "cannot unmarshal array into Go value of type map[string]interface {}") { // 尝试解析为数组 var arrayResult []map[string]interface{} if arrayErr := json.Unmarshal(data, &arrayResult); arrayErr != nil { return "", fmt.Errorf("JSON解析错误: %v", err) } arrayResultStr, err := json.Marshal(arrayResult) if err != nil { return "", fmt.Errorf("JSON序列化失败: %v", err) } return string(arrayResultStr), nil } return "", fmt.Errorf("JSON解析错误: %v", err) } resultStr, err := json.Marshal(result) if err != nil { return "", fmt.Errorf("JSON序列化失败: %v", err) } return string(resultStr), nil } // YAMLConfigReader YAML配置文件读取器 type YAMLConfigReader struct{} func (r *YAMLConfigReader) ReadConfig(data []byte) (string, error) { var result map[string]interface{} if err := yaml.Unmarshal(data, &result); err != nil { return "", fmt.Errorf("YAML解析错误: %v", err) } resultStr, err := json.Marshal(result) if err != nil { return "", fmt.Errorf("JSON序列化失败: %v", err) } return string(resultStr), nil } // INIConfigReader INI配置文件读取器 type INIConfigReader struct{} func (r *INIConfigReader) ReadConfig(data []byte) (string, error) { cfg, err := ini.Load(data) if err != nil { return "", fmt.Errorf("INI解析错误: %v", err) } result := make(map[string]interface{}) // 将INI结构转换为map for _, section := range cfg.Sections() { sectionName := section.Name() if sectionName == "DEFAULT" { sectionName = "default" } sectionMap := make(map[string]interface{}) for _, key := range section.Keys() { sectionMap[key.Name()] = key.Value() } // 如果是默认节,直接合并到顶层 if sectionName == "default" { for k, v := range sectionMap { result[k] = v } } else { result[sectionName] = sectionMap } } resultStr, err := json.Marshal(result) if err != nil { return "", fmt.Errorf("JSON序列化失败: %v", err) } return string(resultStr), nil } // ConfigProcessor 配置处理器 type ConfigProcessor struct { readers map[string]ConfigReader } // NewConfigProcessor 创建配置处理器 func NewConfigProcessor() *ConfigProcessor { return &ConfigProcessor{ readers: map[string]ConfigReader{ "json": &JSONConfigReader{}, "yaml": &YAMLConfigReader{}, "yml": &YAMLConfigReader{}, "ini": &INIConfigReader{}, "conf": &INIConfigReader{}, }, } } // GetFileExtension 获取文件扩展名 func (p *ConfigProcessor) GetFileExtension(fileName string) string { ext := strings.ToLower(filepath.Ext(fileName)) if ext != "" { return ext[1:] // 去掉点号 } return "" } // GetReader 根据文件扩展名获取对应的读取器 func (p *ConfigProcessor) GetReader(fileName string) (ConfigReader, error) { ext := p.GetFileExtension(fileName) if ext == "" { return nil, fmt.Errorf("无法识别文件类型: %s", fileName) } reader, exists := p.readers[ext] if !exists { return nil, fmt.Errorf("不支持的文件类型: %s", ext) } return reader, nil } // ReadConfigFile 读取配置文件 // 参数: filePath:文件路径 fileName:文件名 func (p *ConfigProcessor) readConfigFile(filePath, fileName string) (string, error) { // 构建完整文件路径 fullPath := p.buildFullPath(filePath, fileName) // 读取文件内容 data, err := p.readFileContent(fullPath) if err != nil { return "", err } reader, err := p.GetReader(fileName) if err != nil { return "", err } return reader.ReadConfig(data) } // buildFullPath 构建完整文件路径 func (p *ConfigProcessor) buildFullPath(filePath, fileName string) string { // 如果文件路径为空,使用当前目录 if filePath == "" { return fileName } // 检查是否为HTTP/HTTPS URL if strings.HasPrefix(filePath, "http://") || strings.HasPrefix(filePath, "https://") { // 确保URL以斜杠结尾 if !strings.HasSuffix(filePath, "/") { filePath += "/" } return filePath + fileName } // 本地文件路径 return filepath.Join(filePath, fileName) } // readFileContent 读取文件内容 func (p *ConfigProcessor) readFileContent(fullPath string) ([]byte, error) { // 检查是否为HTTP/HTTPS URL if strings.HasPrefix(fullPath, "http://") || strings.HasPrefix(fullPath, "https://") { return p.readFromHTTP(fullPath) } // 本地文件 return p.readFromLocal(fullPath) } // readFromLocal 从本地文件读取内容 func (p *ConfigProcessor) readFromLocal(filePath string) ([]byte, error) { // 检查文件是否存在 if _, err := os.Stat(filePath); os.IsNotExist(err) { return nil, fmt.Errorf("文件不存在: %s", filePath) } return os.ReadFile(filePath) } // readFromHTTP 从HTTP URL读取内容 func (p *ConfigProcessor) readFromHTTP(url string) ([]byte, error) { resp, err := http.Get(url) if err != nil { return nil, fmt.Errorf("HTTP请求失败: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("HTTP请求失败,状态码: %d", resp.StatusCode) } return io.ReadAll(resp.Body) } // PrettyPrint 美化打印配置内容 func PrettyPrint(config map[string]interface{}, indent string) { for key, value := range config { switch v := value.(type) { case map[string]interface{}: fmt.Printf("%s%s:\n", indent, key) PrettyPrint(v, indent+" ") default: fmt.Printf("%s%s: %v\n", indent, key, v) } } } // ReadConfigFile 读取配置文件 // //export ReadConfigFile func ReadConfigFile(filePath, fileName *C.char) *C.char { filePathStr := C.GoString(filePath) fileNameStr := C.GoString(fileName) info, err := NewConfigProcessor().readConfigFile(filePathStr, fileNameStr) if err != nil { return C.CString(err.Error()) } return C.CString(info) } // FreeCString 释放C字符串内存 // //export FreeCString func FreeCString(str *C.char) { C.free(unsafe.Pointer(str)) } // CSV_VERSION 版本号 const ( CSV_VERSION = "v1" ) // 获取版本信息 // //export GetVersion func GetVersion() *C.char { return C.CString(CSV_VERSION) } // 主函数 func main() { }