daShangDao_kfzgw-info/config/config.go
2026-02-27 11:46:40 +08:00

272 lines
6.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
/*
#include <stdlib.h>
*/
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() {
}