找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 154|回复: 0

[每日一码] 一个查询DWG文件属性的类

[复制链接]

1

主题

0

回帖

43

积分

管理员

积分
43
发表于 2024-3-14 20:16:23 | 显示全部楼层 |阅读模式
  1. //////////////////////////////////////////////////////////////////////////
  2. // Реализация чтения DwgProps для AutoCAD 2004...2016 (возможно и дальше,
  3. // если сохранится структура dwg-файла).
  4. //////////////////////////////////////////////////////////////////////////
  5. #include <io.h>
  6. #include <sys/stat.h>
  7. #include <fcntl.h>
  8. #include <malloc.h>
  9. #include <stdlib.h>
  10. #include <vector>
  11. #include <string>
  12. //
  13. // Имена стандартных свойств чертежа
  14. //
  15. const char *stdPropNames[] = {
  16.         "title",
  17.         "subject",
  18.         "author",
  19.         "keywords",
  20.         "comments",
  21.         "lastSavedBy",
  22.         "revisionNumber",
  23.         "hyperlinkBase"
  24. };
  25. class DwgProps
  26. {
  27.         struct record {
  28.                 WORD len;
  29.                 union {
  30.                         char    c[32767];
  31.                         wchar采用t w[32767];
  32.                 };
  33.         };
  34. public:
  35.         DwgProps() {
  36.                 for (int i=0; i < sizeof(stdPropNames)/sizeof(stdPropNames[0]); i++)  {
  37.                         m采用stdProps.push采用back("");
  38.                 }
  39.                 memset(bTotalEditingTime,0,sizeof(bTotalEditingTime));
  40.                 memset(bCreateDateTime,0,sizeof(bCreateDateTime));
  41.                 memset(bModifiedDateTime,0,sizeof(bModifiedDateTime));
  42.         };
  43.         ~DwgProps() {}
  44.         //  data items
  45.         const char *title()          const    {return m采用stdProps[0].c采用str(); }
  46.         const char *subject()        const    {return m采用stdProps[1].c采用str(); }
  47.         const char *author()         const    {return m采用stdProps[2].c采用str(); }
  48.         const char *keywords()       const    {return m采用stdProps[3].c采用str(); }
  49.         const char *comments()       const    {return m采用stdProps[4].c采用str(); }
  50.         const char *lastSavedBy()    const    {return m采用stdProps[5].c采用str(); }
  51.         const char *revisionNumber() const    {return m采用stdProps[6].c采用str(); }
  52.         const char *hyperlinkBase()  const    {return m采用stdProps[7].c采用str(); }
  53.         const char *customName(int idx) const  {
  54.                 return ((idx >= 0 && idx < (int)m采用custPropNames.size())?m采用custPropNames[idx].c采用str():0);
  55.         }
  56.         const char *customValue(int idx) const {
  57.                 return ((idx >= 0 && idx < (int)m采用custPropValues.size())?m采用custPropValues[idx].c采用str():0);
  58.         }
  59.         const char *customValue(const char *name) const  {
  60.                 for (int i=0; i < (int)m采用custPropNames.size(); i++) {
  61.                         if (m采用custPropNames[i] == name) return m采用custPropValues[i].c采用str();
  62.                 }
  63.                 return 0;
  64.         }
  65.         int    customNumber() const { return (int) m采用custPropNames.size(); }
  66.         ULONG      inDwg()   { return ReadDiffDate(bTotalEditingTime); }
  67.         SYSTEMTIME created() { return ReadDate(bCreateDateTime); }
  68.         SYSTEMTIME updated() { return ReadDate(bModifiedDateTime); }
  69.         const void DateToString(char *buf, SYSTEMTIME tm)
  70.         {
  71.                 sprintf( buf,
  72.                         "%d-%02d-%02d %02d:%02d:%02d.%03d",
  73.                         tm.wYear, tm.wMonth, tm.wDay,
  74.                         tm.wHour, tm.wMinute, tm.wSecond, tm.wMilliseconds);
  75.         }
  76.         const void DiffDateToString(char *buf, ULONG tDiff)
  77.         {
  78.                 int days = tDiff / (24*60*60*1000);
  79.                 tDiff -= days * (24*60*60*1000);
  80.                 int hours = tDiff / (60*60*1000);
  81.                 tDiff -= hours * (60*60*1000);
  82.                 int minutes = tDiff / (60*1000);
  83.                 tDiff -= minutes * (60*1000);
  84.                 int seconds = tDiff / 1000;
  85.                 tDiff -= seconds * (1000);
  86.                 int mseconds = tDiff;
  87.                 sprintf( buf,
  88.                         "Days:%d Hours:%d Minutes:%d Seconds:%d Milliseconds:%d",
  89.                         days, hours, minutes, seconds, mseconds);
  90.         }
  91.         int load(const char * fname)
  92.         {
  93.                 bool unicode = false;
  94.                 int h;
  95.                 char buf[32767]; memset(buf,0,sizeof(buf));
  96.                 if ((h = 采用open(fname,采用O采用BINARY|采用O采用RDONLY)) == -1)
  97.                         return 0;
  98.                 char ACADVER[7];
  99.                 if (采用read(h,ACADVER,sizeof(ACADVER)) <= 0) {
  100.                         采用close(h); return 0;
  101.                 }
  102.                 if (atoi(ACADVER+2) < 1018) {  // AutoCAD R14,2000...2002 обрабатывать не будем
  103.                         采用close(h); return 0;
  104.                 }
  105.                 if (atoi(ACADVER+2) >= 1021) { // AutoCAD 2007... строки в Unicode
  106.                         unicode = true;
  107.                 }
  108.                 // Указатель перемещаем на WORD, содержащий смещение DwgProps
  109.                 if (采用lseek(h,0x20,SEEK采用SET) == -1) {
  110.                         采用close(h); return 0;
  111.                 }
  112.                 // Считываем смещение DwgProps
  113.                 WORD offset采用dwgprops = 0;
  114.                 if (采用read(h,&offset采用dwgprops,sizeof(offset采用dwgprops)) <= 0) {
  115.                         采用close(h); return 0;
  116.                 }
  117.                 long begin采用offset = offset采用dwgprops, cur采用offset = offset采用dwgprops;
  118.                 // Устанавливаем указатель на начало DwgProps
  119.                 if (采用lseek(h,offset采用dwgprops,SEEK采用SET) == -1) {
  120.                         采用close(h); return 0;
  121.                 }
  122.                 // Теперь можно читать длины и сами строки:
  123.                 record rec;
  124.                 for (int i=0; i < sizeof(stdPropNames)/sizeof(stdPropNames[0]); i++) {
  125.                         if (采用read(h,&rec,sizeof(record)) == -1) {
  126.                                 采用close(h); return 0;
  127.                         }
  128.                         if (unicode) {
  129.                                 WideCharToMultiByte(CP采用ACP,0,rec.w,rec.len,buf,rec.len,0,NULL);
  130.                                 m采用stdProps[i] = buf;
  131.                         } else {
  132.                                 m采用stdProps[i] = rec.c;
  133.                         }
  134.                         cur采用offset += (rec.len*((unicode)?2:1) + sizeof(rec.len));
  135.                         if (采用lseek(h,cur采用offset,SEEK采用SET) == -1) {
  136.                                 采用close(h); return 0;
  137.                         }
  138.                 }
  139.                 if (采用read(h,&bTotalEditingTime,sizeof(bTotalEditingTime)) == -1) {
  140.                         采用close(h); return 0;
  141.                 }
  142.                 if (采用read(h,&bCreateDateTime,sizeof(bCreateDateTime)) == -1) {
  143.                         采用close(h); return 0;
  144.                 }
  145.                 if (采用read(h,&bModifiedDateTime,sizeof(bModifiedDateTime)) == -1) {
  146.                         采用close(h); return 0;
  147.                 }
  148.                 cur采用offset += (sizeof(bTotalEditingTime)+ sizeof(bCreateDateTime) + sizeof(bModifiedDateTime));
  149.                 if (采用lseek(h,cur采用offset,SEEK采用SET) == -1) {
  150.                         采用close(h); return 0;
  151.                 }
  152.                 // Читаем количество собственных (custom) переменных
  153.                 WORD nCust = 0;
  154.                 if (采用read(h,&nCust,sizeof(nCust)) <= 0) { 采用close(h); return 0; }
  155.                 cur采用offset += sizeof(WORD);
  156.                 for (int i=0; i < nCust; i++) {
  157.                         // Считываем имя переменной
  158.                         if (采用read(h,&rec,sizeof(record)) == -1) {采用close(h); return 0;}
  159.                         if (unicode) {
  160.                                 WideCharToMultiByte(CP采用ACP,0,rec.w,rec.len,buf,rec.len,0,NULL);
  161.                                 m采用custPropNames.push采用back(buf);
  162.                         } else {
  163.                                 m采用custPropNames.push采用back(rec.c);
  164.                         }
  165.                         cur采用offset += (rec.len*((unicode)?2:1) + sizeof(rec.len));
  166.                         if (采用lseek(h,cur采用offset,SEEK采用SET) == -1) {
  167.                                 采用close(h); return 0;
  168.                         }
  169.                         if (采用read(h,&rec,sizeof(record)) == -1) {采用close(h); return 0;}
  170.                         if (unicode) {
  171.                                 WideCharToMultiByte(CP采用ACP,0,rec.w,rec.len,buf,rec.len,0,NULL);
  172.                                 m采用custPropValues.push采用back(buf);
  173.                         } else {
  174.                                 m采用custPropValues.push采用back(rec.c);
  175.                         }
  176.                         cur采用offset += (rec.len*((unicode)?2:1) + sizeof(rec.len));
  177.                         if (采用lseek(h,cur采用offset,SEEK采用SET) == -1) {采用close(h); return 0;}
  178.                 }
  179.                 采用close(h);
  180.                 return 1;
  181.         }
  182. private:
  183.         //  data
  184.         std::vector<std::string> m采用stdProps;
  185.         std::vector<std::string> m采用custPropNames;
  186.         std::vector<std::string> m采用custPropValues;
  187.         byte bTotalEditingTime[8];
  188.         byte bCreateDateTime[8];
  189.         byte bModifiedDateTime[8];
  190.         SYSTEMTIME minDate, maxDate;
  191.         //
  192.         // Преобразование даты/времени из юлианского календаря
  193.         //
  194.         SYSTEMTIME FromJulian(ULONG days)
  195.         {
  196.                 FILETIME fmin = {0, 0} , fmax = {0x7fffffff, 0xffffffff} ;
  197.                 FileTimeToSystemTime(&fmin, &minDate);  FileTimeToSystemTime(&fmax, &maxDate);
  198.                 SYSTEMTIME s; memset(&s,0,sizeof(s));
  199.                 if (days < 0x1a4452) return minDate;
  200.                 if (days > 0x51fe2c) return maxDate;
  201.                 int j = days + 32044;
  202.                 int g = j / 146097;
  203.                 int dg = j % 146097;
  204.                 int c = (((dg / 36524) + 1) * 3) / 4;
  205.                 int dc = dg - (c * 36524);
  206.                 int b = dc / 1461;
  207.                 int db = dc % 1461;
  208.                 int a = (((db / 365) + 1) * 3) / 4;
  209.                 int da = db - (a * 365);
  210.                 int y = (((g * 400) + (c * 100)) + (b * 4)) + a;
  211.                 int m = (((da * 5) + 308) / 153) - 2;
  212.                 int d = (da - (((m + 4) * 153) / 5)) + 0x7a;
  213.                 int year = (y - 4800) + ((m + 2) / 12);
  214.                 int month = ((m + 2) % 12) + 1;
  215.                 int day = d + 1;
  216.                 s.wYear = year;
  217.                 s.wMonth = month;
  218.                 s.wDay = day;
  219.                 s.wHour = 2;
  220.                 s.wMinute = 0;
  221.                 s.wSecond = 0;
  222.                 s.wDayOfWeek = 0;
  223.                 s.wMilliseconds = 0;
  224.                 return s;
  225.         }
  226.         //
  227.         // Добавление дробной части (миллисекунд)
  228.         //
  229.         SYSTEMTIME addMilliSecs(SYSTEMTIME s, double mseconds) {
  230.                 FILETIME f; SystemTimeToFileTime(&s, &f);
  231.                 ULARGE采用INTEGER u;
  232.                 memcpy(&u, &f, sizeof(u));
  233.                 ULONGLONG mmsec = mseconds * 10000;
  234.                 u.QuadPart += mmsec;
  235.                 memcpy(&f, &u, sizeof(f));
  236.                 FileTimeToSystemTime(&f, &s);
  237.                 return s;
  238.         }
  239.         //
  240.         // Чтение даты/времени
  241.         //
  242.         const SYSTEMTIME ReadDate(byte *src)
  243.         {
  244.                 ULONG days = *((ULONG *)(src)); src += 4;
  245.                 ULONG fraction = *((ULONG *)(src)); src += 4;
  246.                 SYSTEMTIME tm = FromJulian(days);
  247.                 if (tm.wYear == maxDate.wYear)
  248.                         return tm;
  249.                 return addMilliSecs(tm,fraction);
  250.         }
  251.         //
  252.         // Чтение интервала редактирования
  253.         //
  254.         const ULONG ReadDiffDate(byte* src)
  255.         {
  256.                 ULONG days = *((ULONG *)(src)); src += 4;
  257.                 ULONG fraction = *((ULONG *)(src)); src += 4;
  258.                 ULONG diff = days * 24 * 60 * 60 * 1000 + fraction;
  259.                 return diff;
  260.         }
  261. };
  262. ////-----------------------------------------
  263. //// Пример использования класса DwgProps
  264. ////-----------------------------------------
  265. //#include "stdafx.h"
  266. //#include <conio.h>
  267. //#include <stdio.h>
  268. //#include <string.h>
  269. //#include <wtypes.h>
  270. //#include <time.h>
  271. //#include "DwgProps.h"
  272. //
  273. //
  274. //const char * valid(const char *s)
  275. //{
  276. //  return s ? s : "";
  277. //}
  278. //
  279. //void main(int argc, char *argv[])
  280. //{
  281. //  DwgProps p;
  282. //
  283. //  if ( argc < 2 )
  284. //  {
  285. //    fprintf(stderr, "Usage: dwgprops file [file ...]\n");
  286. //    return;
  287. //  }
  288. //
  289. //  //  loop over files
  290. //  for ( int f = 1; f < argc; f++ )
  291. //  {
  292. //    printf("%s\n", argv[f]);
  293. //
  294. //    if ( p.load(argv[f]) )
  295. //    {
  296. //      //  print list of tags
  297. //      printf("  Title:         [%s]\n", valid(p.title()));
  298. //      printf("  Subject:       [%s]\n", valid(p.subject()));
  299. //      printf("  Author:        [%s]\n", valid(p.author()));
  300. //      printf("  Comments:      [%s]\n", valid(p.comments()));
  301. //      printf("  Keywords:      [%s]\n", valid(p.keywords()));
  302. //      printf("  HyperlinkBase: [%s]\n", valid(p.hyperlinkBase()));
  303. //      printf("  LastSavedBy:   [%s]\n", valid(p.lastSavedBy()));
  304. //      printf("  RevisionNo.:   [%s]\n", valid(p.revisionNumber()));
  305. //      char buffer[ 256 ];
  306. //      p.DiffDateToString(buffer, p.inDwg());
  307. //      printf("  Edit time: %s\n", buffer);
  308. //      p.DateToString(buffer, p.created());
  309. //      printf("  Created:       [%s]\n", buffer);
  310. //      p.DateToString(buffer, p.updated());
  311. //      printf("  Updated:       [%s]\n", buffer);
  312. //      for ( int i = 0; i < p.customNumber(); i++ ) {
  313. //        printf("  Custom Name[%d]:   [%s]\n", i, valid(p.customName(i)));
  314. //        printf("  Custom Value[%d]:  [%s]\n", i, valid(p.customValue(i)));
  315. //      }
  316. //    }
  317. //  }
  318. //}
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|膜结构网

GMT+8, 2025-1-11 00:49 , Processed in 0.133401 second(s), 22 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表