{"id":2839,"date":"2018-05-31T16:24:23","date_gmt":"2018-05-31T21:24:23","guid":{"rendered":"http:\/\/www.logikalsolutions.com\/wordpress\/?p=2839"},"modified":"2018-05-31T16:24:23","modified_gmt":"2018-05-31T21:24:23","slug":"qt-and-usb-pt-4","status":"publish","type":"post","link":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/","title":{"rendered":"Qt and USB &#8211; Pt. 4"},"content":{"rendered":"<p>The physical loading of the database isn&#8217;t performed by a class. It is performed by a series of C++ functions all contained in the following source file.<\/p>\n<pre>\/*\r\n *      Copyright (c) 2018 Roland Hughes and Logical Solutions  ALL RIGHTS RESERVED\r\n *\r\n *      This code is \"as-is\" without any warranty expressed or implied. You may not modify or distribute it\r\n *      without having purchased the right to do so from the copyright holder. This code is provided for\r\n *      demonstration purposes only. Usage of it implies your express agreement to hold both the author and\r\n *      copyright holder harmless from damages both real and perceived.\r\n *\/\r\n\r\n\r\n#include \r\n#include \r\n\r\nusing namespace std;\r\n\r\n#include \r\n#include \r\n#include \r\n#include \r\n#include \r\n#include \r\n#include \r\n\r\nstatic const int SPACES_PER_TAB = 4;\r\nstatic const QString SPACE_STR(SPACES_PER_TAB, QChar(' '));\r\n\r\nstatic const QString DB_DATE_FORMAT = QString(\"yyyy-MM-dd HH:mm:ss.z\");\r\n\r\nstatic QString lastVendor;\r\nstatic QString lastDevice;\r\nstatic QString lastClass;\r\nstatic QString lastSubClass;\r\nstatic QString lastUsagePage;\r\nstatic QString lastLanguage;\r\n\r\nvoid cleanLineIn(QString&amp; lineIn)\r\n{\r\n    lineIn.replace(SPACE_STR, \"\\t\");\r\n    lineIn.remove(QRegExp(\"[\\\\n\\\\r]\")); \/\/ get rid of trailing newline\r\n}\r\n\r\nQString buildVendorsSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n    QString cmdStr;\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    switch(lineIn.at(0).toLatin1())\r\n    {\r\n    case '\\t':\r\n        if (lineIn.at(1) == '\\t')\r\n        {\r\n            cmdStr = QString(\"INSERT INTO DEVICE_INTERVACE(VENDOR_ID, DEVICE_ID, INTERFACE, INTERFACE_NAME) \"\r\n                             \"VALUES( '%1', '%2', '%3', '%4');\").arg(lastVendor).arg(lastDevice).arg(keyStr).arg(nameStr);\r\n        }\r\n        else\r\n        {\r\n            cmdStr = QString(\"INSERT INTO VENDOR_DEVICE(VENDOR_ID, DEVICE_ID, DEVICE_NAME) \"\r\n                             \"VALUES( '%1', '%2', '%3');\").arg(lastVendor).arg(keyStr).arg(nameStr);\r\n            lastDevice = keyStr;\r\n        }\r\n        break;\r\n    default:\r\n        cmdStr = QString(\"INSERT INTO VENDORS(VENDOR_ID, VENDOR_NAME) \"\r\n                         \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr);\r\n        lastVendor = keyStr;\r\n        break;\r\n    }\r\n\r\n    return cmdStr;\r\n}\r\n\r\nQString buildClassesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n    QString cmdStr;\r\n\r\n    if (lineIn.at(0) == 'C')\r\n    {\r\n        lineIn = lineIn.mid(2);\r\n    }\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    switch(lineIn.at(0).toLatin1())\r\n    {\r\n    case '\\t':\r\n        if (lineIn.at(1) == '\\t')\r\n        {\r\n            cmdStr = QString(\"INSERT INTO PROTOCOL(CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, PROTOCOL_NAME) \"\r\n                             \"VALUES('%1', '%2', '%3', '%4');\").arg(lastClass).arg(lastSubClass).arg(keyStr).arg(nameStr);\r\n        }\r\n        else\r\n        {\r\n            cmdStr = QString(\"INSERT INTO SUBCLASS(CLASS_ID, SUBCLASS_ID, SUBCLASS_NAME) \"\r\n                             \"VALUES('%1', '%2', '%3');\").arg(lastClass).arg(keyStr).arg(nameStr);\r\n            lastSubClass = keyStr;\r\n        }\r\n        break;\r\n    default:\r\n        cmdStr = QString(\"INSERT INTO CLASS(CLASS_ID, CLASS_NAME) VALUES('%1', '%2');\").arg(keyStr).arg(nameStr);\r\n        lastClass = keyStr;\r\n        break;\r\n    }\r\n\r\n    return cmdStr;\r\n}\r\n\r\n\r\nQString buildAudioTerminalsSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'A')\r\n    {\r\n        lineIn = lineIn.mid(2);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO AUDIO_TERMINAL(TERMINAL_TYPE, TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildHIDDescriptorsSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'H')\r\n    {\r\n        lineIn = lineIn.mid(3);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO HID_TYPES(DESCRIPTOR_TYPE, DESCRIPTOR_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildItemTypesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'R')\r\n    {\r\n        lineIn = lineIn.mid(2); \/\/ don't forget the trailing space\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO HID_ITEM_TYPES(ITEM_TYPE, ITEM_TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildBiasTypesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'B')\r\n    {\r\n        lineIn = lineIn.mid(5);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO BIAS_TYPES(ITEM_TYPE, ITEM_TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildPhysicalTypesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'P')\r\n    {\r\n        lineIn = lineIn.mid(4);  \/\/ don't forget trailing space\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO PHYSICAL_TYPES(ITEM_TYPE, ITEM_TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildUsagesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n    QString cmdStr;\r\n\r\n    if (lineIn.at(0) == 'H')\r\n    {\r\n        lineIn = lineIn.mid(4);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    switch(lineIn.at(0).toLatin1())\r\n    {\r\n    case '\\t':\r\n        cmdStr = QString(\"INSERT INTO USAGE_NAMES(PAGE_ID, USAGE_ID, USAGE_NAME) \"\r\n                         \"VALUES( '%1', '%2', '%3');\").arg(lastUsagePage).arg(keyStr).arg(nameStr);\r\n        break;\r\n    default:\r\n        cmdStr = QString(\"INSERT INTO USAGES(PAGE_ID, PAGE_NAME) \"\r\n                         \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr);\r\n        lastUsagePage = keyStr;\r\n        break;\r\n    }\r\n\r\n    return cmdStr;\r\n}\r\n\r\nQString buildLanguagesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n    QString cmdStr;\r\n\r\n    if (lineIn.at(0) == 'L')\r\n    {\r\n        lineIn = lineIn.mid(2);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    switch(lineIn.at(0).toLatin1())\r\n    {\r\n    case '\\t':\r\n        cmdStr = QString(\"INSERT INTO DIALECTS(LANGUAGE_ID, DIALECT_ID, DIALECT_NAME) \"\r\n                         \"VALUES( '%1', '%2', '%3');\").arg(lastLanguage).arg(keyStr).arg(nameStr);\r\n        break;\r\n    default:\r\n        cmdStr = QString(\"INSERT INTO LANGUAGES(LANGUAGE_ID, LANGUAGE_NAME) \"\r\n                         \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr);\r\n        lastLanguage = keyStr;\r\n        break;\r\n    }\r\n    return cmdStr;\r\n}\r\n\r\nQString buildCountryCodesSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'H')\r\n    {\r\n        lineIn = lineIn.mid(4);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO COUNTRY_CODE(COUNTRY_ID, KEYMAP_TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nQString buildVideoClassSQL(QString lineIn)\r\n{\r\n    QString keyStr;\r\n    QString nameStr;\r\n\r\n    if (lineIn.at(0) == 'V')\r\n    {\r\n        lineIn = lineIn.mid(3);\r\n    }\r\n\r\n    int firstSpace = lineIn.indexOf(' ');\r\n    keyStr = lineIn.left(firstSpace).simplified();\r\n    nameStr = lineIn.mid(firstSpace).simplified();\r\n\r\n    return (QString(\"INSERT INTO VIDEO_CLASS(TERMINAL_TYPE, TERMINAL_TYPE_NAME) \"\r\n                     \"VALUES('%1', '%2');\").arg(keyStr).arg(nameStr));\r\n}\r\n\r\nvoid loadDbFromFile(QString filePath, QSqlDatabase db)\r\n{\r\n    QDateTime createDate = QFileInfo(filePath).created();\r\n\r\n    QFile inFile(filePath);\r\n    if (!inFile.exists())\r\n    {\r\n        cout &lt;&lt; \"could not locate \" &lt;&lt; filePath.toStdString() &lt;&lt; \" for input - database not loaded\" &lt;&lt; endl;\r\n        return;\r\n    }\r\n\r\n    if (!inFile.open(QIODevice::ReadOnly | QIODevice::Text))\r\n    {\r\n        cout &lt;&lt; \"could not open \" &lt;&lt; filePath.toStdString() &lt;&lt; \" for input - database not loaded\" &lt;&lt; endl;\r\n        return;\r\n    }\r\n\r\n    std::vector tables;\r\n\r\n    tables.push_back(buildVendorsSQL);\r\n    tables.push_back(buildClassesSQL);\r\n    tables.push_back(buildAudioTerminalsSQL);\r\n    tables.push_back(buildHIDDescriptorsSQL);\r\n    tables.push_back(buildItemTypesSQL);\r\n    tables.push_back(buildBiasTypesSQL);\r\n    tables.push_back(buildPhysicalTypesSQL);\r\n    tables.push_back(buildUsagesSQL);\r\n    tables.push_back(buildLanguagesSQL);\r\n    tables.push_back(buildCountryCodesSQL);\r\n    tables.push_back(buildVideoClassSQL);\r\n\r\n    cout &lt;&lt; db.lastError().text().toStdString() &lt;&lt; endl;\r\n\r\n    QString lineIn = \" \";  \/\/ needs to be initialized so at() doesn't gag\r\n    QString cmdStr;\r\n    QSqlQuery query(db);\r\n\r\n    db.transaction();   \/\/ start a transaction to speed up bulk insertion\r\n\r\n    \/\/ first section is vendors\r\n    for (auto f : tables)\r\n    {\r\n        cout &lt;&lt; \"top of tables loop \" &lt;&lt; endl;\r\n        \/\/ find beginning of data\r\n        while ((lineIn.at(0) == '#' || lineIn.length() &lt; 3) &amp;&amp; !inFile.atEnd()) { lineIn = inFile.readLine(); } while (lineIn.length() &gt; 3  &amp;&amp;  !inFile.atEnd())\r\n        {\r\n            \/\/ skip any comment lines which might be in data\r\n            if (lineIn.at(0) != '#')\r\n            {\r\n                cleanLineIn(lineIn);\r\n                cmdStr = f(lineIn);\r\n                if (cmdStr.length() &gt; 0)\r\n                {\r\n                    query.exec(cmdStr);\r\n                }\r\n            }\r\n            lineIn = inFile.readLine();\r\n        }\r\n    }\r\n\r\n    cmdStr = QString(\"INSERT INTO CONTROL(FILE_DT) VALUES('%1');\").arg(createDate.toString(DB_DATE_FORMAT));\r\n    query.exec(cmdStr);\r\n    cout &lt;&lt; \"finished loading\" &lt;&lt; endl;\r\n    inFile.close();\r\n    db.commit();\r\n}\r\n<\/pre>\n<p>We will start our discussion with loadDbFromFile(). Yes, I verify the input file once again. While it may seem a waste of CPU cycles, this code could be used by something else later. The interesting trick is the vector of function pointers which all have the same signature. This lets me use the new style for loop to process the various sections. The functions are called in the order they exist in the input file. The first blank line found while processing a section indicates end of section and that we will have some comments and blank lines to skip before the next section starts.<\/p>\n<p>You will note this entire for loop is encapsulated by a single transaction() and commit(). If you don&#8217;t start a transaction then all database I\/O occurs one record at a time and it is sloooooow. On my really fast I5 desktop with a screaming hard drive I lost interest after about 25 minutes. Surrounded by a transaction() and commit() it executes in seconds. SQLite finally fixed that nasty little flaw!<\/p>\n<p>Opting for this design allowed my section parsing methods to parse one line at a time returning the SQL statement needed to insert the data. Yes, I experimented with making each one do their own thing, but, the code was cumbersome and it ran slow.<\/p>\n<p>I can hear the OOP purists wailing in anguish over my use of function pointers. Pure OOP isn&#8217;t always the best solution. Besides, I recently was doing some OpenVMS C programming and that code used quite a few of them. I will be the first to admit function pointers get abused. During the early days of DOS with overlay linkers, you couldn&#8217;t even be certain the function you wanted was still in local memory, causing no end of weirdness.<\/p>\n<p>Ah, you kids, you have it so easy. Us old timers had to actually solve all of those problems so we could hang onto a tiny scrap of our sanity. Now you get to work on 64-bit processors and operating systems which can swap things in and out of memory near perfectly. You don&#8217;t have to deal with swapping a 64K chunk above the 640K wall then have the video card overwrite part of it. <em>Fun times!<\/em><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The physical loading of the database isn&#8217;t performed by a class. It is performed by a series of C++ functions all contained in the following source file. \/* * Copyright (c) 2018 Roland Hughes and Logical Solutions ALL RIGHTS RESERVED * * This code is &#8220;as-is&#8221; without any warranty expressed or implied. You may not modify or distribute it * without having purchased the right to do so from the copyright holder. This code is &hellip; <a title=\"Qt and USB &#8211; Pt. 4\" class=\"bnm-read-more\" href=\"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/\"><span class=\"screen-reader-text\">Qt and USB &#8211; Pt. 4<\/span>Read more<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,1113],"tags":[1504,159,1607],"class_list":["post-2839","post","type-post","status-publish","format-standard","hentry","category-information-technology","category-raspberry-pi","tag-c","tag-qt","tag-usb","bnm-entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Qt and USB - Pt. 4 &#8211; Logikal Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Qt and USB - Pt. 4 &#8211; Logikal Blog\" \/>\n<meta property=\"og:description\" content=\"The physical loading of the database isn&#8217;t performed by a class. It is performed by a series of C++ functions all contained in the following source file. \/* * Copyright (c) 2018 Roland Hughes and Logical Solutions ALL RIGHTS RESERVED * * This code is &quot;as-is&quot; without any warranty expressed or implied. You may not modify or distribute it * without having purchased the right to do so from the copyright holder. This code is &hellip; Qt and USB &#8211; Pt. 4Read more\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/\" \/>\n<meta property=\"og:site_name\" content=\"Logikal Blog\" \/>\n<meta property=\"article:published_time\" content=\"2018-05-31T21:24:23+00:00\" \/>\n<meta name=\"author\" content=\"seasoned_geek\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"seasoned_geek\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/\"},\"author\":{\"name\":\"seasoned_geek\",\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#\\\/schema\\\/person\\\/c077f770ade13de7faaf616c3eac6842\"},\"headline\":\"Qt and USB &#8211; Pt. 4\",\"datePublished\":\"2018-05-31T21:24:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/\"},\"wordCount\":414,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#\\\/schema\\\/person\\\/c077f770ade13de7faaf616c3eac6842\"},\"keywords\":[\"C++\",\"Qt\",\"usb\"],\"articleSection\":[\"Information Technology\",\"Raspberry Pi\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/\",\"url\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/\",\"name\":\"Qt and USB - Pt. 4 &#8211; Logikal Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#website\"},\"datePublished\":\"2018-05-31T21:24:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/information-technology\\\/qt-and-usb-pt-4\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Qt and USB &#8211; Pt. 4\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#website\",\"url\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/\",\"name\":\"Logikal Blog\",\"description\":\"For people with attention spans longer than a Tweet\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#\\\/schema\\\/person\\\/c077f770ade13de7faaf616c3eac6842\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/#\\\/schema\\\/person\\\/c077f770ade13de7faaf616c3eac6842\",\"name\":\"seasoned_geek\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r\",\"caption\":\"seasoned_geek\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r\"},\"description\":\"Roland Hughes started his IT career in the early 1980s. He quickly became a consultant and president of Logikal Solutions, a software consulting firm specializing in OpenVMS application and C++\\\/Qt touchscreen\\\/embedded Linux development. Early in his career he became involved in what is now called cross platform development. Given the dearth of useful books on the subject he ventured into the world of professional author in 1995 writing the first of the \\\"Zinc It!\\\" book series for John Gordon Burke Publisher, Inc. A decade later he released a massive (nearly 800 pages) tome \\\"The Minimum You Need to Know to Be an OpenVMS Application Developer\\\" which tried to encapsulate the essential skills gained over what was nearly a 20 year career at that point. From there \\\"The Minimum You Need to Know\\\" book series was born. Three years later he wrote his first novel \\\"Infinite Exposure\\\" which got much notice from people involved in the banking and financial security worlds. Some of the attacks predicted in that book have since come to pass. While it was not originally intended to be a trilogy, it became the first book of \\\"The Earth That Was\\\" trilogy: Infinite Exposure Lesedi - The Greatest Lie Ever Told John Smith - Last Known Survivor of the Microsoft Wars When he is not consulting Roland Hughes posts about technology and sometimes politics on his blog. He also has regularly scheduled Sunday posts appearing on the Interesting Authors blog.\",\"sameAs\":[\"https:\\\/\\\/theminimumyouneedtoknow.com\"],\"url\":\"https:\\\/\\\/www.logikalsolutions.com\\\/wordpress\\\/author\\\/seasoned_geek\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Qt and USB - Pt. 4 &#8211; Logikal Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/","og_locale":"en_US","og_type":"article","og_title":"Qt and USB - Pt. 4 &#8211; Logikal Blog","og_description":"The physical loading of the database isn&#8217;t performed by a class. It is performed by a series of C++ functions all contained in the following source file. \/* * Copyright (c) 2018 Roland Hughes and Logical Solutions ALL RIGHTS RESERVED * * This code is \"as-is\" without any warranty expressed or implied. You may not modify or distribute it * without having purchased the right to do so from the copyright holder. This code is &hellip; Qt and USB &#8211; Pt. 4Read more","og_url":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/","og_site_name":"Logikal Blog","article_published_time":"2018-05-31T21:24:23+00:00","author":"seasoned_geek","twitter_card":"summary_large_image","twitter_misc":{"Written by":"seasoned_geek","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/#article","isPartOf":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/"},"author":{"name":"seasoned_geek","@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#\/schema\/person\/c077f770ade13de7faaf616c3eac6842"},"headline":"Qt and USB &#8211; Pt. 4","datePublished":"2018-05-31T21:24:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/"},"wordCount":414,"commentCount":0,"publisher":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#\/schema\/person\/c077f770ade13de7faaf616c3eac6842"},"keywords":["C++","Qt","usb"],"articleSection":["Information Technology","Raspberry Pi"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/","url":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/","name":"Qt and USB - Pt. 4 &#8211; Logikal Blog","isPartOf":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#website"},"datePublished":"2018-05-31T21:24:23+00:00","breadcrumb":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.logikalsolutions.com\/wordpress\/information-technology\/qt-and-usb-pt-4\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.logikalsolutions.com\/wordpress\/"},{"@type":"ListItem","position":2,"name":"Qt and USB &#8211; Pt. 4"}]},{"@type":"WebSite","@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#website","url":"https:\/\/www.logikalsolutions.com\/wordpress\/","name":"Logikal Blog","description":"For people with attention spans longer than a Tweet","publisher":{"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#\/schema\/person\/c077f770ade13de7faaf616c3eac6842"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.logikalsolutions.com\/wordpress\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.logikalsolutions.com\/wordpress\/#\/schema\/person\/c077f770ade13de7faaf616c3eac6842","name":"seasoned_geek","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r","url":"https:\/\/secure.gravatar.com\/avatar\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r","caption":"seasoned_geek"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/ae9adac14079d84b909e635d7af986fe4568053af4fd9ff8d4109298c392493e?s=96&d=mm&r=r"},"description":"Roland Hughes started his IT career in the early 1980s. He quickly became a consultant and president of Logikal Solutions, a software consulting firm specializing in OpenVMS application and C++\/Qt touchscreen\/embedded Linux development. Early in his career he became involved in what is now called cross platform development. Given the dearth of useful books on the subject he ventured into the world of professional author in 1995 writing the first of the \"Zinc It!\" book series for John Gordon Burke Publisher, Inc. A decade later he released a massive (nearly 800 pages) tome \"The Minimum You Need to Know to Be an OpenVMS Application Developer\" which tried to encapsulate the essential skills gained over what was nearly a 20 year career at that point. From there \"The Minimum You Need to Know\" book series was born. Three years later he wrote his first novel \"Infinite Exposure\" which got much notice from people involved in the banking and financial security worlds. Some of the attacks predicted in that book have since come to pass. While it was not originally intended to be a trilogy, it became the first book of \"The Earth That Was\" trilogy: Infinite Exposure Lesedi - The Greatest Lie Ever Told John Smith - Last Known Survivor of the Microsoft Wars When he is not consulting Roland Hughes posts about technology and sometimes politics on his blog. He also has regularly scheduled Sunday posts appearing on the Interesting Authors blog.","sameAs":["https:\/\/theminimumyouneedtoknow.com"],"url":"https:\/\/www.logikalsolutions.com\/wordpress\/author\/seasoned_geek\/"}]}},"_links":{"self":[{"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/posts\/2839","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/comments?post=2839"}],"version-history":[{"count":0,"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/posts\/2839\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/media?parent=2839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/categories?post=2839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.logikalsolutions.com\/wordpress\/wp-json\/wp\/v2\/tags?post=2839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}