【9】Strongswan collections —— enumerator

//以目錄枚舉為例子,說明enumerator,從源碼剝離可運行

#include <stdio.h>
#include <stdbool.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <sys/time.h>
#include <stdarg.h>/*** This macro allows counting the number of arguments passed to a macro.* Combined with the VA_ARGS_DISPATCH() macro this can be used to implement* macro overloading based on the number of arguments.* 0 to 10 arguments are currently supported.*/
#define VA_ARGS_NUM(...) _VA_ARGS_NUM(0,##__VA_ARGS__,10,9,8,7,6,5,4,3,2,1,0)
#define _VA_ARGS_NUM(_0,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,NUM,...) NUM/*** This macro can be used to dispatch a macro call based on the number of given* arguments, for instance:** @code* #define MY_MACRO(...) VA_ARGS_DISPATCH(MY_MACRO, __VA_ARGS__)(__VA_ARGS__)* #define MY_MACRO1(arg) one_arg(arg)* #define MY_MACRO2(arg1,arg2) two_args(arg1,arg2)* @endcode** MY_MACRO() can now be called with either one or two arguments, which will* resolve to one_arg(arg) or two_args(arg1,arg2), respectively.*/
#define VA_ARGS_DISPATCH(func, ...) _VA_ARGS_DISPATCH(func, VA_ARGS_NUM(__VA_ARGS__))
#define _VA_ARGS_DISPATCH(func, num) __VA_ARGS_DISPATCH(func, num)
#define __VA_ARGS_DISPATCH(func, num) func ## num/*** Assign variadic arguments to the given variables.** @note The order and types of the variables are significant and must match the* variadic arguments passed to the function that calls this macro exactly.** @param last		the last argument before ... in the function that calls this* @param ...		variable names*/
#define VA_ARGS_GET(last, ...) ({ \va_list _va_args_get_ap; \va_start(_va_args_get_ap, last); \_VA_ARGS_GET_ASGN(__VA_ARGS__) \va_end(_va_args_get_ap); \
})/*** Assign variadic arguments from a va_list to the given variables.** @note The order and types of the variables are significant and must match the* variadic arguments passed to the function that calls this macro exactly.** @param list		the va_list variable in the function that calls this* @param ...		variable names*/
#define VA_ARGS_VGET(list, ...) ({ \va_list _va_args_get_ap; \va_copy(_va_args_get_ap, list); \_VA_ARGS_GET_ASGN(__VA_ARGS__) \va_end(_va_args_get_ap); \
})#define _VA_ARGS_GET_ASGN(...) VA_ARGS_DISPATCH(_VA_ARGS_GET_ASGN, __VA_ARGS__)(__VA_ARGS__)
#define _VA_ARGS_GET_ASGN1(v1) __VA_ARGS_GET_ASGN(v1)
#define _VA_ARGS_GET_ASGN2(v1,v2) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2)
#define _VA_ARGS_GET_ASGN3(v1,v2,v3) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \__VA_ARGS_GET_ASGN(v3)
#define _VA_ARGS_GET_ASGN4(v1,v2,v3,v4) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \__VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4)
#define _VA_ARGS_GET_ASGN5(v1,v2,v3,v4,v5) __VA_ARGS_GET_ASGN(v1) __VA_ARGS_GET_ASGN(v2) \__VA_ARGS_GET_ASGN(v3) __VA_ARGS_GET_ASGN(v4) __VA_ARGS_GET_ASGN(v5)
#define __VA_ARGS_GET_ASGN(v) v = va_arg(_va_args_get_ap, typeof(v));#ifndef FALSE
# define FALSE false
#endif /* FALSE */
#ifndef TRUE
# define TRUE  true
#endif /* TRUE */typedef struct enumerator_t enumerator_t;struct enumerator_t {/*** 枚舉集合。** enumerate() 方法接受可變數量的指針參數(枚舉到的值被寫入這些參數)**通常只需分配調用枚舉器的 venumerate() 方法的通用 enumerator_enumerate_default() 函數就足夠了。 ...** @param ...	枚舉項的變量列表,取決于實現* @return		TRUE if pointers returned*/bool (*enumerate)(enumerator_t *this, ...);/*** 枚舉集合。** venumerate() 方法采用一個變量參數列表,其中包含將枚舉值寫入的指針。** @param args	枚舉項的變量列表,取決于實現* @return		TRUE if pointers returned*/bool (*venumerate)(enumerator_t *this, va_list args);/*** Destroy an enumerator_t instance.*/void (*destroy)(enumerator_t *this);
};/*** Enumerator implementation for directory enumerator*/
typedef struct {/** implements enumerator_t */enumerator_t public;/** directory handle */DIR *dir;/** absolute path of current file */char full[PATH_MAX];/** where directory part of full ends and relative file gets written *///完整路徑中的目錄部分結束以及相對文件將被寫入的位置char *full_end;
} dir_enum_t;
/*** Helper function that compares two strings for equality*/
static inline bool streq(const char *x, const char *y)
{return (x == y) || (x && y && strcmp(x, y) == 0);
}bool enumerate_dir_enum(dir_enum_t *this, va_list args){//讀取目錄中的條目,依靠此函數特性實現枚舉struct dirent *entry = readdir(this->dir);struct stat *st = NULL;size_t remaining;char **relative = NULL, **absolute = NULL;;int len;//對應enumerate輸入的變參... &relative, &file, NULL 下面寫入這些值相當于寫入那些值VA_ARGS_VGET(args, relative, absolute, st);if (!entry){return FALSE;}if (streq(entry->d_name, ".") || streq(entry->d_name, "..")){return this->public.enumerate(&this->public, relative, absolute, st);}if (relative){//條目名稱*relative = entry->d_name;}if (absolute || st){//full是路徑,relativeremaining = sizeof(this->full) - (this->full_end - this->full);len = snprintf(this->full_end, remaining, "%s", entry->d_name);if (len < 0 || len >= remaining){return FALSE;}if (absolute){*absolute = this->full;}if (st && stat(this->full, st)){/* try lstat() e.g. if a symlink is not valid anymore */if ((errno != ENOENT && errno != ENOTDIR) || lstat(this->full, st)){return FALSE;}}}return TRUE;
}# define DIRECTORY_SEPARATOR "/"
static inline bool path_is_separator(char c)
{return c == DIRECTORY_SEPARATOR[0];
}/*** Object allocation/initialization macro, using designated initializer.*/
#define INIT(this, ...) ({ (this) = malloc(sizeof(*(this))); \*(this) = (typeof(*(this))){ __VA_ARGS__ }; (this); })bool enumerator_enumerate_default(enumerator_t *enumerator, ...)
{va_list args;bool result;if (!enumerator->venumerate){return FALSE;}//va_start用于獲取函數參數列表...中可變參數的首指針//輸出參數args保存函數參數列表中可變參數的首指針(即,可變參數列表)//輸入參數enumerator為函數參數列表中最后一個固定參數(...之前)va_start(args, enumerator);result = enumerator->venumerate(enumerator, args);va_end(args);return result;
}void destroy_dir_enum(dir_enum_t *this){closedir(this->dir);free(this);
}enumerator_t* enumerator_create_directory(const char *path)
{dir_enum_t *this;int len;//實例化INIT(this,.public = {.enumerate = enumerator_enumerate_default,.venumerate = enumerate_dir_enum,.destroy = destroy_dir_enum,},);if (*path == '\0'){path = "./";}len = snprintf(this->full, sizeof(this->full)-1, "%s", path);if (len < 0 || len >= sizeof(this->full)-1){free(this);return NULL;}/* append a '/' if not already done */if (!path_is_separator(this->full[len-1])){this->full[len++] = DIRECTORY_SEPARATOR[0];this->full[len] = '\0';}this->full_end = &this->full[len];//打開目錄this->dir = opendir(path);if (!this->dir){free(this);return NULL;}return &this->public;
}int main()
{char *file;char *relative;char *st;char *path = "/root/open/strongswan-6.0.0";enumerator_t *enumerator;enumerator = enumerator_create_directory(path);if (enumerator){while (enumerator->enumerate(enumerator, &relative, &file, NULL)){printf("file: %s | relative: %s | size:%s\n", file, relative, NULL);}enumerator->destroy(enumerator);}return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73685.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73685.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73685.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

談談對spring IOC的理解,原理和實現

一、IoC 核心概念 1. 控制反轉&#xff08;Inversion of Control&#xff09; 傳統編程中對象自行管理依賴&#xff08;主動創建&#xff09;&#xff0c;而IoC將控制權轉移給容器&#xff0c;由容器負責對象的創建、裝配和管理&#xff0c;實現依賴關系的反向控制。 2. 依賴…

【Hugging Face 開源庫】Diffusers 庫 —— 擴散模型

Diffusers 的三個主要組件1. DiffusionPipeline&#xff1a;端到端推理工具__call__ 函數callback_on_step_end 管道回調函數 2. 預訓練模型架構和模塊UNetVAE&#xff08;Variational AutoEncoder&#xff09;圖像尺寸與 UNet 和 VAE 的關系EMA&#xff08;Exponential Moving…

甘肅旅游服務平臺+論文源碼視頻演示

4 系統設計 4.1系統概要設計 甘肅旅游服務平臺并沒有使用C/S結構&#xff0c;而是基于網絡瀏覽器的方式去訪問服務器&#xff0c;進而獲取需要的數據信息&#xff0c;這種依靠瀏覽器進行數據訪問的模式就是現在用得比較廣泛的適用于廣域網并且沒有網速限制要求的小程序結構&am…

路由選型終極對決:直連/靜態/動態三大類型+華為華三思科配置差異,一張表徹底講透!

路由選型終極對決&#xff1a;直連/靜態/動態三大類型華為華三思科配置差異&#xff0c;一張表徹底講透&#xff01; 一、路由&#xff1a;互聯網世界的導航系統二、路由類型深度解析三者的本質區別 三、 解密路由表——網絡設備的GPS華為&#xff08;Huawei&#xff09;華三&a…

【RAG綜述系列】之 RAG 相關背景和基本原理

系列文章&#xff1a; 【RAG綜述系列】之 RAG 相關背景和基本原理 【RAG綜述系列】之 RAG 特點與挑戰以及方法與評估 【RAG綜述系列】之 RAG 先進方法與綜合評估 【RAG綜述系列】之 RAG 應用和未來方向 正文&#xff1a; 檢索增強生成&#xff08;Retrieval-Augmented Gen…

CMake 構建的Qt 項目中的構建套件的配置

在Qt 框架中&#xff0c;使用CMake 構建工具時&#xff0c;需要自己給構建套件添加相關配置&#xff0c;否則已經添加的構建套件將不可選擇使用。 創建CMake 項目后&#xff0c;如果打開項目配置時&#xff0c;出現如下構建套件不可選的情況&#xff0c; 需要先確認是否安裝…

本地化智能運維助手:基于 LangChain 數據增強 和 DeepSeek-R1 的K8s運維文檔檢索與問答系統 Demo

寫在前面 博文內容為基于 LangChain 數據增強 和 Ollams 本地部署 DeepSeek-R1實現 K8s運維文檔檢索與問答系統 Demo通過 Demo 對 LEDVR 工作流&#xff0c; 語義檢索有基本認知理解不足小伙伴幫忙指正 &#x1f603;,生活加油 我看遠山&#xff0c;遠山悲憫 持續分享技術干貨…

Kotlin when 表達式完全指南:從基礎到高級的12種實戰用法

掌握 when 的靈活運用&#xff0c;告別繁瑣的 if-else 鏈 以下是 Kotlin 中 when 表達式的 12種核心用法 的全面總結&#xff0c;涵蓋基礎到高級場景&#xff0c;并附帶實用示例&#xff1a; 一、基礎用法 1. 替代 Java 的 switch-case when (x) {1 -> println("一&qu…

新加坡 PSB 認證:安全標準、證書特點及申請注意事項

目錄 什么是PSB認證&#xff1f; 涉及產品范圍 強制性認證產品類別 自愿性認證產品 認證項目與測試標準 1. 安全測試 2. 電磁兼容性&#xff08;EMC&#xff09;測試 3. 能效測試&#xff08;特定產品&#xff09; 認證流程詳解 第一步&#xff1a;準備階段 第二步&a…

UE4學習筆記 FPS游戲制作26 UE中的UI

文章目錄 幾個概念創建一個UI藍圖添加UI獲取UI的引用 切換設計器和UI藍圖將UI添加到游戲場景錨點軸點slotSizeToContent三種UI數據更新方式函數綁定屬性綁定事件綁定 九宮格分割圖片 幾個概念 UMG&#xff1a;UE的UI編輯器 slate UI: UE的UI的編輯語言 創建一個UI藍圖 右鍵用…

HttpRunner v4.x 遠程調用實踐指南

一、基于 SSH 的遠程執行方案 1. 環境準備流程 在目標服務器部署 HttpRunner 運行時環境&#xff1a; # 遠程服務器執行&#xff08;需 Golang 1.18 和 Python 3.8&#xff09; curl -ksSL https://httprunner.com/script/install.sh | bash配置免密登錄&#xff08;本地機器…

頭條項目的文章延遲發布功能

最近做的頭條項目其中有個功能是創作者發表的文章可以設置在未來某個時間發表&#xff0c;在實現這個功能的時候就在想該怎么實現呢&#xff1f;剛開始想的是利用Spring的定時任務定時的去數據庫中查詢&#xff0c;可以這個查詢頻率該怎么設置&#xff0c;每次從數據庫中需要查…

Celery 全面指南:Python 分布式任務隊列詳解

Celery 全面指南&#xff1a;Python 分布式任務隊列詳解 Celery 是一個強大的分布式任務隊列/異步任務隊列系統&#xff0c;基于分布式消息傳遞&#xff0c;專注于實時處理&#xff0c;同時也支持任務調度。本文將全面介紹 Celery 的核心功能、應用場景&#xff0c;并通過豐富…

OpenHarmony NativeC++應用開發speexdsp噪聲消除案例

隨著5.0的版本的迭代升級&#xff0c;筆者感受到了開源鴻蒙前所未有大的版本更替速度。5.0出現了越來越多的C API可以調用&#xff0c;極大的方便了native c應用的開發。筆者先將speexdsp噪聲消除的案例分享&#xff0c;老規矩&#xff0c;還是開源&#xff01;&#xff01;&am…

nuxt3 seo優化

在 Nuxt3 中&#xff0c;通過 nuxtjs/seo、nuxtjs/sitemap 和 nuxtjs/robots 模塊可以生成包含動態鏈接的站點地圖&#xff08;sitemap.xml&#xff09;&#xff0c;但具體是“實時生成”還是“部署時生成”&#xff0c;取決于你的配置方式和數據更新頻率。以下是具體分析&…

es6的100個問題

基礎概念 解釋 let、const 和 var 的區別。什么是塊級作用域&#xff1f;ES6 如何實現它&#xff1f;箭頭函數和普通函數的主要區別是什么&#xff1f;解釋模板字符串&#xff08;Template Literals&#xff09;的用途&#xff0c;并舉例嵌套變量的寫法。解構賦值的語法是什么…

【機器學習】什么是決策樹?

什么是決策樹&#xff1f; 決策樹是一種用于分類和回歸問題的模型。它通過一系列的“決策”將數據逐步分裂&#xff0c;最終得出預測結果。可以把它看作是一個“樹”&#xff0c;每個節點表示一個特征的判斷&#xff0c;而每個分支代表了可能的判斷結果&#xff0c;最終的葉子…

Java面試黃金寶典15

1. 請找出增序排列中一個數字第一次和最后一次出現的數組下標 定義 由于數組是增序排列的&#xff0c;我們可以利用二分查找的特性來高效地定位目標數字。對于查找第一次出現的位置&#xff0c;當中間元素等于目標數字時&#xff0c;我們需要繼續向左搜索&#xff0c;以確保找…

CentOS 7安裝 mysql

CentOS 7安裝 mysql 1. yum 安裝 mysql 配置mysql源 yum -y install mysql57-community-release-el7-10.noarch.rpm安裝MySQL服務器 yum -y install mysql-community-server啟動MySQL systemctl start mysqld.service查看MySQL運行狀態&#xff0c;運行狀態如圖&#xff…

科軟25機試

題目: 2025科軟復試上機題&#xff08;回憶版&#xff09;題解_嗶哩嗶哩_bilibili 1. 字符串反轉 #include<bits/stdc.h> using namespace std;void solve(string& a, int CurN) {if (!(CurN % 2)) {int right a.size() - 1;int left 0;while (left < right)…