• NDAttributeList源码解析及测试


     NDAttributeList对象的源代码:

    1. #include
    2. #include "NDAttributeList.h"
    3. /** NDAttributeList构造器:初始化ELLLIST,创建互斥量
    4. */
    5. NDAttributeList::NDAttributeList()
    6. {
    7. ellInit(&this->list_);
    8. this->lock_ = epicsMutexCreate();
    9. }
    10. /** NDAttributeList析构函数:清除所有NDAttribute对象,释放ELLLIST,销毁互斥量
    11. */
    12. NDAttributeList::~NDAttributeList()
    13. {
    14. this->clear();
    15. ellFree(&this->list_);
    16. epicsMutexDestroy(this->lock_);
    17. }
    18. /** 添加一个属性到这个列表。
    19. * 如果一个相同名称的属性已经存在,则删除这个已有属性并且用这个新属性替代。
    20. * [in] pAttribute:指向要添加的属性的指针 .
    21. */
    22. int NDAttributeList::add(NDAttribute *pAttribute)
    23. {
    24. //const char *functionName = "NDAttributeList::add";
    25. epicsMutexLock(this->lock_);
    26. /* 移除这个名称的任何已有顺序 */
    27. this->remove(pAttribute->name_.c_str());
    28. // 把这个属性添加到链表中
    29. ellAdd(&this->list_, &pAttribute->listNode_.node);
    30. epicsMutexUnlock(this->lock_);
    31. return(ND_SUCCESS);
    32. }
    33. /** 添加一个NDAttribute对象到链表中
    34. * 这是一个用于添加一个属性到一个链表的便捷函数.
    35. * 它首先搜寻这个链表查看是否有存在一个相同名称的属性。
    36. * 如果存在,它仅更改已有属性的性质。如果不存在,它用指定性质创建一个新的属性。
    37. * 重要:这个方法仅能够创建NDAttribute基类类型的属性,而非派生类属性。
    38. * 要添加一个派生类的属性到一个列表,必须使用NDAttributeList::add(NDAttribute *)方法。
    39. * [in] pName :要被添加的属性的名称.
    40. * [in] pDescription:这个属性的描述.
    41. * [in] dataType :这个属性的数据类型.
    42. * [in] pValue :指向用于这个属性的值的指针.
    43. *
    44. */
    45. NDAttribute* NDAttributeList::add(const char *pName, const char *pDescription, NDAttrDataType_t dataType, void *pValue)
    46. {
    47. //const char *functionName = "NDAttributeList::add";
    48. NDAttribute *pAttribute;
    49. epicsMutexLock(this->lock_);
    50. pAttribute = this->find(pName);
    51. if (pAttribute) {
    52. pAttribute->setValue(pValue);
    53. } else {
    54. pAttribute = new NDAttribute(pName, pDescription, NDAttrSourceDriver, "Driver", dataType, pValue);
    55. ellAdd(&this->list_, &pAttribute->listNode_.node);
    56. }
    57. epicsMutexUnlock(this->lock_);
    58. return(pAttribute);
    59. }
    60. /** 通过名称查找一个属性;搜索现在是区分大小写的。
    61. * [in] pName : 要被查找的属性的名称.
    62. * 返回:如果找到,一个指向这个属性的指针,如果没有找到,返回NULL .
    63. */
    64. NDAttribute* NDAttributeList::find(const char *pName)
    65. {
    66. NDAttribute *pAttribute;
    67. NDAttributeListNode *pListNode;
    68. //const char *functionName = "NDAttributeList::find";
    69. epicsMutexLock(this->lock_);
    70. pListNode = (NDAttributeListNode *)ellFirst(&this->list_);
    71. while (pListNode) {
    72. pAttribute = pListNode->pNDAttribute;
    73. if (pAttribute->name_ == pName) goto done;
    74. pListNode = (NDAttributeListNode *)ellNext(&pListNode->node);
    75. }
    76. pAttribute = NULL;
    77. done:
    78. epicsMutexUnlock(this->lock_);
    79. return(pAttribute);
    80. }
    81. /** 查找在属性链表中下一个属性。
    82. * [in] pAttributeIn : 一个指向链表中前一个属性的指针
    83. * 如果NULL,返回链表中第一个属性
    84. * 返回:如果有,返回一个指向下一个属性的指针,
    85. * 如果在链表中没有更多属性了,返回NULL。
    86. */
    87. NDAttribute* NDAttributeList::next(NDAttribute *pAttributeIn)
    88. {
    89. NDAttribute *pAttribute=NULL;
    90. NDAttributeListNode *pListNode;
    91. //const char *functionName = "NDAttributeList::next";
    92. epicsMutexLock(this->lock_);
    93. if (!pAttributeIn) {
    94. pListNode = (NDAttributeListNode *)ellFirst(&this->list_);
    95. }
    96. else {
    97. pListNode = (NDAttributeListNode *)ellNext(&pAttributeIn->listNode_.node);
    98. }
    99. if (pListNode) pAttribute = pListNode->pNDAttribute;
    100. epicsMutexUnlock(this->lock_);
    101. return(pAttribute);
    102. }
    103. /** 返回属性链表中属性的总数。
    104. * 返回:返回属性数目 */
    105. int NDAttributeList::count()
    106. {
    107. //const char *functionName = "NDAttributeList::count";
    108. // 链表中节点数目
    109. return ellCount(&this->list_);
    110. }
    111. /** 从链表中移除一个属性。
    112. * [in] pName : 要被删除的属性名称.
    113. * 返回:如果找到这个属性并且被删除,返回ND_SUCCESS。
    114. * 如果没有找到这个属性,ND_ERRORR
    115. */
    116. int NDAttributeList::remove(const char *pName)
    117. {
    118. NDAttribute *pAttribute;
    119. int status = ND_ERROR;
    120. //const char *functionName = "NDAttributeList::remove";
    121. epicsMutexLock(this->lock_);
    122. pAttribute = this->find(pName);
    123. if (!pAttribute) goto done; // 指定名称的属性不存在,则直接结束
    124. ellDelete(&this->list_, &pAttribute->listNode_.node); // 从链表中删除这个属性
    125. delete pAttribute;
    126. status = ND_SUCCESS;
    127. done:
    128. epicsMutexUnlock(this->lock_);
    129. return(status);
    130. }
    131. /** 从链表删除所有属性 */
    132. int NDAttributeList::clear()
    133. {
    134. NDAttribute *pAttribute;
    135. NDAttributeListNode *pListNode;
    136. //const char *functionName = "NDAttributeList::clear";
    137. epicsMutexLock(this->lock_);
    138. pListNode = (NDAttributeListNode *)ellFirst(&this->list_); // 第一个节点
    139. while (pListNode) {
    140. pAttribute = pListNode->pNDAttribute;
    141. ellDelete(&this->list_, &pListNode->node);
    142. delete pAttribute;
    143. pListNode = (NDAttributeListNode *)ellFirst(&this->list_);
    144. }
    145. epicsMutexUnlock(this->lock_);
    146. return(ND_SUCCESS);
    147. }
    148. /**
    149. * 从一个属性链表复制所有属性到另一个属性链表。
    150. * 它是高效的,因而如果这个属性已经存在于这个输出链表,它仅复制这些性质,并且内存分配被最小化。
    151. * 这些属性被添加到在输出链表中已经存在的任何已有属性中。
    152. * [out]pListNode: 指向要复制到的输出属性链表的指针
    153. */
    154. int NDAttributeList::copy(NDAttributeList *pListOut)
    155. {
    156. NDAttribute *pAttrIn, *pAttrOut, *pFound;
    157. NDAttributeListNode *pListNode;
    158. //const char *functionName = "NDAttributeList::copy";
    159. epicsMutexLock(this->lock_);
    160. pListNode = (NDAttributeListNode *)ellFirst(&this->list_); // 获取第一个属性所在节点
    161. while (pListNode) {
    162. pAttrIn = pListNode->pNDAttribute; // 获取属性NDAttribute对象
    163. /* 查找输出链表中是否已经存在相同名称的属性 */
    164. pFound = pListOut->find(pAttrIn->name_.c_str());
    165. /* 如果输出链表中存在相同名称的,则将仅将输入链表中属性对象的属性值复制到输出链表中属性对象的属性值中
    166. 如果不存在,则拷贝构造一个输入链表中的属性对象
    167. */
    168. pAttrOut = pAttrIn->copy(pFound);
    169. /* 如果pFound是NULL,则一个复制窗一个新属性,需要添加它到输出链表*/
    170. if (!pFound) pListOut->add(pAttrOut);
    171. pListNode = (NDAttributeListNode *)ellNext(&pListNode->node);// 输入链表中当前节点的下一个节点
    172. }
    173. epicsMutexUnlock(this->lock_);
    174. return(ND_SUCCESS);
    175. }
    176. /**
    177. * 更新链表中所有属性值;为链表中每个属性调用NDAttribute::updateValue()
    178. */
    179. int NDAttributeList::updateValues()
    180. {
    181. NDAttribute *pAttribute;
    182. NDAttributeListNode *pListNode;
    183. //const char *functionName = "NDAttributeList::updateValues";
    184. epicsMutexLock(this->lock_);
    185. pListNode = (NDAttributeListNode *)ellFirst(&this->list_);
    186. while (pListNode) {// 调用链表中每个节点上每个NDAttribute对象的updateValue()
    187. pAttribute = pListNode->pNDAttribute;
    188. pAttribute->updateValue();
    189. pListNode = (NDAttributeListNode *)ellNext(&pListNode->node);
    190. }
    191. epicsMutexUnlock(this->lock_);
    192. return(ND_SUCCESS);
    193. }
    194. /** 报告这个属性链表的性质。
    195. * [in] fp :报告输出的文件指针
    196. * [in] details : 所需报告的详细程度;如果>10, 为每个属性调用NDAttribute::report()。
    197. */
    198. int NDAttributeList::report(FILE *fp, int details)
    199. {
    200. NDAttribute *pAttribute;
    201. NDAttributeListNode *pListNode;
    202. epicsMutexLock(this->lock_);
    203. fprintf(fp, "\n");
    204. fprintf(fp, "NDAttributeList: address=%p:\n", this);
    205. fprintf(fp, " number of attributes=%d\n", this->count());
    206. if (details > 10) {
    207. pListNode = (NDAttributeListNode *) ellFirst(&this->list_);
    208. while (pListNode) {
    209. pAttribute = (NDAttribute *)pListNode->pNDAttribute;
    210. pAttribute->report(fp, details);
    211. pListNode = (NDAttributeListNode *) ellNext(&pListNode->node);
    212. }
    213. }
    214. epicsMutexUnlock(this->lock_);
    215. return ND_SUCCESS;
    216. }

    测试代码:

    1. #include
    2. #include
    3. #include
    4. #include "NDAttribute.h"
    5. #include "NDAttributeList.h"
    6. int main()
    7. {
    8. NDAttributeList * list = new NDAttributeList();
    9. epicsInt8 i8 = 10;
    10. epicsInt16 i16 = 256;
    11. epicsInt32 i32 = 100000;
    12. epicsFloat64 f64 = 3.14;
    13. const char * str = "Hello World";
    14. NDAttrDataType_t types[] = {NDAttrInt8, NDAttrInt16, NDAttrInt32, NDAttrFloat64, NDAttrString};
    15. void * ptrValue[] = {&i8, &i16, &i32, &f64, (void *)str};
    16. const char * pDescription[] = {"NDInt8", "NDInt16", "NDInt32", "NDFloat64", "NDString"};
    17. const char * name[] = {"i8Attribute", "i16Attribute", "i32Attribute", "f64Attribute", "strAttribute"};
    18. int i;
    19. for (i = 0; i < 5; i++){
    20. list->add(name[i], pDescription[i], types[i], ptrValue[i]);
    21. }
    22. printf("Total number of Attributes: %d\n", list->count());
    23. printf("Find the attribute of name: %s\n", name[4]);
    24. NDAttribute * pAttribute = list->find(name[4]);
    25. if (pAttribute){
    26. printf("find the attribute of name %s\n", name[4]);
    27. pAttribute->report(stdout, 10);
    28. }
    29. else
    30. {
    31. printf("can not find the attribute of the name: %s\n", name[4]);
    32. }
    33. printf("Display all attribute: \n");
    34. pAttribute = list->next(NULL);
    35. printf("\n");
    36. i = 0;
    37. while (pAttribute){
    38. printf("Num:%d", ++i);
    39. pAttribute->report(stdout, 10);
    40. pAttribute = list->next(pAttribute);
    41. }
    42. printf("Delete the attribute of the name: %s\n", name[4]);
    43. list->remove(name[4]);
    44. printf("Total number of Attributes: %d\n", list->count());
    45. if (pAttribute){
    46. printf("find the attribute of name %s\n", name[4]);
    47. pAttribute->report(stdout, 10);
    48. }
    49. else
    50. {
    51. printf("can not find the attribute of the name: %s\n", name[4]);
    52. }
    53. return 0;
    54. }

    编译以上源代码,进行测试,解释结果如下:

    1. Total number of Attributes: 5
    2. Find the attribute of name: strAttribute
    3. find the attribute of name strAttribute
    4. NDAttribute, address=0xaaaac52ab020:
    5. name=strAttribute
    6. description=NDString
    7. source type=0
    8. source type string=NDAttrSourceDriver
    9. source=Driver
    10. dataType=NDAttrString
    11. value=Hello World
    12. Display all attribute:
    13. Num:1
    14. NDAttribute, address=0xaaaac52aabe0:
    15. name=i8Attribute
    16. description=NDInt8
    17. source type=0
    18. source type string=NDAttrSourceDriver
    19. source=Driver
    20. dataType=NDAttrInt8
    21. value=10
    22. Num:2
    23. NDAttribute, address=0xaaaac52aacf0:
    24. name=i16Attribute
    25. description=NDInt16
    26. source type=0
    27. source type string=NDAttrSourceDriver
    28. source=Driver
    29. dataType=NDAttrInt16
    30. value=256
    31. Num:3
    32. NDAttribute, address=0xaaaac52aae00:
    33. name=i32Attribute
    34. description=NDInt32
    35. source type=0
    36. source type string=NDAttrSourceDriver
    37. source=Driver
    38. dataType=NDAttrInt32
    39. value=100000
    40. Num:4
    41. NDAttribute, address=0xaaaac52aaf10:
    42. name=f64Attribute
    43. description=NDFloat64
    44. source type=0
    45. source type string=NDAttrSourceDriver
    46. source=Driver
    47. dataType=NDAttrFloat64
    48. value=3.140000
    49. Num:5
    50. NDAttribute, address=0xaaaac52ab020:
    51. name=strAttribute
    52. description=NDString
    53. source type=0
    54. source type string=NDAttrSourceDriver
    55. source=Driver
    56. dataType=NDAttrString
    57. value=Hello World
    58. Delete the attribute of the name: strAttribute
    59. Total number of Attributes: 4
    60. can not find the attribute of the name: strAttribute
  • 相关阅读:
    80个在线小游戏源码
    基础 | 并发编程 - [Lock 使用 & 对比 synchronized]
    C++ Qt 学习(九):模型视图代理
    【Redis面试】基础题总结(上)
    前端工作总结212-账号绑定逻辑复杂
    java毕业设计旅游网站设计mybatis+源码+调试部署+系统+数据库+lw
    二极管:Irush与我相干!
    webpack打包gz文件,nginx开启gzip压缩
    周一见!距离阿里巴巴开源开放周还有3天
    SpringBoot
  • 原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/133581159