├── .nvmrc ├── .gemini └── code-config.yaml ├── Utils ├── EnumMap.cpp ├── IJsonable.cpp ├── StringVector.h ├── ExitCode.h ├── utils_export.h ├── win.h ├── equals_within.cpp ├── IJsonable.h ├── equals_within.h ├── fastmove.h ├── CrossPlatform.h ├── libarchive_extract.h ├── timestamp.h ├── crow_win.h ├── UrlEncoding.h ├── CrowReturnable.h ├── FileReader.h ├── StopWatch.h ├── JsonCrowReturnable.h ├── fastmove.cpp ├── StopWatch.cpp ├── CommandLineArgs.h ├── CMakeLists.txt ├── timestamp.cpp ├── FileReader.cpp ├── CrossPlatform.cpp ├── ArchiveExtractor.h ├── UrlEncoding.cpp ├── EnumMap.h └── str_utils.h ├── test_data └── FILES │ └── test.txt ├── local_ai_instruction_modules ├── ai-local-instructions.md └── ai-terminal-commands.md ├── OdbDesignLib ├── App │ ├── IOdbApp.cpp │ ├── IOdbServerApp.cpp │ ├── IOdbApp.h │ ├── RequestAuthenticationBase.h │ ├── IOdbServerApp.h │ ├── OdbAppBase.h │ ├── RouteController.h │ ├── BasicRequestAuthentication.h │ ├── RequestAuthenticationBase.cpp │ ├── OdbDesignArgs.h │ ├── OdbServerAppBase.h │ ├── DesignCache.h │ └── OdbDesignArgs.cpp ├── FileModel │ ├── invalid_odb_error.cpp │ ├── Design │ │ ├── FileArchive.h │ │ ├── AttributeLookupTable.h │ │ ├── RgbColor.h │ │ ├── PropertyRecord.cpp │ │ ├── PropertyRecord.h │ │ ├── SymbolName.h │ │ ├── RgbColor.cpp │ │ ├── SymbolsDirectory.h │ │ ├── AttrListFile.h │ │ ├── AttributeLookupTable.cpp │ │ ├── LayerDirectory.h │ │ ├── SymbolName.cpp │ │ ├── ContourPolygon.h │ │ ├── StepHdrFile.h │ │ ├── ContourPolygon.cpp │ │ ├── StandardFontsFile.h │ │ └── StepDirectory.h │ ├── IStreamSaveable.h │ ├── ISaveable.h │ ├── invalid_odb_error.h │ ├── parse_error.cpp │ ├── OdbFile.cpp │ ├── OdbFile.h │ ├── parse_info.cpp │ ├── parse_info.h │ └── parse_error.h ├── protoc │ ├── part.proto │ ├── pin.proto │ ├── color.proto │ ├── via.proto │ ├── symbolname.proto │ ├── attrlistfile.proto │ ├── symbolsdirectory.proto │ ├── enums.proto │ ├── net.proto │ ├── package.proto │ ├── pinconnection.proto │ ├── layerdirectory.proto │ ├── miscinfofile.proto │ ├── component.proto │ ├── stepdirectory.proto │ ├── filearchive.proto │ ├── toolsfile.proto │ ├── standardfontsfile.proto │ ├── common.proto │ ├── stephdrfile.proto │ ├── design.proto │ ├── netlistfile.proto │ ├── matrixfile.proto │ ├── featuresfile.proto │ └── componentsfile.proto ├── OdbDesign.h ├── odbdesign_export.h ├── Constants.h ├── enums.h └── ProductModel │ ├── Part.cpp │ ├── Part.h │ ├── Pin.cpp │ ├── Via.h │ ├── Pin.h │ ├── Via.cpp │ ├── Net.h │ ├── Package.h │ ├── PinConnection.h │ ├── Component.h │ ├── Net.cpp │ └── PinConnection.cpp ├── docs ├── odb_spec_user.pdf ├── odb++ file hierarchy (implemented).png ├── _config.yml ├── CONTRIBUTING.md ├── SECURITY.md └── CODEQL_SETUP_COMPLETE.md ├── OdbDesign.code-workspace ├── OdbDesignServer ├── OdbDesignServer.h ├── templates │ └── helloworld.html ├── main.cpp ├── Controllers │ ├── HelloWorldController.h │ ├── HealthCheckController.h │ ├── HelloWorldController.cpp │ ├── FileUploadController.h │ ├── DesignsController.h │ └── HealthCheckController.cpp ├── OdbDesignServerApp.h ├── CMakeLists.txt └── OdbDesignServerApp.cpp ├── .github ├── CODEOWNERS ├── prompts │ ├── odf_inp_adv-mem.prompt.md │ └── odf_project-setup_advanced-memory.prompt.md ├── dependabot.yml ├── workflows │ ├── disabled │ │ ├── validate-plans.yml │ │ ├── python-publish.yml │ │ └── test-runtime.yml │ ├── sbom-generate-submit.yml │ ├── prebuild.yml │ ├── dependency-review.yml │ └── validate-setup-scripts.yml ├── problem-matchers │ ├── eslint-stylish.json │ └── dotnet.json ├── ISSUE_TEMPLATE │ ├── feature_request.md │ ├── bug_report.md │ └── copilot-task.md ├── codeql │ └── cpp-queries │ │ ├── odbdesign-suite.qls │ │ └── odbdesign-security.ql ├── .branch-protection-ruleset_protected branches.json ├── codeql-config.yml ├── .labels.json ├── .mcp-github.json └── mcp.json ├── .idea ├── OdbDesign.iml ├── misc.xml ├── codeStyles │ └── codeStyleConfig.xml ├── vcs.xml └── modules.xml ├── deploy ├── helm │ ├── values-trivy.yaml │ └── values-prom.yaml └── kube │ ├── k3d-volume-pvc.yaml │ ├── k3d-volume-pv.yaml │ ├── issuer.yaml │ ├── OdbDesignServer-SwaggerUI │ ├── service.yaml │ └── deployment.yaml │ ├── OdbDesignServer │ └── service.yaml │ ├── local-ingress.yaml │ └── default-ingress (eks).yaml ├── .vscode ├── settings.json ├── mcp.json └── codeql-settings.json ├── OdbDesignApp ├── OdbDesignApp.h └── CMakeLists.txt ├── .dockerignore ├── scripts ├── odbdesign-server-request-secret.ps1 ├── fetch-setup-linux-script.ps1 ├── install-dependencies-deb.sh ├── patch │ ├── compile_wrapper_consider_clang-cl.patch │ └── mingw-w64-x86_64.cmake ├── compress-artifacts.sh ├── deploy-monitoring.ps1 ├── compile-protobuf.ps1 ├── patch-vcpkg-install.ps1 ├── compress-artifacts.ps1 ├── common-auth.ps1 ├── validate-toolset.ps1 ├── deploy.ps1 ├── create-k3d-cluster.ps1 └── create-release.js ├── vcpkg-configuration.json ├── release └── release-body.md ├── OdbDesignTests ├── Fixtures │ ├── DesignNameValueParamTest.h │ ├── FileArchiveLoadFixture.h │ ├── TestDataFixture.h │ ├── FileArchiveLoadFixture.cpp │ └── TestDataFixture.cpp ├── CMakeLists_Remote.txt ├── ArchiveTests.cpp ├── ArchiveExtractorTests.cpp ├── DesignCacheLoadTests.cpp ├── CMakeLists.txt ├── TestTests.cpp └── FileReaderTests.cpp ├── testEnvironments.json ├── vcpkg.json ├── Those qualities are certainly beneficial.txt ├── compose.yml ├── .gitignore └── .devcontainer └── devcontainer.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 22.18.0 2 | -------------------------------------------------------------------------------- /.gemini/code-config.yaml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Utils/EnumMap.cpp: -------------------------------------------------------------------------------- 1 | #include "EnumMap.h" -------------------------------------------------------------------------------- /Utils/IJsonable.cpp: -------------------------------------------------------------------------------- 1 | #include "IJsonable.h" -------------------------------------------------------------------------------- /test_data/FILES/test.txt: -------------------------------------------------------------------------------- 1 | Test file content 2 | -------------------------------------------------------------------------------- /local_ai_instruction_modules/ai-local-instructions.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /OdbDesignLib/App/IOdbApp.cpp: -------------------------------------------------------------------------------- 1 | #include "IOdbServerApp.h" -------------------------------------------------------------------------------- /OdbDesignLib/App/IOdbServerApp.cpp: -------------------------------------------------------------------------------- 1 | #include "IOdbServerApp.h" -------------------------------------------------------------------------------- /docs/odb_spec_user.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nam20485/OdbDesign/HEAD/docs/odb_spec_user.pdf -------------------------------------------------------------------------------- /OdbDesign.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | } 6 | ], 7 | "settings": {} 8 | } -------------------------------------------------------------------------------- /OdbDesignServer/OdbDesignServer.h: -------------------------------------------------------------------------------- 1 | // OdbDesignServer.h : Header file for your target. 2 | 3 | #pragma once 4 | 5 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # 2 | # CODEOWNERS 3 | # 4 | 5 | # Everything in this repo is owned by @nam20485 6 | * @nam20485 -------------------------------------------------------------------------------- /.idea/OdbDesign.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/invalid_odb_error.cpp: -------------------------------------------------------------------------------- 1 | #include "invalid_odb_error.h" 2 | 3 | namespace Odb::Lib::FileModel 4 | { 5 | 6 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/FileArchive.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nam20485/OdbDesign/HEAD/OdbDesignLib/FileModel/Design/FileArchive.h -------------------------------------------------------------------------------- /docs/odb++ file hierarchy (implemented).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nam20485/OdbDesign/HEAD/docs/odb++ file hierarchy (implemented).png -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /deploy/helm/values-trivy.yaml: -------------------------------------------------------------------------------- 1 | serviceMonitor: 2 | # enabled determines whether a serviceMonitor should be deployed 3 | enabled: true 4 | trivy: 5 | ignoreUnfixed: true -------------------------------------------------------------------------------- /OdbDesignServer/templates/helloworld.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Hello {{design}}!

5 | 6 | -------------------------------------------------------------------------------- /Utils/StringVector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Utils 7 | { 8 | typedef std::vector StringVector; 9 | } 10 | -------------------------------------------------------------------------------- /deploy/helm/values-prom.yaml: -------------------------------------------------------------------------------- 1 | prometheus: 2 | prometheusSpec: 3 | serviceMonitorSelectorNilUsesHelmValues: true 4 | serviceMonitorSelector: {} 5 | serviceMonitorNamespaceSelector: {} -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "sonarlint.pathToCompileCommands": "${config:cmake.buildDirectory}/compile_commands.json", 3 | "sonarlint.connectedMode.project": { 4 | "connectionId": "nam20485", 5 | "projectKey": "nam20485_OdbDesign" 6 | } 7 | } -------------------------------------------------------------------------------- /OdbDesignApp/OdbDesignApp.h: -------------------------------------------------------------------------------- 1 | // OdbDesignApp.h : Include file for standard system include files, 2 | // or project specific include files. 3 | 4 | #pragma once 5 | 6 | //#include 7 | 8 | // TODO: Reference additional headers your program requires here. 9 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | out/ 2 | .vs/ 3 | .github/ 4 | .git/ 5 | .gitignore 6 | .gitattributes 7 | Dockerfile* 8 | docker-compose.yml 9 | *.code-workspace 10 | vcpkg_installed/ 11 | ssl/ 12 | out/ 13 | cmake-build-*/ 14 | build/ 15 | .idea/ 16 | Testing/ 17 | *.code-workspace 18 | -------------------------------------------------------------------------------- /scripts/odbdesign-server-request-secret.ps1: -------------------------------------------------------------------------------- 1 | kubectl create secret generic 'odbdesign-server-request-secret' --from-literal=ODBDESIGN_SERVER_REQUEST_USERNAME=$env:ODBDESIGN_SERVER_REQUEST_USERNAME --from-literal=ODBDESIGN_SERVER_REQUEST_PASSWORD=$env:ODBDESIGN_SERVER_REQUEST_PASSWORD -------------------------------------------------------------------------------- /scripts/fetch-setup-linux-script.ps1: -------------------------------------------------------------------------------- 1 | Invoke-WebRequest -Uri "https://raw.githubusercontent.com/nam20485/OdbDesign/development/.github/setup-environment.sh" ` 2 | -OutFile ".github/setup-environment.sh" ` 3 | -Headers @{"Accept"="application/vnd.github.raw"} 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OdbDesignServer/main.cpp: -------------------------------------------------------------------------------- 1 | // main.cpp : Source file for your target. 2 | // 3 | 4 | #include "OdbDesignServerApp.h" 5 | 6 | using namespace Odb::App::Server; 7 | 8 | int main(int argc, char* argv[]) 9 | { 10 | OdbDesignServerApp serverApp(argc, argv); 11 | return static_cast(serverApp.Run()); 12 | } -------------------------------------------------------------------------------- /deploy/kube/k3d-volume-pvc.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: PersistentVolumeClaim 4 | metadata: 5 | #name: task-pv-claim 6 | name: k3d-volume-claim 7 | spec: 8 | storageClassName: manual 9 | accessModes: 10 | - ReadWriteOnce 11 | resources: 12 | requests: 13 | storage: 10Gi 14 | -------------------------------------------------------------------------------- /.github/prompts/odf_inp_adv-mem.prompt.md: -------------------------------------------------------------------------------- 1 | --- 2 | mode: agent 3 | --- 4 | 5 | /orchestrate-dynamic-workflow 6 | - $workflow_name = `initiate-new-repo`, 7 | - $context = { 8 | repo_name = "advanced_memory", 9 | app_plan_docs = [ #file:Advanced Memory .NET - Dev Plan.md , #file:index.html ] 10 | } 11 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/part.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf.ProductModel; 7 | 8 | // 9 | // Part.h 10 | // 11 | 12 | message Part { 13 | 14 | optional string name = 1; 15 | 16 | } -------------------------------------------------------------------------------- /.github/prompts/odf_project-setup_advanced-memory.prompt.md: -------------------------------------------------------------------------------- 1 | --- 2 | mode: agent 3 | --- 4 | 5 | /orchestrate-dynamic-workflow 6 | - $workflow_name = `project-setup`, 7 | - $context = { 8 | repo_name = "advanced_memory", 9 | app_plan_docs = [ #file:Advanced Memory .NET - Dev Plan.md , #file:index.html ] 10 | } -------------------------------------------------------------------------------- /deploy/kube/k3d-volume-pv.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: PersistentVolume 3 | metadata: 4 | name: k3d-volume 5 | #name: task-pv-volume 6 | labels: 7 | type: local 8 | spec: 9 | storageClassName: manual 10 | capacity: 11 | storage: 1Ti 12 | accessModes: 13 | - ReadWriteOnce 14 | hostPath: 15 | path: /mnt/d/k3dvolume -------------------------------------------------------------------------------- /Utils/ExitCode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | namespace Utils 5 | { 6 | enum class ExitCode 7 | { 8 | Success = 0, 9 | FailedInit = 1, 10 | FailedInitSsl = 2, 11 | FailedInitSslDirDoesNotExist = 3, 12 | FailedInitLoadDesign = 4, 13 | PreServerRunFailed = 5, 14 | PostServerRunFailed = 6, 15 | UnknownError = 7 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /Utils/utils_export.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(_WIN32) 3 | # if defined(Utils_EXPORTS) 4 | # define UTILS_EXPORT __declspec(dllexport) 5 | # define EXPIMP_TEMPLATE 6 | # else 7 | # define UTILS_EXPORT __declspec(dllimport) 8 | # //define EXPIMP_TEMPLATE extern 9 | # endif 10 | #else // non windows 11 | # define UTILS_EXPORT 12 | #endif 13 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/IStreamSaveable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../odbdesign_export.h" 5 | 6 | namespace Odb::Lib::FileModel 7 | { 8 | class ODBDESIGN_EXPORT IStreamSaveable 9 | { 10 | public: 11 | virtual bool Save(std::ostream& os) = 0; 12 | 13 | protected: 14 | IStreamSaveable() = default; 15 | }; 16 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/ISaveable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../odbdesign_export.h" 5 | 6 | namespace Odb::Lib::FileModel 7 | { 8 | class ODBDESIGN_EXPORT ISaveable 9 | { 10 | public: 11 | virtual bool Save(const std::filesystem::path& directory) = 0; 12 | 13 | protected: 14 | ISaveable() = default; 15 | }; 16 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/pin.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf.ProductModel; 7 | 8 | // 9 | // Pin.h 10 | // 11 | 12 | message Pin { 13 | 14 | optional string name = 1; 15 | optional uint32 index = 2; 16 | 17 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/color.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | message Color { 9 | optional float red = 1; 10 | optional float green = 2; 11 | optional float blue = 3; 12 | 13 | optional bool noPreference = 4; 14 | } -------------------------------------------------------------------------------- /Utils/win.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | 5 | #define WIN32_LEAN_AND_MEAN 6 | 7 | #include 8 | 9 | #ifndef _WIN32_WINNT_WIN7 10 | # define _WIN32_WINNT_WIN7 0x0601 11 | #endif 12 | 13 | #define _WIN32_WINNT _WIN32_WINNT_WIN7 14 | #define WINVER _WIN32_WINNT 15 | 16 | #include 17 | //#include 18 | 19 | #endif -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | remote_theme: pages-themes/minimal@v0.2.0 2 | plugins: 3 | - jekyll-remote-theme # add this line to the plugins list if you already have one 4 | 5 | title: OdbDesign ODB++ Parser 6 | description: REST API and C++ library for parsing ODB++ Design archives 7 | show_downloads: false 8 | 9 | url: https://source.odbdesignserver.com 10 | #baseurl: /jekyll-blog-demo 11 | -------------------------------------------------------------------------------- /OdbDesignLib/OdbDesign.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // include headers for linking to library 4 | 5 | #include "FileModel/Design/FileArchive.h" 6 | #include "FileModel/parse_error.h" 7 | #include "FileModel/invalid_odb_error.h" 8 | 9 | #include "ProductModel/Design.h" 10 | 11 | #include "App/DesignCache.h" 12 | #include "App/OdbAppBase.h" 13 | #include "App/OdbServerAppBase.h" 14 | 15 | 16 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/via.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "enums.proto"; 7 | 8 | package Odb.Lib.Protobuf.ProductModel; 9 | 10 | // 11 | // Via.h 12 | // 13 | 14 | message Via { 15 | 16 | optional string name = 1; 17 | optional BoardSide boardSide = 2; 18 | 19 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/symbolname.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "enums.proto"; 7 | 8 | package Odb.Lib.Protobuf; 9 | 10 | // 11 | // SymbolName.h 12 | // 13 | 14 | message SymbolName { 15 | 16 | optional string name = 1; 17 | optional UnitType unitType = 2; 18 | } 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: github-actions 4 | directory: / 5 | schedule: 6 | interval: weekly 7 | 8 | - package-ecosystem: pip 9 | directory: /PyOdbDesignServer 10 | schedule: 11 | interval: weekly 12 | 13 | - package-ecosystem: docker 14 | directory: / 15 | schedule: 16 | interval: weekly 17 | #target-branch: nam20485 18 | -------------------------------------------------------------------------------- /.github/workflows/disabled/validate-plans.yml: -------------------------------------------------------------------------------- 1 | name: Disabled - goldens removed (SSOT) 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | workflow_dispatch: 8 | 9 | jobs: 10 | noop: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: No-op 14 | run: echo "Plan validation via goldens is disabled. Dynamic workflows and assignments are the single source of truth." 15 | -------------------------------------------------------------------------------- /OdbDesignLib/odbdesign_export.h: -------------------------------------------------------------------------------- 1 | 2 | #if defined(_WIN32) 3 | # if defined(OdbDesign_EXPORTS) 4 | # define ODBDESIGN_EXPORT __declspec(dllexport) 5 | # define EXPIMP_TEMPLATE 6 | # else 7 | # define ODBDESIGN_EXPORT __declspec(dllimport) 8 | # //define EXPIMP_TEMPLATE extern 9 | # endif 10 | #else // non windows define it to nothing (Linux exports by default) 11 | # define ODBDESIGN_EXPORT 12 | #endif 13 | -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/HelloWorldController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "App/RouteController.h" 4 | #include "App/IOdbServerApp.h" 5 | 6 | 7 | namespace Odb::App::Server 8 | { 9 | class HelloWorldController : public Odb::Lib::App::RouteController 10 | { 11 | public: 12 | HelloWorldController(Odb::Lib::App::IOdbServerApp& serverApp); 13 | 14 | void register_routes() override; 15 | 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /Utils/equals_within.cpp: -------------------------------------------------------------------------------- 1 | #include "equals_within.h" 2 | 3 | namespace Utils 4 | { 5 | bool float_equals(float a, float b, float epsilon) 6 | { 7 | //return std::abs(a - b) < epsilon; 8 | return equals_within(a, b, epsilon); 9 | } 10 | 11 | bool double_equals(double a, double b, double epsilon) 12 | { 13 | //return std::abs(a - b) < epsilon; 14 | return equals_within(a, b, epsilon); 15 | } 16 | } -------------------------------------------------------------------------------- /vcpkg-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "default-registry": { 3 | "kind": "git", 4 | "baseline": "cf035d9916a0a23042b41fcae7ee0386d245af08", 5 | "repository": "https://github.com/microsoft/vcpkg" 6 | }, 7 | "registries": [ 8 | { 9 | "kind": "artifact", 10 | "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", 11 | "name": "microsoft" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Utils/IJsonable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | 6 | namespace Utils 7 | { 8 | class UTILS_EXPORT IJsonable 9 | { 10 | public: 11 | virtual ~IJsonable() {} 12 | 13 | virtual std::string to_json() const = 0; 14 | virtual void from_json(const std::string& json) = 0; 15 | 16 | protected: 17 | // abstract class/interface 18 | IJsonable() = default; 19 | 20 | }; 21 | } 22 | -------------------------------------------------------------------------------- /release/release-body.md: -------------------------------------------------------------------------------- 1 | ## Docker 2 | 3 | The signed Docker image for this release can be found here: 4 | 5 | * [nam20485/odbdesign:release-latest](https://github.com/nam20485/OdbDesign/pkgs/container/odbdesign/139993649?tag=release-latest) 6 | 7 | _If a specific tag that changes with each release is required, you can find the matching tag of the form `release-nnn`, where `nnn` is an monotonically-increasing integer, on the same page._ 8 | -------------------------------------------------------------------------------- /OdbDesignTests/Fixtures/DesignNameValueParamTest.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gtest/gtest.h" 4 | #include 5 | #include "OdbDesign.h" 6 | #include 7 | #include 8 | #include "FileArchiveLoadFixture.h" 9 | 10 | namespace Odb::Test::Fixtures 11 | { 12 | class DesignNameValueParamTest : public FileArchiveLoadFixture, 13 | public testing::WithParamInterface 14 | { 15 | 16 | }; 17 | } -------------------------------------------------------------------------------- /Utils/equals_within.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | 6 | namespace Utils 7 | { 8 | template 9 | bool equals_within(const R a, const R b, const R epsilon = 0.001f) 10 | { 11 | return std::abs(a - b) < epsilon; 12 | } 13 | 14 | UTILS_EXPORT bool float_equals(float a, float b, float epsilon = 0.001f); 15 | 16 | UTILS_EXPORT bool double_equals(double a, double b, double epsilon = 0.001); 17 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/attrlistfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | // 9 | // StepDirectory.h 10 | // 11 | 12 | message AttrListFile { 13 | 14 | optional string directory = 1; 15 | optional string path = 2; 16 | optional string units = 3; 17 | map attributesByName = 4; 18 | } -------------------------------------------------------------------------------- /scripts/install-dependencies-deb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | sudo apt update 5 | sudo apt install -y -qq --no-install-recommends \ 6 | git \ 7 | cmake \ 8 | ninja-build \ 9 | build-essential \ 10 | docker.io \ 11 | docker-compose-v2 12 | 13 | git clone https://github.com/microsoft/vcpkg $HOME/vcpkg 14 | "$HOME/vcpkg/bootstrap-vcpkg.sh" -------------------------------------------------------------------------------- /Utils/fastmove.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | #include 6 | 7 | namespace Utils 8 | { 9 | UTILS_EXPORT void move_file(const std::filesystem::path& source, const std::filesystem::path& dest, bool overwriteExisting, std::error_code& ec); 10 | UTILS_EXPORT void fastmove_file(const std::filesystem::path& source, const std::filesystem::path& dest, bool overwriteExisting, std::error_code& ec); 11 | } 12 | -------------------------------------------------------------------------------- /testEnvironments.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "environments": [ 4 | // See https://aka.ms/remotetesting for more details 5 | // about how to configure remote environments. 6 | { 7 | "name": "WSL Ubuntu", 8 | "type": "wsl", 9 | "wslDistribution": "Ubuntu" 10 | }, 11 | { 12 | "name": "Docker dotnet/sdk", 13 | "type": "docker", 14 | "dockerImage": "mcr.microsoft.com/dotnet/sdk" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /.vscode/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "inputs": [], 3 | "servers": { 4 | "sequential-thinking": { 5 | "type": "stdio", 6 | "command": "npx", 7 | "args": [ 8 | "-y", 9 | "@modelcontextprotocol/server-sequential-thinking" 10 | ], 11 | "version": "0.0.1" 12 | }, 13 | "memory": { 14 | "type": "stdio", 15 | "command": "npx", 16 | "args": [ 17 | "-y", 18 | "@modelcontextprotocol/server-memory" 19 | ], 20 | "version": "0.0.1" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /OdbDesignLib/Constants.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // 4 | // Created by nmill on 10/13/2023. 5 | // 6 | 7 | namespace Odb::Lib::FileModel::Design 8 | { 9 | class Constants 10 | { 11 | public: 12 | inline static const auto COMMENT_TOKEN = "#"; 13 | inline static const auto UNITS_TOKEN = "UNITS"; 14 | inline static const auto ARRAY_RECORD_OPEN_TOKEN = "{"; 15 | inline static const auto ARRAY_RECORD_CLOSE_TOKEN = "}"; 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/invalid_odb_error.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace Odb::Lib::FileModel 7 | { 8 | class invalid_odb_error : public std::runtime_error 9 | { 10 | public: 11 | invalid_odb_error(const char* message) 12 | : runtime_error(message) 13 | { 14 | } 15 | 16 | invalid_odb_error(const std::string& message) 17 | : invalid_odb_error(message.c_str()) 18 | { 19 | } 20 | }; 21 | } -------------------------------------------------------------------------------- /OdbDesignLib/enums.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace Odb::Lib 4 | { 5 | enum class BoardSide 6 | { 7 | BsNone, 8 | Top, 9 | Bottom 10 | }; 11 | 12 | enum class LineShape 13 | { 14 | Square, 15 | Round 16 | }; 17 | 18 | enum class Polarity 19 | { 20 | Positive, 21 | Negative 22 | }; 23 | 24 | enum class UnitType 25 | { 26 | None, 27 | Metric, 28 | Imperial 29 | }; 30 | 31 | enum class DesignType 32 | { 33 | FileArchive, 34 | Design 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /Utils/CrossPlatform.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //#include 4 | #include "utils_export.h" 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Utils 10 | { 11 | class UTILS_EXPORT CrossPlatform 12 | { 13 | public: 14 | static bool localtime_safe(const std::time_t* time, struct std::tm& tmOut); 15 | static bool getenv_safe(const char* env_var, std::string& envValueOut); 16 | static bool tmpnam_safe(std::string& tempNameOut); 17 | 18 | }; 19 | } 20 | -------------------------------------------------------------------------------- /Utils/libarchive_extract.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "utils_export.h" 4 | #include 5 | 6 | namespace Utils 7 | { 8 | enum class CompressionType 9 | { 10 | TarGzip 11 | }; 12 | 13 | bool extract(const char* filename, const char* destDir); 14 | UTILS_EXPORT bool compress_dir(const char* srcDir, 15 | const char* destDir, 16 | const char* archiveName, 17 | std::string& fileOut, 18 | CompressionType type = CompressionType::TarGzip); 19 | } 20 | -------------------------------------------------------------------------------- /Utils/timestamp.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by nam20485 on 6/12/22. 3 | // 4 | 5 | #pragma once 6 | 7 | #include 8 | #include 9 | #include "utils_export.h" 10 | 11 | namespace Utils 12 | { 13 | std::string UTILS_EXPORT make_timestamp(const std::chrono::system_clock::time_point& timepoint); 14 | std::string UTILS_EXPORT make_timestamp(); 15 | 16 | std::chrono::system_clock::time_point UTILS_EXPORT parse_timestamp(const std::string& timestamp, const std::string& format); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /Utils/crow_win.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // disable error-checking in crow's json code to improve its performance 4 | // https://crowcpp.org/master/guides/json/ 5 | //#define CROW_JSON_NO_ERROR_CHECK 6 | 7 | #include "win.h" 8 | #include "crow.h" 9 | #include "crow/middlewares/cors.h" 10 | #include "crow/app.h" 11 | #include "crow/http_request.h" 12 | #include "crow/http_response.h" 13 | #include 14 | #include 15 | 16 | 17 | using CrowApp = crow::Crow; -------------------------------------------------------------------------------- /Utils/UrlEncoding.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | 6 | namespace Utils 7 | { 8 | // inspired by: https://github.com/davisking/dlib/blob/f7d99ae0dc97c00c1690863881709b7a8b89bb40/dlib/server/server_http.cpp 9 | 10 | class UTILS_EXPORT UrlEncoding 11 | { 12 | public: 13 | static std::string encode(const std::string& unencoded); 14 | static std::string decode(const std::string& encoded); 15 | 16 | // static-only class 17 | UrlEncoding() = delete; 18 | 19 | }; 20 | } 21 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/symbolsdirectory.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | import "attrlistfile.proto"; 9 | import "featuresfile.proto"; 10 | 11 | // 12 | // LayerDirectory.h 13 | // 14 | 15 | message SymbolsDirectory { 16 | 17 | optional string name = 1; 18 | optional string path = 2; 19 | 20 | optional AttrListFile attrlistFile = 3; 21 | optional FeaturesFile featureFile = 4; 22 | } -------------------------------------------------------------------------------- /docs/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | The project is happy to accept pull requests if you would like to contribute. Please open an issue to discuss your proposed changes before submitting a pull request. Pull requests are accepted against the `development` branch. Please make sure your pull request is up to date with the latest changes in the `development` branch before submitting it. 4 | 5 | All contributed code must be covered by accompanying test cases. Please make sure your changes are covered by test cases before submitting a pull request. 6 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/enums.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | enum BoardSide 9 | { 10 | BsNone = 0; 11 | Top = 1; 12 | Bottom = 2; 13 | }; 14 | 15 | enum LineShape 16 | { 17 | Square = 0; 18 | Round = 1; 19 | }; 20 | 21 | enum Polarity 22 | { 23 | Positive = 0; 24 | Negative = 1; 25 | }; 26 | 27 | enum UnitType 28 | { 29 | None = 0; 30 | Metric = 1; 31 | Imperial = 2; 32 | }; -------------------------------------------------------------------------------- /scripts/patch/compile_wrapper_consider_clang-cl.patch: -------------------------------------------------------------------------------- 1 | diff --git a/usr/share/automake-1.16/compile b/usr/share/automake-1.16/compile 2 | index 2078fc833..dfc946593 100755 3 | --- a/usr/share/automake-1.16/compile 4 | +++ b/usr/share/automake-1.16/compile 5 | @@ -256,6 +256,7 @@ EOF 6 | exit $? 7 | ;; 8 | cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ 9 | + clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \ 10 | icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) 11 | func_cl_wrapper "$@" # Doesn't return... 12 | ;; 13 | -------------------------------------------------------------------------------- /OdbDesignLib/App/IOdbApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OdbDesignArgs.h" 4 | #include "DesignCache.h" 5 | #include "ExitCode.h" 6 | #include "../odbdesign_export.h" 7 | 8 | namespace Odb::Lib::App 9 | { 10 | class ODBDESIGN_EXPORT IOdbApp 11 | { 12 | public: 13 | virtual ~IOdbApp() {} 14 | 15 | virtual const OdbDesignArgs& args() const = 0; 16 | virtual DesignCache& designs() = 0; 17 | 18 | virtual Utils::ExitCode Run() = 0; 19 | 20 | protected: 21 | // abstract class/interface 22 | IOdbApp() = default; 23 | 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /OdbDesignLib/App/RequestAuthenticationBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include "crow_win.h" 5 | 6 | namespace Odb::Lib::App 7 | { 8 | class ODBDESIGN_EXPORT RequestAuthenticationBase 9 | { 10 | public: 11 | virtual crow::response AuthenticateRequest(const crow::request& req); 12 | 13 | protected: 14 | RequestAuthenticationBase(bool disableAuthentication); 15 | 16 | // pure virtual interface 17 | RequestAuthenticationBase() = default; 18 | 19 | bool m_disableAuthentication = false; 20 | 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /.github/problem-matchers/eslint-stylish.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "eslint-stylish", 5 | "pattern": [ 6 | { 7 | "regexp": "^([^\\s].*)$", 8 | "file": 1 9 | }, 10 | { 11 | "regexp": "^\\s+(\\d+):(\\d+)\\s+(error|warning|info)\\s+(.*)\\s\\s+(.*)$", 12 | "line": 1, 13 | "column": 2, 14 | "severity": 3, 15 | "message": 4, 16 | "code": 5, 17 | "loop": true 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/net.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "pinconnection.proto"; 7 | 8 | package Odb.Lib.Protobuf.ProductModel; 9 | 10 | // 11 | // Net.h 12 | // 13 | 14 | message Net { 15 | 16 | // std::string m_name; 17 | // PinConnection::Vector m_pinConnections; 18 | // unsigned int m_index; 19 | 20 | optional string name = 1; 21 | repeated PinConnection pinConnections = 2; 22 | optional uint32 index = 3; 23 | 24 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/package.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "pin.proto"; 7 | 8 | package Odb.Lib.Protobuf.ProductModel; 9 | 10 | // 11 | // Package.h 12 | // 13 | 14 | message Package { 15 | 16 | // std::string m_name; 17 | // Pin::Vector m_pins; 18 | // Pin::StringMap m_pinsByName; 19 | // unsigned int m_index; 20 | 21 | optional string name = 1; 22 | repeated Pin pins = 2; 23 | map pinsByName = 3; 24 | optional uint32 index = 4; 25 | } -------------------------------------------------------------------------------- /deploy/kube/issuer.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: cert-manager.io/v1 2 | kind: Issuer 3 | metadata: 4 | name: letsencrypt-staging 5 | spec: 6 | acme: 7 | # The ACME server URL 8 | server: https://acme-staging-v02.api.letsencrypt.org/directory 9 | # Email address used for ACME registration 10 | email: nmiller217@gmail.com 11 | # Name of a secret used to store the ACME account private key 12 | privateKeySecretRef: 13 | name: letsencrypt-staging-tls 14 | # Enable the HTTP-01 challenge provider 15 | solvers: 16 | - http01: 17 | ingress: 18 | ingressClassName: traefik -------------------------------------------------------------------------------- /OdbDesignLib/protoc/pinconnection.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "component.proto"; 7 | import "pin.proto"; 8 | 9 | package Odb.Lib.Protobuf.ProductModel; 10 | 11 | // 12 | // PinConnection.h 13 | // 14 | 15 | message PinConnection { 16 | 17 | // std::string m_name; 18 | // std::shared_ptr m_pComponent; 19 | // std::shared_ptr m_pPin; 20 | 21 | optional string name = 1; 22 | optional Component component = 2; 23 | optional Pin pin = 3; 24 | 25 | } -------------------------------------------------------------------------------- /OdbDesignApp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : CMake project for OdbDesignApp, include source and define 2 | # project specific logic here. 3 | # 4 | 5 | # Add source to this project's executable. 6 | add_executable (OdbDesignApp "OdbDesignApp.cpp" "OdbDesignApp.h" ) 7 | 8 | ## PCH 9 | #if (NOT DEFINED ENV{CI}) 10 | file (GLOB_RECURSE ODBDESIGN_APP_HEADER_FILES "*.h") 11 | target_precompile_headers(OdbDesignApp PRIVATE ${ODBDESIGN_APP_HEADER_FILES}) 12 | #endif() 13 | 14 | # link to OdbDesign library 15 | target_link_libraries(OdbDesignApp PRIVATE OdbDesign) 16 | 17 | # TODO: Add tests and install targets if needed. 18 | -------------------------------------------------------------------------------- /OdbDesignServer/OdbDesignServerApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "OdbDesignServer.h" 4 | #include "App/OdbServerAppBase.h" 5 | 6 | 7 | namespace Odb::App::Server 8 | { 9 | class OdbDesignServerApp : public Odb::Lib::App::OdbServerAppBase 10 | { 11 | public: 12 | OdbDesignServerApp(int argc, char* argv[]); 13 | //~OdbDesignServerApp(); 14 | 15 | //Utils::ExitCode Run() override; 16 | 17 | protected: 18 | void add_controllers() override; 19 | 20 | 21 | // Inherited via OdbServerAppBase 22 | bool preServerRun() override; 23 | //bool postServerRun() override; 24 | 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /OdbDesignLib/App/IOdbServerApp.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IOdbApp.h" 4 | #include "../odbdesign_export.h" 5 | #include "RequestAuthenticationBase.h" 6 | #include 7 | 8 | namespace Odb::Lib::App 9 | { 10 | class ODBDESIGN_EXPORT IOdbServerApp : public virtual IOdbApp 11 | { 12 | public: 13 | virtual ~IOdbServerApp() {} 14 | 15 | virtual CrowApp& crow_app() = 0; 16 | virtual RequestAuthenticationBase& request_auth() = 0; 17 | virtual void request_auth(std::unique_ptr requestAuthentication) = 0; 18 | 19 | protected: 20 | IOdbServerApp() = default; 21 | 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/AttributeLookupTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include "../../odbdesign_export.h" 5 | 6 | 7 | namespace Odb::Lib::FileModel::Design 8 | { 9 | class ODBDESIGN_EXPORT AttributeLookupTable 10 | { 11 | public: 12 | 13 | const std::map& GetAttributeLookupTable() const; 14 | bool ParseAttributeLookupTable(const std::string& AttributeLookupTableString); 15 | 16 | protected: 17 | AttributeLookupTable() = default; // abtract class 18 | 19 | std::map m_attributeLookupTable; 20 | 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /OdbDesignTests/CMakeLists_Remote.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : CMake project for OdbDesignTests 2 | # 3 | 4 | enable_testing() 5 | 6 | add_executable(OdbDesignTests 7 | "Fixtures/FileArchiveLoadFixture.h" 8 | "Fixtures/FileArchiveLoadFixture.cpp" 9 | "TestTests.cpp" 10 | "DesignLoadTests.cpp" 11 | "Fixtures/DesignNameValueParamTest.h" 12 | "FileArchiveLoadTests.cpp" 13 | ) 14 | 15 | target_link_libraries(OdbDesignTests PRIVATE GTest::gtest_main) 16 | 17 | # link to OdbDesign library 18 | target_link_libraries(OdbDesignTests PRIVATE OdbDesign) 19 | 20 | include(GoogleTest) 21 | gtest_discover_tests(OdbDesignTests) -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/HealthCheckController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | #include "App/RouteController.h" 5 | #include "App/IOdbServerApp.h" 6 | 7 | namespace Odb::App::Server 8 | { 9 | 10 | class HealthCheckController : public Odb::Lib::App::RouteController 11 | { 12 | public: 13 | HealthCheckController(Odb::Lib::App::IOdbServerApp& serverApp); 14 | 15 | void register_routes() override; 16 | 17 | private: 18 | crow::response health_check_live(const crow::request& req); 19 | crow::response health_check_ready(const crow::request& req); 20 | crow::response health_check_started(const crow::request& req); 21 | 22 | }; 23 | } 24 | -------------------------------------------------------------------------------- /scripts/compress-artifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # COPY --from=build /src/OdbDesign/out/build/linux-release/OdbDesignLib/*.so . 4 | # COPY --from=build /src/OdbDesign/out/build/linux-release/Utils/*.so . 5 | # COPY --from=build /src/OdbDesign/out/build/linux-release/OdbDesignServer/OdbDesignServer . 6 | 7 | mkdir ./artifacts 8 | cp ./out/build/linux-release/OdbDesignLib/*.so ./artifacts 9 | cp ./out/build/linux-release/Utils/*.so ./artifacts 10 | cp ./out/build/linux-release/OdbDesignServer/OdbDesignServer ./artifacts 11 | #cp ./out/build/linux-release/OdbDesignServer/*.so ./artifacts 12 | cd ./artifacts 13 | zip -r ./artifacts.zip ./*.so ./OdbDesignServer -------------------------------------------------------------------------------- /Utils/CrowReturnable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "crow_win.h" 4 | 5 | namespace Utils 6 | { 7 | template 8 | class CrowReturnable : public crow::returnable 9 | { 10 | public: 11 | CrowReturnable(const T& t, const std::string& contentType) 12 | : crow::returnable(contentType) 13 | , m_t(t) 14 | {} 15 | 16 | protected: 17 | const T& m_t; 18 | 19 | // Inherited via returnable 20 | std::string dump() const override; 21 | 22 | virtual std::string to_string() const = 0; 23 | 24 | }; 25 | 26 | template 27 | inline std::string CrowReturnable::dump() const 28 | { 29 | return to_string(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /deploy/kube/OdbDesignServer-SwaggerUI/service.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################################## 2 | # odbdesign-server-swaggerui service 3 | ################################################################################################## 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: odbdesign-server-swaggerui-service 8 | labels: 9 | app: odbdesign-server-swaggerui 10 | service: odbdesign-server-swaggerui 11 | spec: 12 | ports: 13 | - port: 80 14 | name: oss-svc-port 15 | targetPort: oss-dep-port 16 | selector: 17 | app: odbdesign-server-swaggerui 18 | 19 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/parse_error.cpp: -------------------------------------------------------------------------------- 1 | #include "parse_error.h" 2 | #include 3 | 4 | namespace Odb::Lib::FileModel 5 | { 6 | 7 | std::string parse_error::toString(const std::string& message) const 8 | { 9 | std::stringstream ss; 10 | ss << m_parseInfo.toString(message) << std::endl; 11 | ss << "location: " << sourceFile.filename().string() << ":" << sourceLine; 12 | return ss.str(); 13 | } 14 | 15 | const parse_info& parse_error::getParseInfo() const 16 | { 17 | return m_parseInfo; 18 | } 19 | 20 | char const* parse_error::what() const noexcept 21 | { 22 | return WHAT_STR; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/layerdirectory.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "componentsfile.proto"; 7 | import "attrlistfile.proto"; 8 | import "featuresfile.proto"; 9 | import "toolsfile.proto"; 10 | 11 | package Odb.Lib.Protobuf; 12 | 13 | // 14 | // LayerDirectory.h 15 | // 16 | 17 | message LayerDirectory { 18 | 19 | optional string name = 1; 20 | optional string path = 2; 21 | 22 | optional ComponentsFile components = 3; 23 | optional AttrListFile attrlistFile = 4; 24 | optional FeaturesFile featureFile = 5; 25 | optional ToolsFile toolFile = 6; 26 | 27 | } -------------------------------------------------------------------------------- /.github/problem-matchers/dotnet.json: -------------------------------------------------------------------------------- 1 | { 2 | "problemMatcher": [ 3 | { 4 | "owner": "dotnet-build", 5 | "pattern": [ 6 | { 7 | "regexp": "^(.+)\\((\\d+),(\\d+)\\):\\s+(error|warning|info)\\s+(\\w{1,2}\\d+):\\s*(.*)$", 8 | "file": 1, 9 | "line": 2, 10 | "column": 3, 11 | "severity": 4, 12 | "code": 5, 13 | "message": 6 14 | } 15 | ] 16 | }, 17 | { 18 | "owner": "dotnet-test", 19 | "pattern": [ 20 | { 21 | "regexp": "^\\s*Failed\\s+(.*)\\s*\\[(.*)\\]$", 22 | "message": 1, 23 | "file": 2 24 | } 25 | ] 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /scripts/deploy-monitoring.ps1: -------------------------------------------------------------------------------- 1 | kubectl create namespace monitoring 2 | 3 | helm repo add prometheus-community https://prometheus-community.github.io/helm-charts 4 | helm repo add aqua https://aquasecurity.github.io/helm-charts/ 5 | helm repo update 6 | 7 | helm upgrade --install prom prometheus-community/kube-prometheus-stack -n monitoring --values ./deploy/helm/values-prom.yaml 8 | kubectl --namespace monitoring get pods -l "release=prom" 9 | 10 | #kubectl delete -f https://raw.githubusercontent.com/aquasecurity/trivy-operator/v0.1.5/deploy/static/trivy-operator.yaml 11 | helm install trivy-operator aqua/trivy-operator --namespace trivy-system --create-namespace --version 0.11.0 --values trivy-values.yaml 12 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /OdbDesignLib/App/OdbAppBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IOdbServerApp.h" 4 | #include "DesignCache.h" 5 | #include "OdbDesignArgs.h" 6 | #include "../odbdesign_export.h" 7 | 8 | namespace Odb::Lib::App 9 | { 10 | class ODBDESIGN_EXPORT OdbAppBase : public virtual IOdbApp 11 | { 12 | public: 13 | OdbAppBase(int argc, char* argv[]); 14 | virtual ~OdbAppBase(); 15 | 16 | const OdbDesignArgs& args() const override; 17 | DesignCache& designs() override; 18 | 19 | virtual Utils::ExitCode Run() override; 20 | 21 | inline static const char* DEFAULT_DESIGNS_DIR = "designs"; 22 | 23 | protected: 24 | DesignCache m_designCache; 25 | const OdbDesignArgs m_commandLineArgs; 26 | 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /scripts/compile-protobuf.ps1: -------------------------------------------------------------------------------- 1 | $PROTOC = 'C:\Source\github\nam20485\OdbDesign\out\build\x64-debug\vcpkg_installed\x64-windows\tools\protobuf\protoc' 2 | $DLL_EXPORT = 'ODBDESIGN_EXPORT' 3 | $_GRPC_CPP_PLUGIN_EXECUTABLE = 'C:\Program Files (x86)\grpc\bin\grpc_cpp_plugin.exe' 4 | 5 | . $PROTOC --cpp_out=dllexport_decl=${DLL_EXPORT}:../Protobuf --error_format=msvs *.proto ` 6 | --grpc_out=../Protobuf --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" 7 | 8 | # COMMAND ${_PROTOBUF_PROTOC} 9 | # ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" 10 | # --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" 11 | # -I "${hw_proto_path}" 12 | # --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" 13 | # "${hw_proto}" 14 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/OdbFile.cpp: -------------------------------------------------------------------------------- 1 | #include "OdbFile.h" 2 | #include "OdbFile.h" 3 | #include "OdbFile.h" 4 | 5 | namespace Odb::Lib::FileModel 6 | { 7 | 8 | const std::filesystem::path &OdbFile::GetPath() const 9 | { 10 | return m_path; 11 | } 12 | 13 | const std::filesystem::path& OdbFile::GetDirectory() const 14 | { 15 | return m_directory; 16 | } 17 | 18 | const std::string& OdbFile::GetFilename() const 19 | { 20 | return m_filename; 21 | } 22 | 23 | bool OdbFile::Parse(std::filesystem::path path) 24 | { 25 | m_directory = path; 26 | if (!std::filesystem::exists(m_directory)) return false; 27 | 28 | return true; 29 | } 30 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/miscinfofile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package Odb.Lib.Protobuf; 4 | 5 | import "google/protobuf/timestamp.proto"; 6 | 7 | // 8 | // MiscInfoFile.h 9 | // 10 | 11 | message MiscInfoFile { 12 | 13 | optional string productModelName = 1; 14 | optional string jobName = 2; 15 | optional string odbVersionMajor = 3; 16 | optional string odbVersionMinor = 4; 17 | optional string odbSource = 5; 18 | optional google.protobuf.Timestamp creationDateDate = 6; 19 | optional google.protobuf.Timestamp saveDate = 7; 20 | optional string saveApp = 8; 21 | optional string saveUser = 9; 22 | optional string units = 10; 23 | optional uint32 maxUniqueId = 11; 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/OdbFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../odbdesign_export.h" 5 | 6 | namespace Odb::Lib::FileModel 7 | { 8 | class ODBDESIGN_EXPORT OdbFile 9 | { 10 | public: 11 | virtual ~OdbFile() = default; 12 | 13 | const std::filesystem::path& GetPath() const; 14 | const std::filesystem::path& GetDirectory() const; 15 | const std::string& GetFilename() const; 16 | 17 | virtual bool Parse(std::filesystem::path path); 18 | 19 | protected: 20 | std::filesystem::path m_path; 21 | std::filesystem::path m_directory; 22 | std::string m_filename; 23 | 24 | // abstract class 25 | OdbFile() = default; 26 | 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /OdbDesignTests/ArchiveTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Fixtures/TestDataFixture.h" 4 | #include "libarchive_extract.h" 5 | #include "ArchiveExtractor.h" 6 | #include 7 | 8 | using namespace std::filesystem; 9 | using namespace Odb::Test::Fixtures; 10 | using namespace testing; 11 | using namespace Utils; 12 | 13 | namespace Odb::Test 14 | { 15 | static inline constexpr char FILE_CONTENTS[] = "Hello, World!"; 16 | 17 | TEST_F(TestDataFixture, Test_LibArchive_CompressDir) 18 | { 19 | std::string fileArchiveOut; 20 | compress_dir(getTestDataFilesDir().string().c_str(), getTestDataDir().string().c_str(), "files_libarchive", fileArchiveOut); 21 | 22 | ASSERT_TRUE(exists(fileArchiveOut)); 23 | } 24 | } -------------------------------------------------------------------------------- /scripts/patch-vcpkg-install.ps1: -------------------------------------------------------------------------------- 1 | # 2 | # patch-vcpkg-install.ps1 3 | # 4 | 5 | # have to patch the vcpkg install by copying this file over its counterpart because the vcpkg version 6 | # included with VS has a defect in it (fixed in a preview version, but not in a released version yet) 7 | 8 | # see vcpkg GitHub issue #33506 and comment with workaround: 9 | # https://github.com/microsoft/vcpkg/issues/33506#issuecomment-1704949644 10 | 11 | $msys_path = "$env:VCPKG_ROOT\scripts\msys" 12 | If (!(Test-Path -PathType container $msys_path)) 13 | { 14 | New-Item -ItemType Directory -Path $msys_path -Verbose 15 | } 16 | 17 | Copy-Item -Force -Verbose scripts\patch\compile_wrapper_consider_clang-cl.patch "$msys_path\compile_wrapper_consider_clang-cl.patch" 18 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Part.cpp: -------------------------------------------------------------------------------- 1 | #include "Part.h" 2 | #include 3 | #include "../ProtoBuf/part.pb.h" 4 | #include 5 | 6 | namespace Odb::Lib::ProductModel 7 | { 8 | Part::Part(const std::string& name) 9 | : m_name(name) 10 | { 11 | } 12 | 13 | std::string Part::GetName() const 14 | { 15 | return m_name; 16 | } 17 | 18 | std::unique_ptr Odb::Lib::ProductModel::Part::to_protobuf() const 19 | { 20 | auto pPartMsg = std::make_unique(); 21 | pPartMsg->set_name(m_name); 22 | return pPartMsg; 23 | } 24 | 25 | void Odb::Lib::ProductModel::Part::from_protobuf(const Odb::Lib::Protobuf::ProductModel::Part& message) 26 | { 27 | m_name = message.name(); 28 | } 29 | } -------------------------------------------------------------------------------- /vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", 3 | "dependencies": [ 4 | "libarchive", 5 | "zlib", 6 | "crow", 7 | { 8 | "name": "protobuf", 9 | "features": [ 10 | "zlib" 11 | ] 12 | }, 13 | "openssl" 14 | ], 15 | "overrides": [ 16 | { 17 | "name": "protobuf", 18 | "version": "5.29.2" 19 | }, 20 | { 21 | "name": "libarchive", 22 | "version": "3.7.7" 23 | }, 24 | { 25 | "name": "openssl", 26 | "version": "3.4.1" 27 | }, 28 | { 29 | "name": "crow", 30 | "version": "1.2.1.2" 31 | }, 32 | { 33 | "name": "zlib", 34 | "version": "1.3.1" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/parse_info.cpp: -------------------------------------------------------------------------------- 1 | #include "parse_info.h" 2 | #include 3 | 4 | namespace Odb::Lib::FileModel 5 | { 6 | std::string parse_info::toString(const std::string& message /*= ""*/) const 7 | { 8 | std::stringstream ss; 9 | 10 | if (!message.empty()) 11 | { 12 | ss << message << std::endl; 13 | } 14 | 15 | if (!dataFile.empty() || !dataLine.empty() || !dataToken.empty()) 16 | { 17 | ss << "current file: [" << dataFile.relative_path().string() << ":" << dataLineNumber << "]" << std::endl 18 | << "current line: [" << dataLine << "]" << std::endl 19 | << "current token: [" << dataToken << "]"; 20 | } 21 | 22 | return ss.str(); 23 | } 24 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/RgbColor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "../../odbdesign_export.h" 5 | #include 6 | 7 | namespace Odb::Lib::FileModel::Design 8 | { 9 | /// @class struct for representing preferred layer color 10 | /// @brief each color value ranges from 0% - 100% 11 | /// noPreference is true if the Odb++ file does not specify a color 12 | struct ODBDESIGN_EXPORT RgbColor 13 | { 14 | uint8_t red; 15 | uint8_t green; 16 | uint8_t blue; 17 | 18 | bool noPreference; 19 | 20 | RgbColor(); 21 | explicit RgbColor(const std::string& str); 22 | 23 | bool from_string(const std::string& str); 24 | std::string to_string() const; 25 | }; 26 | } 27 | -------------------------------------------------------------------------------- /OdbDesignTests/Fixtures/FileArchiveLoadFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gtest/gtest.h" 4 | #include 5 | #include 6 | #include 7 | #include "TestDataFixture.h" 8 | 9 | namespace Odb::Test::Fixtures 10 | { 11 | class FileArchiveLoadFixture : public TestDataFixture 12 | { 13 | public: 14 | FileArchiveLoadFixture(); 15 | 16 | protected: 17 | std::unique_ptr m_pDesignCache; 18 | 19 | const bool m_removeDecompressedDirectories = true; 20 | 21 | void SetUp() override; 22 | void TearDown() override; 23 | 24 | std::filesystem::path getDesignPath(const std::string& filename) const; 25 | 26 | static inline const std::vector KEEP_DIRECTORIES = { TESTDATA_FILES_DIR }; 27 | 28 | }; 29 | } 30 | -------------------------------------------------------------------------------- /Those qualities are certainly beneficial.txt: -------------------------------------------------------------------------------- 1 | Those qualities are certainly beneficial. I definitely would like to offer this feature. However, I'd like to see the statically-linked version offered **in addition to, as opposed to instead of**. 2 | 3 | What I think we need here is to offer both types of build, allowing type to be selected at build-time. Then the CI pipeline can build both types and place both types of assets in the release artifacts. 4 | 5 | For integration the link type of the consuming application will dictate which version is needed to be able to accomplish 6 | 7 | ## Requirements 8 | 9 | - [ ] static and shared linkage builds 10 | - [ ] version allowed to be selected at build time 11 | - [ ] both types build in CI pipeline 12 | - [ ] both types of artifacts placed in release artifacts -------------------------------------------------------------------------------- /scripts/compress-artifacts.ps1: -------------------------------------------------------------------------------- 1 | 2 | 3 | # COPY --from=build /src/OdbDesign/out/build/linux-release/OdbDesignLib/*.so . 4 | # COPY --from=build /src/OdbDesign/out/build/linux-release/Utils/*.so . 5 | # COPY --from=build /src/OdbDesign/out/build/linux-release/OdbDesignServer/OdbDesignServer . 6 | 7 | New-Item -ItemType Directory -Force -Path ".\artifacts" -V 8 | Copy-Item -Path ".\out\build\x64-release\*.dll" -Destination ".\artifacts" -Force -V 9 | Copy-Item -Path ".\out\build\x64-release\OdbDesignServer.exe" -Destination ".\artifacts" -Force -V 10 | # COPY --from=build /src/OdbDesign/out/build/linux-release/OdbDesignLib/*.so . 11 | # COPY --from=build /src/OdbDesign/out/build/linux-release/Utils/*.so . 12 | Compress-Archive -Path ".\artifacts\*.dll",".\artifacts\*.exe" -DestinationPath ".\artifacts\artifacts.zip" -V -Force 13 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/component.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "enums.proto"; 7 | import "part.proto"; 8 | import "package.proto"; 9 | 10 | package Odb.Lib.Protobuf.ProductModel; 11 | 12 | // 13 | // Component.h 14 | // 15 | 16 | message Component { 17 | 18 | // std::string m_refDes; 19 | // std::string m_partName; 20 | // std::shared_ptr m_pPackage; 21 | // unsigned int m_index; 22 | // BoardSide m_side; 23 | // std::shared_ptr m_pPart; 24 | 25 | optional string refDes = 1; 26 | optional string partName = 2; 27 | optional Package package = 3; 28 | optional uint32 index = 4; 29 | optional BoardSide side = 5; 30 | optional Part part = 6; 31 | 32 | } -------------------------------------------------------------------------------- /OdbDesignTests/ArchiveExtractorTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Fixtures/TestDataFixture.h" 3 | #include "ArchiveExtractor.h" 4 | #include 5 | #include 6 | 7 | //using namespace Odb::Lib::App; 8 | //using namespace Odb::Lib::FileModel; 9 | using namespace Odb::Test::Fixtures; 10 | using namespace std::filesystem; 11 | using namespace Utils; 12 | 13 | namespace Odb::Test 14 | { 15 | static inline constexpr char FILE_CONTENTS[] = "Hello, World!"; 16 | 17 | TEST_F(TestDataFixture, Test_ArchiveExtractor_CompressDir) 18 | { 19 | std::string fileArchiveOut; 20 | ArchiveExtractor::CompressDir(getTestDataFilesDir().string(), getTestDataDir().string(), "files_archiveextractor", fileArchiveOut); 21 | 22 | ASSERT_STRNE(fileArchiveOut.c_str(), ""); 23 | ASSERT_TRUE(exists(fileArchiveOut)); 24 | } 25 | } -------------------------------------------------------------------------------- /Utils/FileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "utils_export.h" 4 | #include 5 | #include 6 | 7 | namespace Utils 8 | { 9 | class UTILS_EXPORT FileReader 10 | { 11 | public: 12 | enum class BufferStrategy 13 | { 14 | Unbuffered, 15 | Buffered 16 | }; 17 | 18 | FileReader(const std::filesystem::path& filePath); 19 | 20 | long long Read(BufferStrategy bufferStrategy = BufferStrategy::Buffered, std::ios::openmode mode = DEFAULT_OPENMODE); 21 | void Clear(); 22 | const std::vector& GetBuffer() const; 23 | 24 | private: 25 | const std::filesystem::path m_filePath; 26 | std::vector m_buffer; 27 | 28 | static inline constexpr std::ios::openmode DEFAULT_OPENMODE = std::ios::in|std::ios::binary; 29 | static inline constexpr size_t BUFFER_SIZE = 1024; 30 | 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/parse_info.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | namespace Odb::Lib::FileModel 7 | { 8 | struct parse_info 9 | { 10 | // data file 11 | std::filesystem::path dataFile; 12 | int dataLineNumber; 13 | std::string dataLine; 14 | std::string dataToken; 15 | 16 | parse_info(std::filesystem::path dataFile, const std::string& szDataLine, const std::string& szDataToken, int dataLineNumber) 17 | : dataFile(dataFile), dataLineNumber(dataLineNumber), dataLine(szDataLine), dataToken(szDataToken) 18 | { 19 | } 20 | 21 | parse_info(std::filesystem::path dataFile, const std::string& szDataLine, int dataLineNumber) 22 | : parse_info(dataFile, szDataLine, "", dataLineNumber) 23 | { 24 | } 25 | 26 | std::string toString(const std::string& message = "") const; 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /deploy/kube/OdbDesignServer/service.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################################## 2 | # OdbDesignServer service 3 | ################################################################################################## 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: odbdesign-server-service 8 | labels: 9 | app: odbdesign-server 10 | service: odbdesign-server 11 | spec: 12 | ## NodePort-style access 13 | # type: NodePort 14 | # ports: 15 | # - port: 80 16 | # targetPort: ods-dep-port 17 | # nodePort: 30888 18 | # name: ods-svc-port 19 | ## ClusterIP/regular ingress-style access 20 | # type: ClusterIP 21 | ports: 22 | - port: 80 23 | name: ods-svc-port 24 | targetPort: ods-dep-port 25 | selector: 26 | app: odbdesign-server 27 | 28 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/stepdirectory.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "edadatafile.proto"; 7 | import "netlistfile.proto"; 8 | import "layerdirectory.proto"; 9 | import "attrlistfile.proto"; 10 | import "featuresfile.proto"; 11 | import "stephdrfile.proto"; 12 | 13 | package Odb.Lib.Protobuf; 14 | 15 | // 16 | // StepDirectory.h 17 | // 18 | 19 | message StepDirectory { 20 | 21 | optional string name = 1; 22 | optional string path = 2; 23 | 24 | map layersByName = 3; 25 | map netlistsByName = 4; 26 | optional EdaDataFile edadatafile = 5; 27 | optional AttrListFile attrlistfile = 6; 28 | optional FeaturesFile profilefile = 7; 29 | optional StepHdrFile stephdrfile = 8; 30 | 31 | } -------------------------------------------------------------------------------- /OdbDesignTests/DesignCacheLoadTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "Fixtures/FileArchiveLoadFixture.h" 3 | #include "OdbDesign.h" 4 | 5 | //using namespace Odb::Lib::App; 6 | using namespace Odb::Lib::FileModel; 7 | using namespace Odb::Test::Fixtures; 8 | using namespace std::filesystem; 9 | 10 | namespace Odb::Test 11 | { 12 | TEST_F(FileArchiveLoadFixture, Load_Design_Succeeds_sample_design_tgz) 13 | { 14 | //ASSERT_TRUE(exists(getDesignPath("sample_design.tgz"))); 15 | auto pDesign = m_pDesignCache->GetDesign("sample_design"); 16 | ASSERT_NE(pDesign, nullptr); 17 | } 18 | 19 | TEST_F(FileArchiveLoadFixture, Load_Design_Succeeds_designodb_rigidflex_tgz) 20 | { 21 | //ASSERT_TRUE(exists(getDesignPath("designodb_rigidflex.tgz"))); 22 | auto pDesign = m_pDesignCache->GetDesign("designodb_rigidflex"); 23 | ASSERT_NE(pDesign, nullptr); 24 | } 25 | } -------------------------------------------------------------------------------- /OdbDesignLib/App/RouteController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IOdbServerApp.h" 4 | #include "../odbdesign_export.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | namespace Odb::Lib::App 11 | { 12 | class ODBDESIGN_EXPORT RouteController 13 | { 14 | public: 15 | virtual ~RouteController() = default; 16 | 17 | virtual void register_routes() = 0; 18 | 19 | typedef std::vector> Vector; 20 | 21 | protected: 22 | IOdbServerApp& m_serverApp; 23 | 24 | RouteController(IOdbServerApp& serverApp); 25 | 26 | typedef std::function TRouteHandlerFunction; 27 | 28 | void register_route_handler(std::string route, TRouteHandlerFunction handler); 29 | 30 | crow::response makeLoadedFileModelsResponse(bool) const; 31 | 32 | }; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /OdbDesignServer/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : CMake project for OdbDesignServer 2 | # 3 | 4 | add_executable(OdbDesignServer "main.cpp" "Controllers/HelloWorldController.h" "Controllers/HelloWorldController.cpp" "OdbDesignServerApp.h" "OdbDesignServerApp.cpp" "OdbDesignServer.h" "Controllers/FileUploadController.h" "Controllers/FileUploadController.cpp" "Controllers/FileModelController.h" "Controllers/FileModelController.cpp" "Controllers/HealthCheckController.h" "Controllers/HealthCheckController.cpp" "Controllers/DesignsController.h" "Controllers/DesignsController.cpp") 5 | 6 | ## PCH 7 | #if (NOT DEFINED ENV{CI}) 8 | file (GLOB_RECURSE ODBDESIGN_SERVER_HEADER_FILES "*.h") 9 | target_precompile_headers(OdbDesignServer PRIVATE ${ODBDESIGN_SERVER_HEADER_FILES}) 10 | #endif() 11 | 12 | # link to OdbDesign library 13 | target_link_libraries(OdbDesignServer PRIVATE OdbDesign) 14 | -------------------------------------------------------------------------------- /Utils/StopWatch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | #include 6 | 7 | namespace Utils 8 | { 9 | class UTILS_EXPORT StopWatch 10 | { 11 | public: 12 | StopWatch(bool start); 13 | 14 | void start(); 15 | void stop(); 16 | 17 | std::chrono::system_clock::duration getElapsedDuration() const; 18 | 19 | long long getElapsedMilliseconds() const; 20 | double getElapsedSeconds() const; 21 | 22 | std::string getElapsedSecondsString(const std::string& suffix = "") const; 23 | 24 | //template 25 | //std::chrono::system_clock::duration getElapsedDuration() const; 26 | 27 | constexpr inline static const double MS_PER_SECOND = 1000.0; 28 | 29 | private: 30 | std::chrono::system_clock::time_point m_started; 31 | std::chrono::system_clock::time_point m_finished; 32 | 33 | bool m_stopped; 34 | 35 | }; 36 | } -------------------------------------------------------------------------------- /OdbDesignLib/App/BasicRequestAuthentication.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "RequestAuthenticationBase.h" 4 | #include "../odbdesign_export.h" 5 | 6 | namespace Odb::Lib::App 7 | { 8 | class ODBDESIGN_EXPORT BasicRequestAuthentication : public RequestAuthenticationBase 9 | { 10 | public: 11 | BasicRequestAuthentication(bool disableAuthentication); 12 | 13 | // Inherited via RequestAuthenticationBase 14 | crow::response AuthenticateRequest(const crow::request& req) override; 15 | 16 | private: 17 | 18 | const inline static char AUTHORIZATION_HEADER_NAME[] = "Authorization"; 19 | 20 | crow::response VerifyCredentials(const std::string& username, const std::string& password); 21 | 22 | const inline static char USERNAME_ENV_NAME[] = "ODBDESIGN_SERVER_REQUEST_USERNAME"; 23 | const inline static char PASSWORD_ENV_NAME[] = "ODBDESIGN_SERVER_REQUEST_PASSWORD"; 24 | 25 | 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/filearchive.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "stepdirectory.proto"; 7 | import "miscinfofile.proto"; 8 | import "matrixfile.proto"; 9 | import "standardfontsfile.proto"; 10 | import "symbolsdirectory.proto"; 11 | import "attrlistfile.proto"; 12 | 13 | package Odb.Lib.Protobuf; 14 | 15 | // 16 | // FileArchive.h 17 | // 18 | 19 | message FileArchive { 20 | 21 | map stepsByName = 1; 22 | optional MiscInfoFile miscInfoFile = 2; 23 | optional MatrixFile matrixFile = 3; 24 | optional StandardFontsFile standardFontsFile = 4; 25 | map symbolsDirectoriesByName = 5; 26 | optional AttrListFile miscAttrListFile = 6; 27 | optional string productName = 7; 28 | optional string fileName = 8; 29 | 30 | } -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/HelloWorldController.cpp: -------------------------------------------------------------------------------- 1 | #include "HelloWorldController.h" 2 | #include "../OdbDesignServerApp.h" 3 | 4 | using namespace Odb::Lib::App; 5 | 6 | namespace Odb::App::Server 7 | { 8 | HelloWorldController::HelloWorldController(IOdbServerApp& serverApp) 9 | : RouteController(serverApp) 10 | { 11 | } 12 | 13 | void HelloWorldController::register_routes() 14 | { 15 | // /helloworld 16 | CROW_ROUTE(m_serverApp.crow_app(), "/helloworld")([]() { 17 | //return "Hello world"; 18 | auto page = crow::mustache::load_text("helloworld.html"); 19 | return page; 20 | }); 21 | 22 | // /hellodesign/ 23 | CROW_ROUTE(m_serverApp.crow_app(), "/hellodesign/")([](std::string designName) { 24 | auto page = crow::mustache::load("helloworld.html"); 25 | crow::mustache::context ctx({ {"design", designName} }); 26 | return page.render(ctx); 27 | }); 28 | } 29 | } -------------------------------------------------------------------------------- /OdbDesignLib/App/RequestAuthenticationBase.cpp: -------------------------------------------------------------------------------- 1 | #include "RequestAuthenticationBase.h" 2 | #include "macros.h" 3 | 4 | using namespace Utils; 5 | 6 | namespace Odb::Lib::App 7 | { 8 | RequestAuthenticationBase::RequestAuthenticationBase(bool disableAuthentication) 9 | : m_disableAuthentication(disableAuthentication) 10 | { 11 | } 12 | 13 | crow::response RequestAuthenticationBase::AuthenticateRequest(const crow::request& req) 14 | { 15 | // if running debug build AND in Local environment, bypass authentication 16 | if (IsDebug() && IsLocal()) 17 | { 18 | // 200 Authorized! 19 | return crow::response(crow::status::OK, "Authorized"); 20 | } 21 | else if (m_disableAuthentication) 22 | { 23 | // 200 Authorized! 24 | return crow::response(crow::status::OK, "Authorized"); 25 | } 26 | else 27 | { 28 | return crow::response(crow::status::UNAUTHORIZED, "Unauthorized"); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Part.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../ProtoBuf/part.pb.h" 9 | #include "../IProtoBuffable.h" 10 | 11 | namespace Odb::Lib::ProductModel 12 | { 13 | class ODBDESIGN_EXPORT Part : public IProtoBuffable 14 | { 15 | public: 16 | Part(const std::string& name); 17 | 18 | std::string GetName() const; 19 | 20 | typedef std::vector> Vector; 21 | typedef std::map> StringMap; 22 | 23 | // Inherited via IProtoBuffable 24 | std::unique_ptr to_protobuf() const override; 25 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Part& message) override; 26 | 27 | private: 28 | std::string m_name; 29 | 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /deploy/kube/local-ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: odbdesign-server-ingress 5 | # annotations: 6 | # cert-manager.io/issuer: "letsencrypt-staging" 7 | spec: 8 | ingressClassName: traefik 9 | rules: 10 | - host: precision5820 11 | http: 12 | paths: 13 | - path: "/" 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: odbdesign-server-service 18 | port: 19 | name: ods-svc-port 20 | - path: /swagger 21 | pathType: Prefix 22 | backend: 23 | service: 24 | name: odbdesign-server-swaggerui-service 25 | port: 26 | name: oss-svc-port 27 | # tls: 28 | # - hosts: 29 | # - precision5820 # your domain 30 | # secretName: letsencrypt-staging-tls 31 | -------------------------------------------------------------------------------- /scripts/common-auth.ps1: -------------------------------------------------------------------------------- 1 | # Common authentication helpers for GitHub CLI 2 | # Dot-source this file from scripts that need to ensure authentication. 3 | 4 | Set-StrictMode -Version Latest 5 | $ErrorActionPreference = 'Stop' 6 | 7 | function Initialize-GitHubAuth { 8 | [CmdletBinding()] 9 | param( 10 | [switch]$DryRun 11 | ) 12 | # Verify gh is available 13 | if (-not (Get-Command gh -ErrorAction SilentlyContinue)) { 14 | throw 'Required tool not found on PATH: gh' 15 | } 16 | # Check auth status; if not authenticated, initiate login so user can complete prompts 17 | & gh auth status 2>$null | Out-Null 18 | $code = $LASTEXITCODE 19 | if ($code -ne 0) { 20 | Write-Warning 'GitHub CLI not authenticated. Initiating gh auth login so the user can complete prompts...' 21 | if ($DryRun) { 22 | Write-Host '[dry-run] Would run: gh auth login' -ForegroundColor Yellow 23 | } else { 24 | & gh auth login | Out-Null 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Pin.cpp: -------------------------------------------------------------------------------- 1 | #include "Pin.h" 2 | #include 3 | #include 4 | #include "../ProtoBuf/pin.pb.h" 5 | 6 | namespace Odb::Lib::ProductModel 7 | { 8 | Pin::Pin(const std::string& name, unsigned int index) 9 | : m_name(name) 10 | , m_index(index) 11 | { 12 | } 13 | 14 | std::string Pin::GetName() const 15 | { 16 | return m_name; 17 | } 18 | 19 | unsigned int Pin::GetIndex() const 20 | { 21 | return m_index; 22 | } 23 | 24 | std::unique_ptr Odb::Lib::ProductModel::Pin::to_protobuf() const 25 | { 26 | auto pPinMessage = std::make_unique(); 27 | pPinMessage->set_name(m_name); 28 | pPinMessage->set_index(m_index); 29 | return pPinMessage; 30 | } 31 | 32 | void Pin::from_protobuf(const Odb::Lib::Protobuf::ProductModel::Pin& message) 33 | { 34 | m_name = message.name(); 35 | m_index = message.index(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /compose.yml: -------------------------------------------------------------------------------- 1 | name: odbdesign 2 | 3 | services: 4 | 5 | ### use remote image build from github container registry 6 | server: 7 | image: ghcr.io/nam20485/odbdesign:nam20485-latest 8 | volumes: 9 | - ./compose-designs:/OdbDesign/designs 10 | ports: 11 | - 8888:8888 12 | environment: 13 | - ODBDESIGN_SERVER_REQUEST_USERNAME 14 | - ODBDESIGN_SERVER_REQUEST_PASSWORD 15 | 16 | ### use local image built from Dockerfile 17 | # server: 18 | # build: 19 | # context: . 20 | # dockerfile: Dockerfile 21 | # volumes: 22 | # - ./compose-designs:/OdbDesign/designs 23 | # ports: 24 | # - 8888:8888 25 | # environment: 26 | # - ODBDESIGN_SERVER_REQUEST_USERNAME 27 | # - ODBDESIGN_SERVER_REQUEST_PASSWORD 28 | 29 | swagger-ui: 30 | image: ghcr.io/nam20485/odbdesignserver-swaggerui:nam20485-latest 31 | depends_on: 32 | - server 33 | ports: 34 | - 8080:8080 35 | -------------------------------------------------------------------------------- /deploy/kube/default-ingress (eks).yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: default-ingress 5 | namespace: default 6 | annotations: 7 | alb.ingress.kubernetes.io/load-balancer-name: default-ingress 8 | alb.ingress.kubernetes.io/target-type: ip 9 | alb.ingress.kubernetes.io/scheme: internet-facing 10 | alb.ingress.kubernetes.io/healthcheck-path: /healthz/live 11 | spec: 12 | ingressClassName: alb 13 | rules: 14 | - http: 15 | paths: 16 | - path: / 17 | pathType: Prefix 18 | backend: 19 | service: 20 | name: odbdesign-server-service 21 | port: 22 | name: ods-svc-port 23 | - path: /swagger 24 | pathType: Prefix 25 | backend: 26 | service: 27 | name: odbdesign-server-swaggerui-service 28 | port: 29 | name: oss-svc-port -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # This .gitignore file was automatically created by Microsoft(R) Visual Studio. 3 | ################################################################################ 4 | 5 | /.vs 6 | /out 7 | /cmake-build-debug 8 | build/ 9 | /vcpkg_installed 10 | /OdbDesignServer/designs/ 11 | /cmake-build-debug-visual-studio 12 | /.idea/workspace.xml 13 | ssl/ 14 | artifacts/ 15 | /TEST_DATA 16 | OdbDesignTests/Testing/ 17 | Testing/ 18 | testlog.txt 19 | testlog.txt.tmp* 20 | testlog.xml 21 | /OdbDesignTests/FileArchiveLoadTests_Local.cpp 22 | /OdbDesignTests/CMakeLists_Local.txt 23 | /OdbDesignTests/DesignNameTests_Local.cpp 24 | /output 25 | /TEST_DATA.zip 26 | deploy/kubeconfig 27 | Dockerfile.commentedOut 28 | scripts/create-release-invoker.js 29 | /compose-designs 30 | docs/api/ 31 | perfertto-tracing-span-events-SQL.md 32 | # Corrected spelling to ensure both variants are ignored 33 | perfetto-tracing-span-events-SQL.md 34 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Via.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../enums.h" 9 | #include "../ProtoBuf/via.pb.h" 10 | #include "../IProtoBuffable.h" 11 | 12 | 13 | namespace Odb::Lib::ProductModel 14 | { 15 | class ODBDESIGN_EXPORT Via : public IProtoBuffable 16 | { 17 | public: 18 | Via(); 19 | 20 | std::string GetName() const; 21 | BoardSide GetSide() const; 22 | 23 | // Inherited via IProtoBuffable 24 | std::unique_ptr to_protobuf() const override; 25 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Via& message) override; 26 | 27 | typedef std::vector> Vector; 28 | typedef std::map> StringMap; 29 | 30 | private: 31 | std::string m_name; 32 | BoardSide m_side; 33 | 34 | }; 35 | } // namespace Odb::Lib::ProductModel 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/PropertyRecord.cpp: -------------------------------------------------------------------------------- 1 | #include "PropertyRecord.h" 2 | 3 | namespace Odb::Lib::FileModel::Design 4 | { 5 | // Inherited via IProtoBuffable 6 | std::unique_ptr 7 | PropertyRecord::to_protobuf() const 8 | { 9 | std::unique_ptr pPropertyRecordMessage(new Odb::Lib::Protobuf::PropertyRecord); 10 | pPropertyRecordMessage->set_name(name); 11 | pPropertyRecordMessage->set_value(value); 12 | for (const auto& f : floatValues) 13 | { 14 | pPropertyRecordMessage->add_floatvalues(f); 15 | } 16 | return pPropertyRecordMessage; 17 | } 18 | 19 | void PropertyRecord::from_protobuf(const Odb::Lib::Protobuf::PropertyRecord& message) 20 | { 21 | name = message.name(); 22 | value = message.value(); 23 | for (int i = 0; i < message.floatvalues_size(); ++i) 24 | { 25 | floatValues.push_back(message.floatvalues(i)); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/toolsfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package Odb.Lib.Protobuf; 4 | 5 | // 6 | // ToolsFile.h 7 | // 8 | 9 | message ToolsFile { 10 | 11 | message ToolsRecord { 12 | 13 | enum Type { 14 | Plated = 0; 15 | NonPlated = 1; 16 | Via = 2; 17 | } 18 | 19 | enum Type2 { 20 | Standard = 0; 21 | PressFit = 1; 22 | Photo = 2; 23 | Laser = 3; 24 | } 25 | 26 | uint32 tool_num = 1; 27 | Type type = 2; 28 | Type2 type2 = 3; 29 | double min_tol = 4; 30 | double max_tol = 5; 31 | string drill_bit = 6; 32 | double finish_size = 7; 33 | double drill_size = 8; 34 | 35 | } 36 | 37 | string directory = 1; 38 | string path = 2; 39 | string units = 3; 40 | double thickness = 4; 41 | string user_params = 5; 42 | 43 | map tools = 6; 44 | } -------------------------------------------------------------------------------- /Utils/JsonCrowReturnable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IJsonable.h" 4 | #include "CrowReturnable.h" 5 | #include 6 | 7 | namespace Utils 8 | { 9 | template 10 | class JsonCrowReturnable : public Utils::CrowReturnable 11 | { 12 | public: 13 | JsonCrowReturnable(const TJsonable& odbObject) 14 | : Utils::CrowReturnable(odbObject, CONTENT_TYPE) 15 | {} 16 | 17 | inline constexpr static const char* CONTENT_TYPE = "application/json"; 18 | 19 | protected: 20 | std::string to_string() const override; 21 | 22 | // TJsonable MUST derive from IJsonConvertable (must use this until template type contraints support is added) 23 | static_assert(std::is_base_of::value, "template parameter type TJsonable must derive from IJsonConvertable interface class"); 24 | 25 | }; 26 | 27 | template 28 | inline std::string JsonCrowReturnable::to_string() const 29 | { 30 | return this->m_t.to_json(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/PropertyRecord.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../../odbdesign_export.h" 8 | #include "../../IProtoBuffable.h" 9 | #include "../../ProtoBuf/common.pb.h" 10 | 11 | namespace Odb::Lib::FileModel::Design 12 | { 13 | struct ODBDESIGN_EXPORT PropertyRecord : public IProtoBuffable 14 | { 15 | // data members 16 | std::string name; 17 | std::string value; 18 | std::vector floatValues; 19 | 20 | // constants 21 | constexpr inline static const char* RECORD_TOKEN = "PRP"; 22 | 23 | // typedefs 24 | typedef std::map> StringMap; 25 | typedef std::vector> Vector; 26 | 27 | // Inherited via IProtoBuffable 28 | std::unique_ptr to_protobuf() const override; 29 | void from_protobuf(const Odb::Lib::Protobuf::PropertyRecord& message) override; 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/standardfontsfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "enums.proto"; 7 | 8 | package Odb.Lib.Protobuf; 9 | 10 | // 11 | // StandardFontsFile.h 12 | // 13 | 14 | message StandardFontsFile { 15 | 16 | message CharacterBlock { 17 | 18 | message LineRecord { 19 | 20 | optional double xStart = 1; 21 | optional double yStart = 2; 22 | optional double xEnd = 3; 23 | optional double yEnd = 4; 24 | optional Polarity polarity = 5; 25 | optional LineShape shape = 6; 26 | optional double width = 7; 27 | } 28 | 29 | optional string character = 1; 30 | repeated LineRecord m_lineRecords = 2; 31 | } 32 | 33 | optional double xSize = 1; 34 | optional double ySize = 2; 35 | optional double offset = 3; 36 | 37 | repeated CharacterBlock m_characterBlocks = 4; 38 | 39 | } -------------------------------------------------------------------------------- /scripts/patch/mingw-w64-x86_64.cmake: -------------------------------------------------------------------------------- 1 | # Sample toolchain file for building for Windows from an Ubuntu Linux system. 2 | # 3 | # Typical usage: 4 | # *) install cross compiler: `sudo apt-get install mingw-w64` 5 | # *) cd build 6 | # *) cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake .. 7 | # This is free and unencumbered software released into the public domain. 8 | 9 | set(CMAKE_SYSTEM_NAME Windows) 10 | set(TOOLCHAIN_PREFIX x86_64-w64-mingw32) 11 | 12 | # cross compilers to use for C, C++ and Fortran 13 | set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc) 14 | set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++) 15 | set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran) 16 | set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres) 17 | 18 | # target environment on the build host system 19 | set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX}) 20 | 21 | # modify default behavior of FIND_XXX() commands 22 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 23 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Pin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../ProtoBuf/pin.pb.h" 9 | #include "../IProtoBuffable.h" 10 | 11 | 12 | namespace Odb::Lib::ProductModel 13 | { 14 | class ODBDESIGN_EXPORT Pin : public IProtoBuffable 15 | { 16 | public: 17 | Pin(const std::string& name, unsigned int index); 18 | //~Pin(); 19 | 20 | std::string GetName() const; 21 | unsigned int GetIndex() const; 22 | 23 | typedef std::vector> Vector; 24 | typedef std::map> StringMap; 25 | 26 | // Inherited via IProtoBuffable 27 | std::unique_ptr to_protobuf() const override; 28 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Pin& message) override; 29 | 30 | private: 31 | std::string m_name; 32 | unsigned int m_index; 33 | 34 | }; 35 | } // namespace Odb::Lib::ProductModel 36 | -------------------------------------------------------------------------------- /.vscode/codeql-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OdbDesign CodeQL Configuration", 3 | "database": { 4 | "languages": ["cpp"], 5 | "sourceRoot": ".", 6 | "buildCommand": "cmake --preset linux-release && cmake --build --preset linux-release" 7 | }, 8 | "queries": { 9 | "suites": [ 10 | ".github/codeql/cpp-queries/odbdesign-suite.qls", 11 | "codeql/cpp-queries:Security", 12 | "codeql/cpp-queries:Correctness" 13 | ] 14 | }, 15 | "analysis": { 16 | "threads": 0, 17 | "timeout": 0, 18 | "trapCaching": true, 19 | "trapCachingDir": ".codeql-trap-cache" 20 | }, 21 | "paths": { 22 | "include": [ 23 | "OdbDesignServer/**", 24 | "OdbDesignApp/**", 25 | "OdbDesignLib/**", 26 | "Utils/**" 27 | ], 28 | "exclude": [ 29 | "vcpkg/**", 30 | "vcpkg_installed/**", 31 | "out/**", 32 | "build/**", 33 | "**/CMakeFiles/**", 34 | "**/_deps/**", 35 | "**/*.pb.h", 36 | "**/*.pb.cc", 37 | "**/protoc/**" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Via.cpp: -------------------------------------------------------------------------------- 1 | #include "Via.h" 2 | #include 3 | #include "../ProtoBuf/via.pb.h" 4 | #include "../ProtoBuf/enums.pb.h" 5 | #include "../enums.h" 6 | #include 7 | 8 | 9 | namespace Odb::Lib::ProductModel 10 | { 11 | Via::Via() 12 | : m_name("") 13 | , m_side(BoardSide::Top) 14 | { 15 | } 16 | 17 | std::string Via::GetName() const 18 | { 19 | return m_name; 20 | } 21 | 22 | BoardSide Via::GetSide() const 23 | { 24 | return m_side; 25 | } 26 | 27 | std::unique_ptr Via::to_protobuf() const 28 | { 29 | auto pViaMsg = std::make_unique(); 30 | pViaMsg->set_name(m_name); 31 | pViaMsg->set_boardside(static_cast(m_side)); 32 | return pViaMsg; 33 | } 34 | 35 | void Via::from_protobuf(const Odb::Lib::Protobuf::ProductModel::Via& message) 36 | { 37 | m_name = message.name(); 38 | m_side = static_cast(message.boardside()); 39 | } 40 | 41 | } // namespace Odb::Lib::ProductModel 42 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/common.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | message PropertyRecord { 9 | 10 | optional string name = 1; 11 | optional string value = 2; 12 | repeated double floatValues = 3; 13 | } 14 | 15 | message ContourPolygon { 16 | 17 | message PolygonPart { 18 | 19 | enum Type 20 | { 21 | Segment = 0; 22 | Arc = 1; 23 | }; 24 | 25 | optional Type type = 1; 26 | optional double endX = 2; 27 | optional double endY = 3; 28 | optional double xCenter = 4; 29 | optional double yCenter = 5; 30 | optional bool isClockwise = 6; 31 | 32 | } 33 | 34 | enum Type 35 | { 36 | Island = 0; 37 | Hole = 1; 38 | }; 39 | 40 | optional Type type = 1; 41 | optional double xStart = 2; 42 | optional double yStart = 3; 43 | 44 | repeated PolygonPart polygonParts = 4; 45 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/copilot-task.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Copilot Task 3 | about: Create a new task for GitHub Copilot to implement 4 | title: "[TASK] " 5 | labels: ["copilot-task", "enhancement"] 6 | assignees: [] 7 | --- 8 | 9 | # Task Description 10 | Brief description of what needs to be accomplished. 11 | 12 | ## Implementation Plan 13 | - [ ] Step 1: Description of first step 14 | - [ ] Step 2: Description of second step 15 | - [ ] Step 3: Description of third step 16 | - [ ] Step 4: Additional steps as needed 17 | 18 | ## Acceptance Criteria 19 | - [ ] Criterion 1: Specific requirement that must be met 20 | - [ ] Criterion 2: Another specific requirement 21 | - [ ] Criterion 3: Additional criteria as needed 22 | 23 | ## Testing Plan 24 | Describe how the implementation will be tested and validated. 25 | 26 | ## Implementation Notes 27 | Space for additional technical details, constraints, or considerations. 28 | 29 | ## Related Issues/PRs 30 | Links to related issues or pull requests (if any). 31 | 32 | --- 33 | **Note**: This issue will be implemented by GitHub Copilot following the task-based workflow process. 34 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the 2 | // README at: https://github.com/devcontainers/templates/tree/main/src/dotnet 3 | { 4 | "name": "odbdesign-devcontainer", 5 | // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile 6 | "image": "ghcr.io/nam20485/cpp-prebuild", 7 | 8 | // Features to add to the dev container. More info: https://containers.dev/features. 9 | // "features": {}, 10 | 11 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 12 | // "forwardPorts": [5000, 5001], 13 | // "portsAttributes": { 14 | // "5001": { 15 | // "protocol": "https" 16 | // } 17 | // } 18 | 19 | // Use 'postCreateCommand' to run commands after the container is created. 20 | // "postCreateCommand": "dotnet restore", 21 | 22 | // Configure tool-specific properties. 23 | // "customizations": {}, 24 | 25 | // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. 26 | "remoteUser": "root", 27 | "customizations": { 28 | "vscode": { 29 | "extensions": [ 30 | ] 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/SymbolName.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../../enums.h" 8 | #include "../../odbdesign_export.h" 9 | #include "../parse_error.h" 10 | #include "../../IProtoBuffable.h" 11 | #include "../../ProtoBuf/symbolname.pb.h" 12 | 13 | // TODO: add SymbolName serialization 14 | 15 | namespace Odb::Lib::FileModel::Design 16 | { 17 | class ODBDESIGN_EXPORT SymbolName : public IProtoBuffable 18 | { 19 | public: 20 | SymbolName(); 21 | 22 | std::string GetName() const; 23 | UnitType GetUnitType() const; 24 | 25 | bool Parse(const std::filesystem::path& path, const std::string& line, int lineNumber); 26 | 27 | // Inherited via IProtoBuffable 28 | std::unique_ptr to_protobuf() const override; 29 | void from_protobuf(const Odb::Lib::Protobuf::SymbolName& message) override; 30 | 31 | typedef std::vector> Vector; 32 | typedef std::map> StringMap; 33 | 34 | private: 35 | std::string m_name; 36 | UnitType m_unitType; 37 | 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /.github/codeql/cpp-queries/odbdesign-suite.qls: -------------------------------------------------------------------------------- 1 | description: OdbDesign Custom Security Analysis Query Suite 2 | queries: 3 | - query: ./odbdesign-security.ql 4 | - query: ./http-response-splitting.ql 5 | - query: codeql/cpp-queries:Security/CWE/CWE-078/CommandInjection.ql 6 | - query: codeql/cpp-queries:Security/CWE/CWE-079/CrossSiteScripting.ql 7 | - query: codeql/cpp-queries:Security/CWE/CWE-089/SqlInjection.ql 8 | - query: codeql/cpp-queries:Security/CWE/CWE-120/BufferWrite.ql 9 | - query: codeql/cpp-queries:Security/CWE/CWE-121/StackBufferOverflow.ql 10 | - query: codeql/cpp-queries:Security/CWE/CWE-190/IntegerOverflow.ql 11 | - query: codeql/cpp-queries:Security/CWE/CWE-416/UseAfterFree.ql 12 | - query: codeql/cpp-queries:Security/CWE/CWE-457/UseOfUninitializedVariable.ql 13 | - query: codeql/cpp-queries:Security/CWE/CWE-476/NullPointerDereference.ql 14 | - query: codeql/cpp-queries:Security/CWE/CWE-676/DangerousUncontrolledCode.ql 15 | - query: codeql/cpp-queries:Correctness/Memory/UninitializedLocal.ql 16 | - query: codeql/cpp-queries:Correctness/Memory/ReturnStackAllocatedMemory.ql 17 | - query: codeql/cpp-queries:Best Practices/Likely Errors/OffsetUseBeforeRangeCheck.ql 18 | -------------------------------------------------------------------------------- /.github/.branch-protection-ruleset_protected branches.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 7521867, 3 | "name": "protected branches", 4 | "target": "branch", 5 | "source_type": "Repository", 6 | "source": "nam20485/support-assistant2", 7 | "enforcement": "active", 8 | "conditions": { 9 | "ref_name": { 10 | "exclude": [], 11 | "include": [ 12 | "refs/heads/main", 13 | "refs/heads/development" 14 | ] 15 | } 16 | }, 17 | "rules": [ 18 | { 19 | "type": "deletion" 20 | }, 21 | { 22 | "type": "non_fast_forward" 23 | }, 24 | { 25 | "type": "creation" 26 | }, 27 | { 28 | "type": "required_signatures" 29 | }, 30 | { 31 | "type": "pull_request", 32 | "parameters": { 33 | "required_approving_review_count": 1, 34 | "dismiss_stale_reviews_on_push": false, 35 | "require_code_owner_review": false, 36 | "require_last_push_approval": false, 37 | "required_review_thread_resolution": true, 38 | "automatic_copilot_code_review_enabled": false, 39 | "allowed_merge_methods": [ 40 | "merge" 41 | ] 42 | } 43 | } 44 | ], 45 | "bypass_actors": [] 46 | } 47 | -------------------------------------------------------------------------------- /.github/workflows/sbom-generate-submit.yml: -------------------------------------------------------------------------------- 1 | name: SBOM Generate and Submit 2 | 3 | on: 4 | push: 5 | branches: [ "main", "release", "development", "staging", "nam20485" ] 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | build: 13 | name: Generate-Submit-SBOM 14 | runs-on: ubuntu-22.04 15 | permissions: 16 | id-token: write 17 | contents: write 18 | 19 | steps: 20 | - name: Harden Runner 21 | uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 22 | with: 23 | egress-policy: audit 24 | 25 | - name: Checkout Code 26 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 27 | 28 | - name: SBOM Generate 29 | uses: advanced-security/sbom-generator-action@6fe43abf522b2e7a19bc769aec1e6c848614b517 # v0.0.2 30 | id: sbom-generate 31 | env: 32 | GITHUB_TOKEN: ${{ github.token }} 33 | 34 | - name: SBOM Upload 35 | uses: advanced-security/spdx-dependency-submission-action@dc069b56ba31ce546dc419b549aceb808c632d9a # v0.0.1 36 | with: 37 | filePath: ${{ steps.sbom-generate.outputs.fileName }} 38 | -------------------------------------------------------------------------------- /Utils/fastmove.cpp: -------------------------------------------------------------------------------- 1 | #include "fastmove.h" 2 | #include 3 | 4 | using namespace std; 5 | using namespace std::filesystem; 6 | 7 | namespace Utils 8 | { 9 | void move_file(const path& source, const path& dest, bool overwriteExisting, std::error_code& ec) 10 | { 11 | auto options = copy_options::none; 12 | if (overwriteExisting) 13 | { 14 | options |= copy_options::overwrite_existing; 15 | } 16 | 17 | if (copy_file(source, dest, options, ec) && 18 | ec.value() == 0) 19 | { 20 | remove(source, ec); 21 | } 22 | } 23 | 24 | void fastmove_file(const path& source, const path& dest, bool overwriteExisting, std::error_code& ec) 25 | { 26 | //try 27 | { 28 | rename(source, dest, ec); 29 | if (ec.value() == static_cast(std::errc::cross_device_link)) 30 | { 31 | move_file(source, dest, overwriteExisting, ec); 32 | } 33 | } 34 | //catch (filesystem_error& fe) 35 | //{ 36 | // // can't rename across devices- try standard copy and remove 37 | // if (fe.code() == std::errc::cross_device_link) 38 | // { 39 | // ec = move_file(source, dest, overwriteExisting); 40 | // } 41 | // else 42 | // { 43 | // throw fe; 44 | // } 45 | //} 46 | 47 | //return ec; 48 | } 49 | } -------------------------------------------------------------------------------- /deploy/kube/OdbDesignServer-SwaggerUI/deployment.yaml: -------------------------------------------------------------------------------- 1 | ################################################################################################## 2 | # odbdesign-server-swaggerui deployment 3 | ################################################################################################## 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: odbdesign-server-swaggerui-v1 8 | labels: 9 | app: odbdesign-server-swaggerui 10 | version: v1 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | app: odbdesign-server-swaggerui 16 | version: v1 17 | template: 18 | metadata: 19 | labels: 20 | app: odbdesign-server-swaggerui 21 | version: v1 22 | spec: 23 | containers: 24 | - name: odbdesign-server-swaggerui 25 | image: ghcr.io/nam20485/odbdesignserver-swaggerui:nam20485-latest 26 | imagePullPolicy: Always 27 | ports: 28 | - containerPort: 8080 29 | name: oss-dep-port 30 | resources: 31 | limits: 32 | cpu: "8" 33 | memory: 10Gi 34 | requests: 35 | cpu: "2" 36 | memory: 2Gi 37 | 38 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Net.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "PinConnection.h" 9 | #include "Component.h" 10 | #include "Pin.h" 11 | #include "../ProtoBuf/net.pb.h" 12 | #include "../IProtoBuffable.h" 13 | 14 | 15 | namespace Odb::Lib::ProductModel 16 | { 17 | class ODBDESIGN_EXPORT Net : public IProtoBuffable 18 | { 19 | public: 20 | Net(const std::string& name, unsigned int index); 21 | ~Net(); 22 | 23 | std::string GetName() const; 24 | PinConnection::Vector& GetPinConnections(); 25 | unsigned int GetIndex() const; 26 | bool AddPinConnection(std::shared_ptr pComponent, std::shared_ptr pPin); 27 | 28 | // Inherited via IProtoBuffable 29 | std::unique_ptr to_protobuf() const override; 30 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Net& message) override; 31 | 32 | typedef std::vector> Vector; 33 | typedef std::map> StringMap; 34 | 35 | private: 36 | std::string m_name; 37 | PinConnection::Vector m_pinConnections; 38 | unsigned int m_index; 39 | 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /OdbDesignTests/Fixtures/TestDataFixture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "gtest/gtest.h" 4 | #include 5 | #include 6 | 7 | namespace Odb::Test::Fixtures 8 | { 9 | class TestDataFixture : public testing::Test 10 | { 11 | public: 12 | TestDataFixture(); 13 | 14 | protected: 15 | virtual void SetUp() override; 16 | virtual void TearDown() override; 17 | 18 | static std::filesystem::path getTestDataDir(); 19 | std::filesystem::path getTestDataFilesDir() const; 20 | std::filesystem::path getTestDataFilePath(const std::string& filename) const; 21 | 22 | static inline constexpr const char ODB_TEST_DATA_DIR_ENV_NAME[] = "ODB_TEST_DATA_DIR"; 23 | static inline constexpr const char ODB_TEST_ENV_NAME[] = "ODB_TEST_ENVIRONMENT_VARIABLE"; 24 | static inline constexpr const char ODB_TEST_ENV_VALUE[] = "ODB_TEST_ENVIRONMENT_VARIABLE_EXISTS"; 25 | static inline constexpr const char ODB_TEST_NONEXISTENT_ENV_NAME[] = "THIS_ENVIRONEMNT_VARIABLE_DOES_NOT_EXIST"; 26 | static inline constexpr const char TESTDATA_FILES_DIR[] = "FILES"; 27 | 28 | 29 | static inline constexpr bool ENABLE_TEST_LOGGING = false; 30 | 31 | private: 32 | std::filesystem::path m_testDataDir; 33 | 34 | const bool m_removeDecompressedDirectories = true; 35 | 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /.github/codeql-config.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL Security Analysis Configuration" 2 | 3 | # Configure what CodeQL should analyze 4 | paths: 5 | - "OdbDesignServer/**" 6 | - "OdbDesignApp/**" 7 | - "OdbDesignLib/**" 8 | - "Utils/**" 9 | 10 | # Exclude generated code, dependencies, and build artifacts 11 | paths-ignore: 12 | - "vcpkg/**" 13 | - "vcpkg_installed/**" 14 | - "out/**" 15 | - "build/**" 16 | - "**/CMakeFiles/**" 17 | - "**/_deps/**" 18 | - "OdbDesignLib/ProtoBuf/Odb/**.pb.h" 19 | - "OdbDesignLib/ProtoBuf/Odb/**.pb.cc" 20 | - "**/*.proto" 21 | - "**/protoc/**" 22 | 23 | # Enable comprehensive security analysis 24 | queries: 25 | - uses: security-and-quality 26 | - uses: security-extended 27 | - uses: security-experimental 28 | - uses: .github/codeql/cpp-queries/odbdesign-suite.qls 29 | 30 | # Disable problematic queries that may cause false positives 31 | disable-default-queries: false 32 | query-filters: 33 | - exclude: 34 | id: "cpp/uncontrolled-format-string" 35 | - exclude: 36 | id: "cpp/poorly-documented-function" 37 | - exclude: 38 | id: "cpp/use-of-goto" 39 | 40 | # Configure C++ specific analysis 41 | query-suites: 42 | - codeql/cpp-queries:Security/CWE 43 | - codeql/cpp-queries:Correctness 44 | - codeql/cpp-queries:Performance -------------------------------------------------------------------------------- /Utils/StopWatch.cpp: -------------------------------------------------------------------------------- 1 | #include "StopWatch.h" 2 | #include 3 | #include 4 | 5 | using namespace std::chrono; 6 | 7 | namespace Utils 8 | { 9 | StopWatch::StopWatch(bool start) 10 | : m_stopped(false) 11 | { 12 | if (start) 13 | { 14 | this->start(); 15 | } 16 | } 17 | 18 | void StopWatch::start() 19 | { 20 | m_stopped = false; 21 | m_started = system_clock::now(); 22 | } 23 | 24 | void StopWatch::stop() 25 | { 26 | m_finished = system_clock::now(); 27 | m_stopped = true; 28 | } 29 | 30 | long long StopWatch::getElapsedMilliseconds() const 31 | { 32 | return duration_cast(getElapsedDuration()).count(); 33 | } 34 | 35 | double StopWatch::getElapsedSeconds() const 36 | { 37 | return getElapsedMilliseconds() / MS_PER_SECOND; 38 | } 39 | 40 | std::string StopWatch::getElapsedSecondsString(const std::string& suffix /*= ""*/) const 41 | { 42 | std::stringstream ss; 43 | ss << std::fixed << std::setprecision(3) << getElapsedSeconds() << suffix; 44 | return ss.str(); 45 | } 46 | 47 | system_clock::duration StopWatch::getElapsedDuration() const 48 | { 49 | // if stop() hasn't been called yet, use the current time 50 | if (m_stopped) return m_finished - m_started; 51 | else return system_clock::now() - m_started; 52 | } 53 | } -------------------------------------------------------------------------------- /.github/.labels.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "name": "assigned", "color": "0052cc", "description": "copilot" }, 3 | { "name": "assigned:copilot", "color": "ededed", "description": "" }, 4 | { "name": "bug", "color": "d73a4a", "description": "Something isn't working" }, 5 | { "name": "documentation", "color": "0075ca", "description": "Improvements or additions to documentation" }, 6 | { "name": "duplicate", "color": "cfd3d7", "description": "This issue or pull request already exists" }, 7 | { "name": "enhancement", "color": "a2eeef", "description": "New feature or request" }, 8 | { "name": "good first issue", "color": "7057ff", "description": "Good for newcomers" }, 9 | { "name": "help wanted", "color": "008672", "description": "Extra attention is needed" }, 10 | { "name": "invalid", "color": "e4e669", "description": "This doesn't seem right" }, 11 | { "name": "question", "color": "d876e3", "description": "Further information is requested" }, 12 | { "name": "state", "color": "b17457", "description": "blocked" }, 13 | { "name": "state:in-progress", "color": "ededed", "description": "" }, 14 | { "name": "state:planning", "color": "ededed", "description": "" }, 15 | { "name": "type:enhancement", "color": "ededed", "description": "" }, 16 | { "name": "wontfix", "color": "ffffff", "description": "This will not be worked on" } 17 | ] -------------------------------------------------------------------------------- /OdbDesignLib/App/OdbDesignArgs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "CommandLineArgs.h" 4 | #include "../odbdesign_export.h" 5 | 6 | namespace Odb::Lib::App 7 | { 8 | class ODBDESIGN_EXPORT OdbDesignArgs : public Utils::CommandLineArgs 9 | { 10 | public: 11 | OdbDesignArgs(int argc, char* argv[]); 12 | 13 | int port() const; 14 | bool useHttps() const; 15 | std::string sslDir() const; 16 | std::string designsDir() const; 17 | std::string templatesDir() const; 18 | bool help() const; 19 | std::string loadDesign() const; 20 | bool loadAll() const; 21 | bool disableAuthentication() const; 22 | 23 | protected: 24 | // Inherited via CommandLineArgs 25 | std::string getUsageString() const override; 26 | 27 | private: 28 | constexpr static const int DEFAULT_PORT = 8888; 29 | constexpr static const bool DEFAULT_USE_HTTPS = false; 30 | constexpr static const char* DEFAULT_SSL_DIR = "./ssl"; 31 | constexpr static const char* DEFAULT_DESIGNS_DIR = "designs"; 32 | constexpr static const char* DEFAULT_TEMPLATES_DIR = "templates"; 33 | constexpr static const bool DEFAULT_HELP = false; 34 | constexpr static const char* DEFAULT_LOAD_DESIGN = ""; 35 | constexpr static const bool DEFAULT_LOAD_ALL = false; 36 | constexpr static const bool DEFAULT_DISABLE_AUTH = false; 37 | 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/stephdrfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | package Odb.Lib.Protobuf; 7 | 8 | // 9 | // StepHdrFile.h 10 | // 11 | 12 | message StepHdrFile { 13 | 14 | message StepRepeatRecord 15 | { 16 | optional string name = 1; 17 | optional double x = 2; 18 | optional double y = 3; 19 | optional double dx = 4; 20 | optional double dy = 5; 21 | optional int32 nx = 6; 22 | optional int32 ny = 7; 23 | optional double angle = 8; 24 | optional bool flip = 9; 25 | optional bool mirror = 10; 26 | } 27 | 28 | optional double xDatum = 1; 29 | optional double yDatum = 2; 30 | optional int32 id = 3; 31 | optional double xOrigin = 4; 32 | optional double yOrigin = 5; 33 | optional double topActive = 6; 34 | optional double bottomActive = 7; 35 | optional double rightActive = 8; 36 | optional double leftActive = 9; 37 | optional string affectingBom = 10; 38 | optional bool affectingBomChanged = 11; 39 | optional string online = 12; 40 | repeated StepRepeatRecord stepRepeatRecords = 13; 41 | optional string path = 14; 42 | map onlineValues = 15; 43 | 44 | } -------------------------------------------------------------------------------- /.github/codeql/cpp-queries/odbdesign-security.ql: -------------------------------------------------------------------------------- 1 | /** 2 | * @name OdbDesign Security Checks 3 | * @description Custom security checks for OdbDesign C++ project 4 | * @kind problem 5 | * @problem.severity warning 6 | * @precision medium 7 | * @id cpp/odbdesign-security 8 | * @tags security 9 | * correctness 10 | * odbdesign 11 | */ 12 | 13 | import cpp 14 | 15 | // Check for unsafe string operations 16 | from FunctionCall fc, Function f 17 | where 18 | f = fc.getTarget() and 19 | ( 20 | // Unsafe C string functions 21 | f.hasGlobalName("strcpy") or 22 | f.hasGlobalName("strcat") or 23 | f.hasGlobalName("sprintf") or 24 | f.hasGlobalName("gets") or 25 | // Potentially unsafe buffer operations 26 | f.hasGlobalName("memcpy") or 27 | f.hasGlobalName("memmove") 28 | ) and 29 | // Exclude protobuf generated files 30 | not fc.getFile().getAbsolutePath().matches("%/protobuf/%") and 31 | not fc.getFile().getAbsolutePath().matches("%.pb.%") and 32 | // Exclude vcpkg dependencies 33 | not fc.getFile().getAbsolutePath().matches("%/vcpkg/%") and 34 | not fc.getFile().getAbsolutePath().matches("%/vcpkg_installed/%") 35 | select fc, "Potentially unsafe string/buffer operation: " + f.getName() + 36 | ". Consider using safer alternatives like strncpy, strncat, or std::string." 37 | -------------------------------------------------------------------------------- /local_ai_instruction_modules/ai-terminal-commands.md: -------------------------------------------------------------------------------- 1 | # Terminal Commands Cheat Sheet (pwsh-first) 2 | 3 | - Default shell: PowerShell (pwsh). Detect before running commands. 4 | - Web fetch: Use PowerShell Invoke-WebRequest (or curl) — web-fetch tool is disabled. 5 | - Prefer automation via MCP tools; terminal is last resort. 6 | 7 | ## PowerShell basics 8 | - Current shell: `$PSVersionTable.PSEdition`, `$PSVersionTable.PSVersion` 9 | - Download raw file: `Invoke-WebRequest -Uri -OutFile ` 10 | - Parallel downloads: `ForEach-Object -Parallel` (PowerShell 7+) 11 | - JSON: `Get-Content -Raw file.json | ConvertFrom-Json` 12 | 13 | ## GitHub CLI (gh) 14 | - Auth: `gh auth status` 15 | - Repo: `gh repo create owner/name --public|--private --template nam20485/ai-new-app-template` 16 | - View: `gh repo view owner/name -w` 17 | - Issues: `gh issue create -t "Title" -b "Body"` 18 | 19 | ## Git 20 | - Clone: `git clone https://github.com/owner/name.git` 21 | - Branch: `git checkout -B main` 22 | - Commit: `git add -A; git commit -m "msg"; git push -u origin main` 23 | 24 | ## Safety 25 | - Use `-WhatIf`/`-Confirm` for destructive cmdlets. 26 | - Quote paths with `-LiteralPath` and use `Join-Path`. 27 | 28 | --- 29 | This file exists to satisfy local docs linking and to standardize terminal usage when automation tools are unavailable. 30 | -------------------------------------------------------------------------------- /scripts/validate-toolset.ps1: -------------------------------------------------------------------------------- 1 | #requires -Version 7.0 2 | [CmdletBinding()] 3 | param( 4 | [string]$ToolsetPath = (Join-Path $PSScriptRoot '..\local_ai_instruction_modules\toolset.selected.json') 5 | ) 6 | $ErrorActionPreference = 'Stop' 7 | 8 | if (-not (Test-Path -LiteralPath $ToolsetPath)) { 9 | throw "Toolset file not found: $ToolsetPath" 10 | } 11 | 12 | $json = Get-Content -Raw -LiteralPath $ToolsetPath | ConvertFrom-Json 13 | $enabled = @($json.enabledTools) 14 | $disabled = @($json.disabledTools) 15 | 16 | $enabledCount = if ($enabled) { $enabled.Count } else { 0 } 17 | $disabledCount = if ($disabled) { $disabled.Count } else { 0 } 18 | 19 | if ($json.enabledCount -ne $enabledCount) { 20 | throw "enabledCount ($($json.enabledCount)) does not match enabledTools.Count ($enabledCount)" 21 | } 22 | if ($json.disabledCount -ne $disabledCount) { 23 | throw "disabledCount ($($json.disabledCount)) does not match disabledTools.Count ($disabledCount)" 24 | } 25 | 26 | # Ensure uniqueness in enabled 27 | $dupes = $enabled | Group-Object | Where-Object { $_.Count -gt 1 } | Select-Object -ExpandProperty Name 28 | if ($dupes) { 29 | throw "Duplicate tool entries found in enabledTools: $($dupes -join ', ')" 30 | } 31 | 32 | Write-Host "Toolset validation passed: enabled=$enabledCount disabled=$disabledCount" -ForegroundColor Green 33 | -------------------------------------------------------------------------------- /Utils/CommandLineArgs.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "utils_export.h" 6 | #include 7 | #include 8 | #include 9 | 10 | 11 | namespace Utils 12 | { 13 | class UTILS_EXPORT CommandLineArgs 14 | { 15 | public: 16 | CommandLineArgs(int argc, char* argv[]); 17 | CommandLineArgs(const std::vector& vecArgv); 18 | 19 | bool boolArg(const std::string& name, bool defaultValue) const; 20 | std::string stringArg(const std::string& name, const std::string& defaultValue) const; 21 | int intArg(const std::string& name, int defaultValue) const; 22 | double doubleArg(const std::string& name, double defaultValue) const; 23 | 24 | std::filesystem::path executable() const; 25 | std::filesystem::path executableDirectory() const; 26 | std::string executableName() const; 27 | 28 | bool isWindows() const; 29 | bool isLinux() const; 30 | 31 | void printUsage() const; 32 | 33 | protected: 34 | std::vector m_vecArguments; 35 | std::map m_mapArguments; 36 | 37 | std::string getArgValue(const std::string& name) const; 38 | 39 | void parse(); 40 | 41 | virtual std::string getUsageString() const = 0; 42 | 43 | const char* EXECUTABLE_ARG_NAME = "executable"; 44 | const char* EXE_EXTENSION = ".exe"; 45 | 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /OdbDesignLib/App/OdbServerAppBase.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "IOdbServerApp.h" 4 | #include "OdbAppBase.h" 5 | #include "RouteController.h" 6 | #include "../odbdesign_export.h" 7 | #include "RequestAuthenticationBase.h" 8 | #include 9 | #include 10 | #include 11 | 12 | namespace Odb::Lib::App 13 | { 14 | class ODBDESIGN_EXPORT OdbServerAppBase : public OdbAppBase, public IOdbServerApp 15 | { 16 | public: 17 | virtual ~OdbServerAppBase(); 18 | 19 | CrowApp& crow_app() override; 20 | 21 | RequestAuthenticationBase& request_auth() override; 22 | void request_auth(std::unique_ptr pRequestAuthentication) override; 23 | 24 | Utils::ExitCode Run() override; 25 | 26 | protected: 27 | OdbServerAppBase(int argc, char* argv[]); 28 | 29 | RouteController::Vector m_vecControllers; 30 | 31 | // implement in subclasses to add route controllers 32 | virtual void add_controllers() = 0; 33 | 34 | virtual bool preServerRun(); 35 | virtual bool postServerRun(); 36 | 37 | private: 38 | CrowApp m_crowApp; 39 | //crow::SimpleApp m_crowApp; 40 | std::unique_ptr m_pRequestAuthentication; 41 | 42 | void register_routes(); 43 | 44 | static constexpr const char* SSL_CERT_FILE = "ssl.crt"; 45 | static constexpr const char* SSL_KEY_FILE = "ssl.key"; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/design.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "filearchive.proto"; 7 | import "net.proto"; 8 | import "package.proto"; 9 | import "component.proto"; 10 | import "part.proto"; 11 | 12 | package Odb.Lib.Protobuf.ProductModel; 13 | 14 | // 15 | // Design.h 16 | // 17 | 18 | message Design { 19 | 20 | // std::string m_productModel; 21 | // std::string m_name; 22 | 23 | // std::shared_ptr m_pFileModel; 24 | 25 | // Net::Vector m_nets; 26 | // Net::StringMap m_netsByName; 27 | 28 | // Package::Vector m_packages; 29 | // Package::StringMap m_packagesByName; 30 | 31 | // Component::Vector m_components; 32 | // Component::StringMap m_componentsByName; 33 | 34 | // Part::Vector m_parts; 35 | // Part::StringMap m_partsByName; 36 | 37 | optional string productModel = 1; 38 | optional string name = 2; 39 | optional FileArchive fileModel = 3; 40 | repeated Net nets = 4; 41 | map netsByName = 5; 42 | repeated Package packages = 6; 43 | map packagesByName = 7; 44 | repeated Component components = 8; 45 | map componentsByName = 9; 46 | repeated Part parts = 10; 47 | map partsByName = 11; 48 | 49 | } -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/FileUploadController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "App/RouteController.h" 4 | #include "App/IOdbServerApp.h" 5 | 6 | namespace Odb::App::Server 7 | { 8 | class FileUploadController : public Odb::Lib::App::RouteController 9 | { 10 | public: 11 | FileUploadController(Odb::Lib::App::IOdbServerApp& serverApp); 12 | 13 | void register_routes() override; 14 | 15 | private: 16 | crow::response handleOctetStreamUpload(const std::string& filename, const crow::request& req); 17 | crow::response handleMultipartFormUpload(const crow::request& req); 18 | 19 | // TODO: actually implement sanitizeFilename() 20 | std::string sanitizeFilename(const std::string& filename) const; 21 | 22 | constexpr static const inline char MULTIPART_FORM_DATA_PART_NAME[] = "file"; 23 | constexpr static const inline char MULTIPART_FORM_DATA_PART_FILENAME[] = "filename"; 24 | constexpr static const inline char CONTENT_DISPOSITION_HEADER_NAME[] = "Content-Disposition"; 25 | constexpr static const inline char CONTENT_TYPE_HEADER_NAME[] = "Content-Type"; 26 | constexpr static const inline char CONTENT_TYPE_MULTIPART_FORM_DATA[] = "multipart/form-data"; 27 | constexpr static const inline char CONTENT_TYPE_APPLICATION_OCTET_STREAM[] = "application/octet-stream"; 28 | 29 | 30 | //constexpr static const inline char MULTIPART_FORMDATA_PART_NAME[] = "InputFile" 31 | 32 | }; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Package.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Pin.h" 9 | #include "../ProtoBuf/package.pb.h" 10 | #include "../IProtoBuffable.h" 11 | 12 | 13 | namespace Odb::Lib::ProductModel 14 | { 15 | class ODBDESIGN_EXPORT Package : public IProtoBuffable 16 | { 17 | public: 18 | Package(const std::string& name, unsigned int index); 19 | ~Package(); 20 | 21 | std::string GetName() const; 22 | unsigned int GetIndex() const; 23 | 24 | void AddPin(const std::string& name); 25 | std::shared_ptr GetPin(const std::string& name) const; 26 | std::shared_ptr GetPin(unsigned int index) const; 27 | const Pin::StringMap& GetPinsByName() const; 28 | const Pin::Vector& GetPins() const; 29 | 30 | // Inherited via IProtoBuffable 31 | std::unique_ptr to_protobuf() const override; 32 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Package& message) override; 33 | 34 | typedef std::vector> Vector; 35 | typedef std::map> StringMap; 36 | 37 | private: 38 | std::string m_name; 39 | Pin::Vector m_pins; 40 | Pin::StringMap m_pinsByName; 41 | unsigned int m_index; 42 | 43 | }; 44 | } // namespace Odb::Lib::ProductModel 45 | -------------------------------------------------------------------------------- /OdbDesignTests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : CMake project for OdbDesignTests 2 | # 3 | 4 | add_executable(OdbDesignTests 5 | "Fixtures/FileArchiveLoadFixture.h" 6 | "Fixtures/FileArchiveLoadFixture.cpp" 7 | "TestTests.cpp" 8 | "DesignCacheLoadTests.cpp" 9 | "Fixtures/DesignNameValueParamTest.h" 10 | "FileArchiveTests.cpp" 11 | "ProtobufSerializationTests.cpp" 12 | "FileReaderTests.cpp" 13 | "ArchiveTests.cpp" 14 | "CrossPlatformTests.cpp" 15 | "Fixtures/TestDataFixture.h" 16 | "Fixtures/TestDataFixture.cpp" 17 | "ArchiveExtractorTests.cpp" 18 | "PerformanceTests.cpp" 19 | "EnhancedTests.cpp" 20 | "IntegrationTests.cpp" 21 | "Fixtures/TestUtils.h") 22 | 23 | target_link_libraries(OdbDesignTests PRIVATE GTest::gtest_main GTest::gmock_main) 24 | 25 | # link to OdbDesign library 26 | target_link_libraries(OdbDesignTests PRIVATE OdbDesign) 27 | 28 | include(GoogleTest) 29 | # Defer test discovery to ctest time to avoid executing the test binary during build 30 | # This prevents build failures when runtime dependencies or environment variables 31 | # are not yet available at link/post-build time. 32 | gtest_discover_tests(OdbDesignTests DISCOVERY_MODE PRE_TEST) 33 | 34 | ## PCH 35 | #if (NOT DEFINED ENV{CI}) 36 | file (GLOB_RECURSE OdbDesignTests_HEADER_FILES "*.h") 37 | target_precompile_headers(OdbDesignTests PRIVATE ${OdbDesignTests_HEADER_FILES}) 38 | #endif() -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/PinConnection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Component.h" 9 | #include "Pin.h" 10 | #include "../ProtoBuf/pinconnection.pb.h" 11 | #include "../IProtoBuffable.h" 12 | 13 | 14 | namespace Odb::Lib::ProductModel 15 | { 16 | class ODBDESIGN_EXPORT PinConnection : public IProtoBuffable 17 | { 18 | public: 19 | PinConnection(std::shared_ptr pComponent, std::shared_ptr pPin); 20 | PinConnection(std::shared_ptr pComponent, std::shared_ptr pPin, const std::string& name); 21 | //~PinConnection(); 22 | 23 | std::shared_ptr GetPin() const; 24 | std::shared_ptr GetComponent() const; 25 | 26 | static std::string MakeName(const Component& component, const Pin& pin); 27 | 28 | // Inherited via IProtoBuffable 29 | std::unique_ptr to_protobuf() const override; 30 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::PinConnection& message) override; 31 | 32 | typedef std::vector> Vector; 33 | typedef std::map> StringMap; 34 | 35 | private: 36 | std::string m_name; 37 | std::shared_ptr m_pComponent; 38 | std::shared_ptr m_pPin; 39 | 40 | }; 41 | } 42 | -------------------------------------------------------------------------------- /scripts/deploy.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | # Cluster name 3 | [Parameter(Mandatory=$true)] 4 | [string]$ClusterName, 5 | # Deployment name 6 | [Parameter(Mandatory=$true)] 7 | [string]$DeploymentName 8 | ) 9 | 10 | # set kubeconfig 11 | kubectl config use-context $ClusterName 12 | if ($LASTEXITCODE -ne 0) { 13 | Exit 1 14 | } 15 | 16 | # 17 | # Common (pre) 18 | # 19 | 20 | # persistent volume 21 | kubectl apply -f deploy/kube/k3d-volume-pv.yaml 22 | kubectl apply -f deploy/kube/k3d-volume-pvc.yaml 23 | 24 | # 25 | # OdbDesignServer 26 | # 27 | 28 | # secrets 29 | & "$PSScriptRoot\odbdesign-server-request-secret.ps1" 30 | 31 | # apply deployment/service manifests 32 | kubectl apply -f deploy/kube/OdbDesignServer/deployment.yaml 33 | kubectl apply -f deploy/kube/OdbDesignServer/service.yaml 34 | 35 | # restart deployment 36 | kubectl rollout restart deployment/$DeploymentName 37 | kubectl rollout status deployment/$DeploymentName 38 | 39 | 40 | # 41 | # Swagger UI 42 | # 43 | 44 | # apply deployment/service manifests 45 | kubectl apply -f deploy/kube/OdbDesignServer-SwaggerUI/deployment.yaml 46 | kubectl apply -f deploy/kube/OdbDesignServer-SwaggerUI/service.yaml 47 | 48 | # restart deployment 49 | kubectl rollout restart deployment/odbdesign-server-swaggerui-v1 50 | kubectl rollout status deployment/odbdesign-server-swaggerui-v1 51 | 52 | # 53 | # Common (post) 54 | # 55 | 56 | # apply ingress manifest 57 | kubectl apply -f deploy/kube/local-ingress.yaml 58 | -------------------------------------------------------------------------------- /Utils/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # CMakeList.txt : CMake project for OdbDesignServer 2 | # 3 | 4 | add_library(Utils SHARED "utils_export.h" "ExitCode.h" "ThreadSafeQueue.h" "WorkQueueLoopThread.h" "Logger.h" "Logger.cpp" "CommandLineArgs.h" "CommandLineArgs.cpp" "bin2ascii.h" "ArchiveExtractor.cpp" "ArchiveExtractor.h" "libarchive_extract.cpp" "libarchive_extract.h" "str_utils.cpp" "str_utils.h" "IJsonable.h" "IJsonable.cpp" "CrowReturnable.h" "JsonCrowReturnable.h" "timestamp.h" "timestamp.cpp" "StopWatch.h" "StopWatch.cpp" "UrlEncoding.h" "UrlEncoding.cpp" "StringVector.h" "equals_within.h" "equals_within.cpp" "crow_win.h" "fastmove.h" "fastmove.cpp" "FileReader.h" "FileReader.cpp" "EnumMap.h" "EnumMap.cpp" "CrossPlatform.h" "CrossPlatform.cpp" "macros.h") 5 | 6 | # state that anybody linking to us needs to include the current source dir, 7 | # while we don't. 8 | target_include_directories(Utils 9 | INTERFACE 10 | $ 11 | $) 12 | 13 | ## PCH 14 | #if (NOT DEFINED ENV{CI}) 15 | file (GLOB_RECURSE UTILS_HEADER_FILES "*.h") 16 | target_precompile_headers(Utils PRIVATE ${UTILS_HEADER_FILES}) 17 | #endif() 18 | 19 | # Link to LibArchive 20 | find_package(LibArchive REQUIRED) 21 | target_link_libraries(Utils PRIVATE LibArchive::LibArchive) 22 | 23 | # Link to Crow (needed for crow_win.h) 24 | find_package(Crow CONFIG REQUIRED) 25 | target_link_libraries(Utils PRIVATE Crow::Crow) 26 | -------------------------------------------------------------------------------- /OdbDesignTests/Fixtures/FileArchiveLoadFixture.cpp: -------------------------------------------------------------------------------- 1 | #include "FileArchiveLoadFixture.h" 2 | #include 3 | #include "Logger.h" 4 | #include 5 | #include 6 | #include "App/DesignCache.h" 7 | #include "TestDataFixture.h" 8 | #include 9 | 10 | using namespace std::filesystem; 11 | //using namespace Odb::Lib; 12 | using namespace Odb::Lib::App; 13 | using namespace Utils; 14 | 15 | namespace Odb::Test::Fixtures 16 | { 17 | FileArchiveLoadFixture::FileArchiveLoadFixture() 18 | : m_pDesignCache(nullptr) 19 | { 20 | } 21 | 22 | void FileArchiveLoadFixture::SetUp() 23 | { 24 | TestDataFixture::SetUp(); 25 | 26 | m_pDesignCache = std::unique_ptr(new DesignCache(getTestDataDir().string())); 27 | ASSERT_NE(m_pDesignCache, nullptr); 28 | } 29 | 30 | void FileArchiveLoadFixture::TearDown() 31 | { 32 | if (m_removeDecompressedDirectories) 33 | { 34 | if (exists(getTestDataDir())) 35 | { 36 | // delete uncompressed directories 37 | for (const auto& entry : directory_iterator(getTestDataDir())) 38 | { 39 | if (is_directory(entry)) 40 | { 41 | if (std::find(KEEP_DIRECTORIES.begin(), KEEP_DIRECTORIES.end(), entry.path().filename()) == KEEP_DIRECTORIES.end()) 42 | { 43 | remove_all(entry.path()); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | 50 | TestDataFixture::TearDown(); 51 | } 52 | 53 | path FileArchiveLoadFixture::getDesignPath(const std::string& filename) const 54 | { 55 | return getTestDataDir() / filename; 56 | } 57 | } -------------------------------------------------------------------------------- /.github/workflows/prebuild.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pre-build dev container image 3 | 4 | on: 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - main 9 | - development 10 | 11 | env: 12 | REGISTRY: ghcr.io 13 | IMAGE_NAME: nam20485/agent-instructions-devcontainer 14 | VERSION_IMAGE_TAG: "${{ vars.VERSION_PREFIX }}.${{ github.run_number }}" 15 | 16 | jobs: 17 | prebuild: 18 | permissions: 19 | contents: read 20 | packages: write 21 | id-token: write 22 | attestations: write 23 | 24 | runs-on: ubuntu-22.04 25 | # only build the prebuild in agent-instructions repo 26 | if: github.repository == 'nam20485/agent-instructions' 27 | steps: 28 | 29 | - name: Checkout repository 30 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 31 | 32 | - name: Login to GitHub Container Registry 33 | uses: docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 34 | with: 35 | registry: ghcr.io 36 | username: ${{ github.actor }} 37 | password: ${{ secrets.GITHUB_TOKEN }} 38 | 39 | - name: Pre-build dev container image 40 | uses: devcontainers/ci@8bf61b26e9c3a98f69cb6ce2f88d24ff59b785c6 41 | id: prebuild 42 | with: 43 | subFolder: .github 44 | imageName: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 45 | cacheFrom: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} 46 | imageTag: latest, ${{ env.VERSION_IMAGE_TAG }} 47 | push: always 48 | -------------------------------------------------------------------------------- /OdbDesignTests/Fixtures/TestDataFixture.cpp: -------------------------------------------------------------------------------- 1 | #include "TestDataFixture.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std::filesystem; 8 | using namespace Utils; 9 | 10 | namespace Odb::Test::Fixtures 11 | { 12 | TestDataFixture::TestDataFixture() 13 | : m_testDataDir() 14 | { 15 | } 16 | 17 | void TestDataFixture::SetUp() 18 | { 19 | if (ENABLE_TEST_LOGGING) 20 | { 21 | Logger::instance()->start(); 22 | } 23 | 24 | ASSERT_FALSE(getTestDataDir().empty()); 25 | m_testDataDir = getTestDataDir(); 26 | m_testDataDir = m_testDataDir.make_preferred(); 27 | ASSERT_TRUE(exists(m_testDataDir)); 28 | } 29 | 30 | void TestDataFixture::TearDown() 31 | { 32 | if (ENABLE_TEST_LOGGING) 33 | { 34 | Logger::instance()->stop(); 35 | } 36 | } 37 | 38 | path TestDataFixture::getTestDataDir() 39 | { 40 | auto szTestDataDir = std::getenv(ODB_TEST_DATA_DIR_ENV_NAME); 41 | if (szTestDataDir == nullptr) return ""; 42 | //if (szTestDataDir == nullptr) throw std::runtime_error("ODB_TEST_DATA_DIR environment variable is not set"); 43 | //if (!exists(szTestDataDir)) throw std::runtime_error("ODB_TEST_DATA_DIR environment variable is set to a non-existent directory"); 44 | return szTestDataDir; 45 | } 46 | 47 | path TestDataFixture::getTestDataFilesDir() const 48 | { 49 | return m_testDataDir / TESTDATA_FILES_DIR; 50 | } 51 | 52 | path TestDataFixture::getTestDataFilePath(const std::string& filename) const 53 | { 54 | return getTestDataFilesDir() / filename; 55 | } 56 | } -------------------------------------------------------------------------------- /Utils/timestamp.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by nam20485 on 6/12/22. 3 | // 4 | 5 | #include 6 | #include 7 | #include 8 | #include "timestamp.h" 9 | #include 10 | #include 11 | 12 | using namespace std::chrono; 13 | 14 | namespace Utils 15 | { 16 | const int MS_PER_S = 1000; 17 | 18 | std::string make_timestamp(const system_clock::time_point& timepoint) 19 | { 20 | auto tp_time_t = system_clock::to_time_t(timepoint); 21 | struct tm* p_tm = localtime(&tp_time_t); 22 | if (p_tm == nullptr) return ""; 23 | auto ms = duration_cast(timepoint.time_since_epoch()) % MS_PER_S; 24 | 25 | std::stringstream ss; 26 | // date and time 27 | ss << std::put_time(p_tm, "%D %T"); 28 | // add ms 29 | ss << '.' << std::setfill('0') << std::setw(3) << ms.count(); 30 | return ss.str(); 31 | } 32 | 33 | std::string make_timestamp() 34 | { 35 | return make_timestamp(system_clock::now()); 36 | } 37 | 38 | system_clock::time_point parse_timestamp(const std::string& timestamp, const std::string& format) 39 | { 40 | struct tm tm{}; 41 | std::istringstream ss(timestamp); 42 | ss >> std::get_time(&tm, format.c_str()); 43 | 44 | #if defined(_DEBUG) 45 | std::stringstream ss2; 46 | ss2 << std::put_time(&tm, "%D %T"); 47 | auto s = ss2.str(); 48 | #endif // DEBUG 49 | 50 | auto tp = system_clock::from_time_t(std::mktime(&tm)); 51 | return tp; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /OdbDesignTests/TestTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | //#include 3 | #include "Fixtures/TestDataFixture.h" 4 | #include 5 | #include 6 | #include 7 | #include "Fixtures/FileArchiveLoadFixture.h" 8 | 9 | using namespace std::filesystem; 10 | using namespace Odb::Test::Fixtures; 11 | using namespace testing; 12 | 13 | namespace Odb::Test 14 | { 15 | // Demonstrate some basic assertions. 16 | TEST(TestTest, BasicAssertions) 17 | { 18 | // Expect two strings not to be equal. 19 | EXPECT_STRNE("hello", "world"); 20 | // Expect equality. 21 | EXPECT_EQ(7 * 6, 42); 22 | EXPECT_FLOAT_EQ(1.0f, 1.0f); 23 | EXPECT_TRUE(true != false); 24 | EXPECT_FALSE(true == false); 25 | } 26 | 27 | TEST(TestTest, SucceedSucceeds) 28 | { 29 | SUCCEED(); 30 | } 31 | 32 | TEST_F(TestDataFixture, TestDataDirEnvironmentVariablesExists) 33 | { 34 | EXPECT_THAT(getTestDataDir().string(), Not(IsEmpty())); 35 | } 36 | 37 | TEST_F(TestDataFixture, TestDataDirDirectoryExists) 38 | { 39 | ASSERT_FALSE(getTestDataDir().empty()); 40 | EXPECT_TRUE(exists(getTestDataDir())); 41 | } 42 | 43 | TEST_F(FileArchiveLoadFixture, TestDataDesignsExist) 44 | { 45 | ASSERT_TRUE(exists(getDesignPath("sample_design.tgz"))); 46 | ASSERT_TRUE(exists(getDesignPath("designodb_rigidflex.tgz"))); 47 | } 48 | 49 | TEST_F(TestDataFixture, TestDataFilesDirDirectoryExists) 50 | { 51 | EXPECT_THAT(getTestDataFilesDir().string(), Not(IsEmpty())); 52 | EXPECT_TRUE(exists(getTestDataFilesDir())); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/RgbColor.cpp: -------------------------------------------------------------------------------- 1 | #include "RgbColor.h" 2 | #include 3 | 4 | namespace Odb::Lib::FileModel::Design 5 | { 6 | RgbColor::RgbColor() 7 | : red(0) 8 | , green(0) 9 | , blue(0) 10 | , noPreference(false) 11 | { 12 | } 13 | 14 | RgbColor::RgbColor(const std::string& str) 15 | : RgbColor() 16 | { 17 | from_string(str); 18 | } 19 | 20 | bool RgbColor::from_string(const std::string& str) 21 | { 22 | if (str.length() == 6) 23 | { 24 | auto strRed = str.substr(0, 2); 25 | auto strGreen = str.substr(2, 2); 26 | auto strBlue = str.substr(4, 2); 27 | 28 | // valid values are [0,100] 29 | red = static_cast(std::stoi(strRed)); 30 | blue = static_cast(std::stoi(strBlue)); 31 | green = static_cast(std::stoi(strGreen)); 32 | 33 | noPreference = false; 34 | return true; 35 | } 36 | else if (str.length() == 1) 37 | { 38 | if (str[0] == '0') 39 | { 40 | noPreference = true; 41 | return true; 42 | } 43 | } 44 | 45 | return false; 46 | } 47 | 48 | std::string RgbColor::to_string() const 49 | { 50 | if (noPreference) 51 | { 52 | return "0"; 53 | } 54 | else 55 | { 56 | return std::to_string(red) + std::to_string(green) + std::to_string(blue); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /.github/workflows/disabled/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload a Python Package using Twine when a release is created 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Upload Python Package 10 | 11 | on: 12 | release: 13 | types: [published] 14 | push: 15 | branches: 16 | - release 17 | #- development 18 | 19 | permissions: 20 | contents: read 21 | 22 | jobs: 23 | deploy: 24 | 25 | runs-on: ubuntu-latest 26 | defaults: 27 | run: 28 | working-directory: PyOdbDesignLib 29 | 30 | steps: 31 | - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 32 | - name: Set up Python 33 | uses: actions/setup-python@3542bca2639a428e1796aaa6a2ffef0c0f575566 # v3.1.4 34 | with: 35 | python-version: '3.x' 36 | - name: Install dependencies 37 | run: | 38 | python -m pip install --upgrade pip 39 | pip install build 40 | - name: Build package 41 | run: python -m build 42 | - name: Publish package 43 | uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 44 | with: 45 | user: __token__ 46 | password: ${{ secrets.PYPI_API_TOKEN_PYODBDESIGNLIB }} 47 | packages_dir: PyOdbDesignLib/dist 48 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Component.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "Package.h" 9 | #include "../enums.h" 10 | #include "Part.h" 11 | #include "../ProtoBuf/component.pb.h" 12 | #include "../IProtoBuffable.h" 13 | 14 | 15 | namespace Odb::Lib::ProductModel 16 | { 17 | class ODBDESIGN_EXPORT Component : public IProtoBuffable 18 | { 19 | public: 20 | Component(); 21 | Component(const std::string& refDes, const std::string& partName, std::shared_ptr pPackage, unsigned int index, BoardSide side, std::shared_ptr pPart); 22 | ~Component(); 23 | 24 | std::string GetRefDes() const; 25 | std::string GetPartName() const; 26 | std::shared_ptr GetPackage() const; 27 | unsigned int GetIndex() const; 28 | BoardSide GetSide() const; 29 | std::shared_ptr GetPart() const; 30 | 31 | // Inherited via IProtoBuffable 32 | std::unique_ptr to_protobuf() const override; 33 | void from_protobuf(const Odb::Lib::Protobuf::ProductModel::Component& message) override; 34 | 35 | //static Component* MakeEmpty(); 36 | 37 | typedef std::vector> Vector; 38 | typedef std::map> StringMap; 39 | 40 | private: 41 | std::string m_refDes; 42 | std::string m_partName; 43 | std::shared_ptr m_pPackage; 44 | unsigned int m_index; 45 | BoardSide m_side; 46 | std::shared_ptr m_pPart; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/DesignsController.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "App/RouteController.h" 4 | 5 | namespace Odb::App::Server 6 | { 7 | class DesignsController : public Odb::Lib::App::RouteController 8 | { 9 | public: 10 | 11 | DesignsController(Odb::Lib::App::IOdbServerApp& serverApp); 12 | 13 | // Inherited via RouteController 14 | void register_routes() override; 15 | 16 | constexpr inline static const char* kszIncludeFileArchiveQueryParamName = "include_filearchive"; 17 | 18 | private: 19 | 20 | crow::response designs_list_route_handler(const crow::request& req); 21 | crow::response design_route_handler(std::string designName, const crow::request& req); 22 | 23 | crow::response designs_components_route_handler(std::string designName, const crow::request& req); 24 | crow::response designs_component_route_handler(std::string designName, std::string refDes, const crow::request& req); 25 | 26 | crow::response designs_nets_route_handler(std::string designName, const crow::request& req); 27 | crow::response designs_net_route_handler(std::string designName, std::string netName, const crow::request& req); 28 | 29 | crow::response designs_parts_route_handler(std::string designName, const crow::request& req); 30 | crow::response designs_part_route_handler(std::string designName, std::string partName, const crow::request& req); 31 | 32 | crow::response designs_packages_route_handler(std::string designName, const crow::request& req); 33 | crow::response designs_package_route_handler(std::string designName, std::string packageName, const crow::request& req); 34 | 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, 4 | # surfacing known-vulnerable versions of the packages declared or updated in the PR. 5 | # Once installed, if the workflow run is marked as required, 6 | # PRs introducing known-vulnerable packages will be blocked from merging. 7 | # 8 | # Source repository: https://github.com/actions/dependency-review-action 9 | name: 'Dependency Review' 10 | on: 11 | pull_request: 12 | branches: [ "main", "staging", "release", "development", "nam20485" ] 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | 19 | dependency-review: 20 | runs-on: ubuntu-22.04 21 | permissions: 22 | id-token: write 23 | contents: write 24 | pull-requests: write 25 | security-events: write 26 | actions: read 27 | 28 | 29 | steps: 30 | - name: Harden Runner 31 | uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 32 | with: 33 | egress-policy: audit 34 | 35 | - name: 'Checkout Repository' 36 | uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 37 | 38 | - name: Component detection 39 | uses: advanced-security/component-detection-dependency-submission-action@d433c2f467e149a8009c8fbce92cc708ed15ef7b # v0.1.0 40 | 41 | - name: 'Dependency Review' 42 | uses: actions/dependency-review-action@3b139cfc5fae8b618d3eae3675e383bb1769c019 # v4.5.0 43 | with: 44 | comment-summary-in-pr: true 45 | -------------------------------------------------------------------------------- /OdbDesignServer/Controllers/HealthCheckController.cpp: -------------------------------------------------------------------------------- 1 | #include "HealthCheckController.h" 2 | 3 | using namespace Odb::Lib::App; 4 | 5 | namespace Odb::App::Server 6 | { 7 | HealthCheckController::HealthCheckController(IOdbServerApp& serverApp) 8 | : RouteController(serverApp) 9 | { 10 | } 11 | 12 | void HealthCheckController::register_routes() 13 | { 14 | //register_route_handler("/health_check", std::bind(&HealthCheckController::health_check, this, std::placeholders::_1)); 15 | 16 | //register_route_handler("/health_check", [&](const crow::request& req) /*-> crow::response*/ 17 | // { 18 | // return crow::response(crow::status::OK, "healthy"); 19 | // } 20 | //); 21 | 22 | register_route_handler("/healthz/live", std::bind(&HealthCheckController::health_check_live, this, std::placeholders::_1)); 23 | register_route_handler("/healthz/ready", std::bind(&HealthCheckController::health_check_ready, this, std::placeholders::_1)); 24 | register_route_handler("/healthz/started", std::bind(&HealthCheckController::health_check_started, this, std::placeholders::_1)); 25 | } 26 | 27 | crow::response HealthCheckController::health_check_live(const crow::request& req) 28 | { 29 | return crow::response(crow::status::OK, "txt", "healthy: live"); 30 | } 31 | 32 | crow::response HealthCheckController::health_check_ready(const crow::request& req) 33 | { 34 | return crow::response(crow::status::OK, "txt", "healthy: ready"); 35 | } 36 | 37 | crow::response HealthCheckController::health_check_started(const crow::request& req) 38 | { 39 | return crow::response(crow::status::OK, "txt", "healthy: started"); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/SymbolsDirectory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../odbdesign_export.h" 4 | #include "FeaturesFile.h" 5 | #include "AttrListFile.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include "../../IProtoBuffable.h" 12 | #include "../../ProtoBuf/symbolsdirectory.pb.h" 13 | #include "../ISaveable.h" 14 | 15 | namespace Odb::Lib::FileModel::Design 16 | { 17 | class ODBDESIGN_EXPORT SymbolsDirectory : public IProtoBuffable, public ISaveable 18 | { 19 | public: 20 | SymbolsDirectory(const std::filesystem::path& path); 21 | 22 | typedef std::vector> Vector; 23 | typedef std::map> StringMap; 24 | 25 | bool Parse(); 26 | // Inherited via ISaveable 27 | bool Save(const std::filesystem::path& directory) override; 28 | 29 | std::string GetName() const; 30 | std::filesystem::path GetPath() const; 31 | 32 | const FeaturesFile& GetFeaturesFile() const; 33 | const AttrListFile& GetAttrListFile() const; 34 | 35 | // Inherited via IProtoBuffable 36 | std::unique_ptr to_protobuf() const override; 37 | void from_protobuf(const Odb::Lib::Protobuf::SymbolsDirectory& message) override; 38 | 39 | private: 40 | std::string m_name; 41 | std::filesystem::path m_path; 42 | 43 | FeaturesFile m_featuresFile; 44 | AttrListFile m_attrListFile; 45 | 46 | bool ParseFeaturesFile(const std::filesystem::path& directory); 47 | bool ParseAttrListFile(const std::filesystem::path& directory); 48 | 49 | }; 50 | } 51 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/netlistfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package Odb.Lib.Protobuf; 4 | 5 | // 6 | // NetlistFile.h 7 | // 8 | 9 | message NetlistFile { 10 | 11 | message NetRecord { 12 | 13 | optional uint32 serialNumber = 1; 14 | optional string netName = 2; 15 | 16 | } 17 | 18 | message NetPointRecord { 19 | 20 | enum AccessSide { 21 | Top = 0; 22 | Down = 1; 23 | Both = 2; 24 | Inner = 3; 25 | } 26 | 27 | optional uint32 netNumber = 1; 28 | optional double radius = 2; 29 | optional double x = 3; 30 | optional double y = 4; 31 | optional AccessSide side = 5; 32 | optional double width = 6; 33 | optional double height = 7; 34 | optional string epoint = 8; 35 | optional string exp = 9; 36 | optional bool commentPoint = 10; 37 | optional double staggeredX = 11; 38 | optional double staggeredY = 12; 39 | optional double staggeredRadius = 13; 40 | optional double viaPoint = 14; 41 | optional double fiducialPoint = 15; 42 | optional double testPoint = 16; 43 | optional string testExecutionSide = 17; 44 | } 45 | 46 | enum Staggered { 47 | Yes = 0; 48 | No = 1; 49 | Unknown = 2; 50 | } 51 | 52 | optional string path = 1; 53 | optional string name = 2; 54 | optional string units = 3; 55 | optional bool optimized = 4; 56 | optional Staggered staggered = 5; 57 | 58 | repeated NetRecord netRecordss = 6; 59 | map netRecordsByName = 7; 60 | repeated NetPointRecord netPointRecords = 8; 61 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/AttrListFile.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by nmill on 10/13/2023. 3 | // 4 | #ifndef ODBDESIGN_ATTRLISTFILE_H 5 | #define ODBDESIGN_ATTRLISTFILE_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include "../../IProtoBuffable.h" 11 | #include "../../ProtoBuf/attrlistfile.pb.h" 12 | #include "../../odbdesign_export.h" 13 | #include "../IStreamSaveable.h" 14 | #include 15 | 16 | namespace Odb::Lib::FileModel::Design 17 | { 18 | class ODBDESIGN_EXPORT AttrListFile : public IProtoBuffable, public IStreamSaveable 19 | { 20 | public: 21 | AttrListFile(); 22 | 23 | typedef std::map AttributeMap; 24 | 25 | std::string GetUnits() const; 26 | const AttributeMap& GetAttributes() const; 27 | 28 | bool Parse(std::filesystem::path directory); 29 | // Inherited via IStreamSaveable 30 | bool Save(std::ostream& os) override; 31 | 32 | // Inherited via IProtoBuffable 33 | std::unique_ptr to_protobuf() const override; 34 | void from_protobuf(const Odb::Lib::Protobuf::AttrListFile& message) override; 35 | 36 | private: 37 | std::filesystem::path m_directory; 38 | std::filesystem::path m_path; 39 | std::string m_units; 40 | AttributeMap m_attributesByName; 41 | 42 | bool attributeValueIsOptional(const std::string& attributeName) const; 43 | 44 | inline static const auto ATTRLIST_FILENAMES = { "attrlist" }; 45 | inline static const char* OPTIONAL_ATTRIBUTES[] = { "" }; 46 | }; 47 | } 48 | 49 | #endif //ODBDESIGN_ATTRLISTFILE_H 50 | -------------------------------------------------------------------------------- /OdbDesignTests/FileReaderTests.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "FileReader.h" 4 | #include "Fixtures/TestDataFixture.h" 5 | 6 | using namespace std::filesystem; 7 | using namespace Odb::Test::Fixtures; 8 | using namespace testing; 9 | using namespace Utils; 10 | 11 | namespace Odb::Test 12 | { 13 | static inline constexpr char FILE_CONTENTS[] = "Hello, World!"; 14 | static inline constexpr char FILE_NAME[] = "filereader_test1.txt"; 15 | 16 | TEST_F(TestDataFixture, Test_FileReaderRead_FileExists) 17 | { 18 | auto filePath = getTestDataFilePath(FILE_NAME); 19 | ASSERT_FALSE(filePath.empty()); 20 | ASSERT_TRUE(exists(filePath)); 21 | } 22 | 23 | TEST_F(TestDataFixture, Test_FileReaderRead_Buffered) 24 | { 25 | auto filePath = getTestDataFilePath(FILE_NAME); 26 | ASSERT_FALSE(filePath.empty()); 27 | ASSERT_TRUE(exists(filePath)); 28 | 29 | FileReader fr(filePath); 30 | 31 | auto fileSize = file_size(filePath); 32 | auto read = fr.Read(FileReader::BufferStrategy::Buffered); 33 | ASSERT_EQ(read, fileSize); 34 | 35 | auto& buffer = fr.GetBuffer(); 36 | ASSERT_EQ(buffer.size(), fileSize); 37 | ASSERT_STREQ(buffer.data(), FILE_CONTENTS); 38 | } 39 | 40 | TEST_F(TestDataFixture, Test_FileReaderRead_Unbuffered) 41 | { 42 | auto filePath = getTestDataFilePath(FILE_NAME); 43 | ASSERT_FALSE(filePath.empty()); 44 | ASSERT_TRUE(exists(filePath)); 45 | 46 | FileReader fr(filePath); 47 | 48 | auto fileSize = file_size(filePath); 49 | auto read = fr.Read(FileReader::BufferStrategy::Unbuffered); 50 | ASSERT_EQ(read, fileSize); 51 | 52 | auto& buffer = fr.GetBuffer(); 53 | ASSERT_EQ(buffer.size(), fileSize); 54 | ASSERT_STREQ(buffer.data(), FILE_CONTENTS); 55 | } 56 | } -------------------------------------------------------------------------------- /OdbDesignLib/protoc/matrixfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package Odb.Lib.Protobuf; 4 | 5 | import "color.proto"; 6 | import "enums.proto"; 7 | 8 | // 9 | // MatrixFile.h 10 | // 11 | 12 | message MatrixFile { 13 | 14 | message StepRecord { 15 | 16 | uint32 column = 1; 17 | uint32 id = 2; 18 | string name = 3; 19 | } 20 | 21 | message LayerRecord { 22 | 23 | enum Type { 24 | Signal = 0; 25 | PowerGround = 1; 26 | Dielectric = 2; 27 | Mixed = 3; 28 | SolderMask = 4; 29 | SolderPaste = 5; 30 | SilkScreen = 6; 31 | Drill = 7; 32 | Rout = 8; 33 | Document = 9; 34 | Component = 10; 35 | Mask = 11; 36 | ConductivePaste = 12; 37 | } 38 | 39 | enum Context { 40 | Board = 0; 41 | Misc = 1; 42 | } 43 | 44 | enum DielectricType { 45 | None = 0; 46 | Prepreg = 1; 47 | Core = 2; 48 | } 49 | 50 | enum Form { 51 | Rigid = 0; 52 | Flex = 1; 53 | } 54 | 55 | uint32 row = 1; 56 | Context context = 2; 57 | Type type = 3; 58 | string name = 4; 59 | Polarity polarity = 5; 60 | DielectricType dielectricType = 6; 61 | string dielectricName = 7; 62 | Form form = 8; 63 | uint32 cuTop = 9; 64 | uint32 cuBottom = 10; 65 | uint32 ref = 11; 66 | string startName = 12; 67 | string endName = 13; 68 | string oldName = 14; 69 | string addType = 15; 70 | Color color = 16; 71 | uint32 id = 17; 72 | } 73 | 74 | repeated StepRecord steps = 1; 75 | repeated LayerRecord layers = 2; 76 | } -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/Net.cpp: -------------------------------------------------------------------------------- 1 | #include "Net.h" 2 | #include 3 | #include "Component.h" 4 | #include "Pin.h" 5 | #include "../ProtoBuf/net.pb.h" 6 | #include 7 | #include "PinConnection.h" 8 | 9 | 10 | namespace Odb::Lib::ProductModel 11 | { 12 | Net::Net(const std::string& name, unsigned int index) 13 | : m_name(name) 14 | , m_index(index) 15 | { 16 | } 17 | 18 | Net::~Net() 19 | { 20 | m_pinConnections.clear(); 21 | } 22 | 23 | std::string Net::GetName() const 24 | { 25 | return m_name; 26 | } 27 | 28 | PinConnection::Vector& Net::GetPinConnections() 29 | { 30 | return m_pinConnections; 31 | } 32 | 33 | unsigned int Net::GetIndex() const 34 | { 35 | return m_index; 36 | } 37 | 38 | bool Net::AddPinConnection(std::shared_ptr pComponent, std::shared_ptr pPin) 39 | { 40 | m_pinConnections.push_back(std::make_shared(pComponent, pPin)); 41 | return true; 42 | } 43 | 44 | std::unique_ptr Odb::Lib::ProductModel::Net::to_protobuf() const 45 | { 46 | auto pNetMsg = std::make_unique(); 47 | pNetMsg->set_name(m_name); 48 | pNetMsg->set_index(m_index); 49 | for (auto& pPinConnection : m_pinConnections) 50 | { 51 | pNetMsg->add_pinconnections()->CopyFrom(*pPinConnection->to_protobuf()); 52 | } 53 | return pNetMsg; 54 | } 55 | 56 | void Odb::Lib::ProductModel::Net::from_protobuf(const Odb::Lib::Protobuf::ProductModel::Net& message) 57 | { 58 | m_name = message.name(); 59 | m_index = message.index(); 60 | for (auto& pinConnectionMsg : message.pinconnections()) 61 | { 62 | auto pPinConnection = std::make_shared(nullptr, nullptr, ""); 63 | pPinConnection->from_protobuf(pinConnectionMsg); 64 | m_pinConnections.push_back(pPinConnection); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /docs/SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | ## Supported Versions 4 | 5 | | Version | Supported | 6 | | ------- | ------------------ | 7 | | 1.0.x | :white_check_mark: | 8 | | < 1.0.x | :x: | 9 | 10 | ## Reporting a Vulnerability 11 | 12 | Security vulnerabilities can be reported privately using the [_Report a Vulnerability_](https://github.com/nam20485/OdbDesign/security) button under the _Security_ tab of this GitHub repository. 13 | Full instructions can be found [here](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability#privately-reporting-a-security-vulnerability). 14 | 15 | If you would like to report a vulnerability publicly, you can create a regular GitHub issue describing it under the Issues tab. 16 | 17 | If you have any questions or the reporting button is not working, please email the [maintainer](mailto:nmiller217@gmail.com). 18 | 19 | ### Timeline 20 | 21 | We strive to provide responses and updates as quickly as we are able. 22 | 23 | You can expect a response in 24-48 hours from submission and regular updates after that by the end of each week. Disclosures can be expected within 60 days. 24 | 25 | ### Details 26 | 27 | When reporting, please include as much of the following details as possible: 28 | 29 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 30 | * Full paths of source file(s) related to the manifestation of the issue 31 | * The location of the affected source code (tag/branch/commit or direct URL) 32 | * Any special configuration required to reproduce the issue 33 | * Step-by-step instructions to reproduce the issue 34 | * Proof-of-concept or exploit code (if possible) 35 | * Impact of the issue, including how an attacker might exploit the issue 36 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/AttributeLookupTable.cpp: -------------------------------------------------------------------------------- 1 | #include "AttributeLookupTable.h" 2 | #include 3 | 4 | namespace Odb::Lib::FileModel::Design 5 | { 6 | const std::map& AttributeLookupTable::GetAttributeLookupTable() const 7 | { 8 | return m_attributeLookupTable; 9 | } 10 | 11 | bool AttributeLookupTable::ParseAttributeLookupTable(const std::string& attributeLookupTableString) 12 | { 13 | std::stringstream ss(attributeLookupTableString); 14 | std::string token; 15 | 16 | // skip the content before the first semicolon 17 | if (!std::getline(ss, token, ';')) 18 | return false; 19 | 20 | // attributes 21 | if (std::getline(ss, token, ';')) 22 | { 23 | std::stringstream attributesStream(token); 24 | std::string attributeAssignment; 25 | while (std::getline(attributesStream, attributeAssignment, ',')) 26 | { 27 | if (!attributeAssignment.empty()) 28 | { 29 | std::string name; 30 | std::string value; 31 | 32 | std::stringstream aa_ss(attributeAssignment); 33 | if (attributeAssignment.find("=") != std::string::npos) 34 | { 35 | if (!std::getline(aa_ss, name, '=')) return false; 36 | if (!std::getline(aa_ss, value)) return false; 37 | } 38 | else 39 | { 40 | if (!std::getline(aa_ss, name)) return false; 41 | } 42 | 43 | m_attributeLookupTable[name] = value; 44 | } 45 | } 46 | } 47 | 48 | // ID 49 | if (std::getline(ss, token, ';')) 50 | { 51 | std::string name; 52 | std::string value; 53 | 54 | std::stringstream token_ss(token); 55 | if (token.find("=") != std::string::npos) 56 | { 57 | if (!std::getline(token_ss, name, '=')) return false; 58 | if (!std::getline(token_ss, value)) return false; 59 | } 60 | 61 | m_attributeLookupTable[name] = value; 62 | } 63 | 64 | return true; 65 | } 66 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/parse_error.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "parse_info.h" 7 | 8 | namespace Odb::Lib::FileModel 9 | { 10 | 11 | #ifndef throw_parse_error 12 | # define throw_parse_error(dataFile, dataLine, dataToken, dataLineNumber) throw parse_error(dataFile, dataLine, dataToken, dataLineNumber, __LINE__, __FILE__) 13 | #endif 14 | 15 | class parse_error : public std::exception 16 | { 17 | public: 18 | 19 | parse_error(std::filesystem::path dataFile, const std::string& szDataLine, const std::string& szDataToken, int dataLineNumber, int sourceLine, const char* szSourceFile) 20 | : m_parseInfo(dataFile, szDataLine, szDataToken, dataLineNumber), sourceLine(sourceLine), sourceFile(szSourceFile) 21 | { 22 | } 23 | 24 | parse_error(const char* szDataFile, const char* szDataLine, const char* szDataToken, int sourceLine, const char* szSourceFile) 25 | : parse_error(szDataFile, szDataLine, szDataToken, -1, sourceLine, szSourceFile) 26 | { 27 | } 28 | 29 | parse_error(const char* szDataFile, const char* szDataLine, int sourceLine, const char* szSourceFile) 30 | : parse_error(szDataFile, szDataLine, "", -1, sourceLine, szSourceFile) 31 | { 32 | } 33 | 34 | parse_error(const char* szDataFile, int sourceLine, const char* szSourceFile) 35 | : parse_error(szDataFile, "", "", -1, sourceLine, szSourceFile) 36 | { 37 | } 38 | 39 | std::string toString(const std::string& message = "") const; 40 | 41 | const parse_info& getParseInfo() const; 42 | 43 | [[nodiscard]] char const* what() const noexcept; 44 | 45 | private: 46 | // data file 47 | const parse_info m_parseInfo; 48 | 49 | // source file 50 | int sourceLine; 51 | std::filesystem::path sourceFile; 52 | 53 | constexpr inline static const char WHAT_STR[] = "Parse error"; 54 | 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/LayerDirectory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "../../odbdesign_export.h" 8 | #include "ComponentsFile.h" 9 | #include "../../IProtoBuffable.h" 10 | #include "../../ProtoBuf/layerdirectory.pb.h" 11 | #include "FeaturesFile.h" 12 | #include "AttrListFile.h" 13 | #include "ToolsFile.h" 14 | #include "../ISaveable.h" 15 | 16 | 17 | namespace Odb::Lib::FileModel::Design 18 | { 19 | class ODBDESIGN_EXPORT LayerDirectory : public IProtoBuffable, public ISaveable 20 | { 21 | public: 22 | LayerDirectory(std::filesystem::path path); 23 | virtual ~LayerDirectory(); 24 | 25 | std::string GetName() const; 26 | std::filesystem::path GetPath() const; 27 | 28 | bool Parse(); 29 | // Inherited via ISaveable 30 | bool Save(const std::filesystem::path& directory) override; 31 | 32 | bool ParseComponentsFile(std::filesystem::path directory); 33 | bool ParseFeaturesFile(std::filesystem::path directory); 34 | bool ParseAttrListFile(std::filesystem::path directory); 35 | bool ParseToolsFile(std::filesystem::path directory); 36 | 37 | const ComponentsFile& GetComponentsFile() const; 38 | const FeaturesFile& GetFeaturesFile() const; 39 | const AttrListFile& GetAttrListFile() const; 40 | const ToolsFile& GetToolsFile() const; 41 | 42 | typedef std::map> StringMap; 43 | 44 | // Inherited via IProtoBuffable 45 | std::unique_ptr to_protobuf() const override; 46 | void from_protobuf(const Odb::Lib::Protobuf::LayerDirectory& message) override; 47 | 48 | private: 49 | std::string m_name; 50 | std::filesystem::path m_path; 51 | 52 | ComponentsFile m_componentsFile; 53 | FeaturesFile m_featuresFile; 54 | AttrListFile m_attrListFile; 55 | ToolsFile m_toolFile; 56 | 57 | }; 58 | } -------------------------------------------------------------------------------- /Utils/FileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "FileReader.h" 2 | #include "FileReader.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std::filesystem; 9 | 10 | namespace Utils 11 | { 12 | FileReader::FileReader(const std::filesystem::path& filePath) 13 | : m_filePath(filePath) 14 | { 15 | } 16 | 17 | //FileReader::FileReader(const std::filesystem::path& filePath, std::ios::openmode mode) 18 | // : FileReader(filePath, mode, false) 19 | //{ 20 | //} 21 | 22 | //FileReader::FileReader(const std::filesystem::path& filePath, std::ios::openmode mode, bool unbuffered) 23 | // : m_filePath(filePath) 24 | // , m_mode(mode) 25 | // , m_unbuffered(unbuffered) 26 | //{ 27 | //} 28 | 29 | long long FileReader::Read(BufferStrategy bufferStrategy /*= BufferStrategy::Buffered*/, std::ios::openmode mode /*= DEFAULT_OPENMODE*/) 30 | { 31 | auto read = 0LL; 32 | 33 | std::ifstream file(m_filePath, mode); 34 | if (file.is_open()) 35 | { 36 | if (bufferStrategy == BufferStrategy::Unbuffered) 37 | { 38 | long long size = file_size(m_filePath); 39 | m_buffer.resize(size); 40 | file.read(m_buffer.data(), size); 41 | if (file.gcount() == size) 42 | { 43 | read = size; 44 | } 45 | } 46 | else 47 | { 48 | char szBuffer[BUFFER_SIZE]{ 0 }; 49 | while (true) 50 | { 51 | file.read(szBuffer, sizeof(szBuffer)); 52 | auto readin = file.gcount(); 53 | if (readin < 1) 54 | { 55 | break; 56 | } 57 | m_buffer.insert(m_buffer.end(), szBuffer, szBuffer + readin); 58 | read += readin; 59 | } 60 | } 61 | m_buffer.push_back(0); 62 | m_buffer.resize(read); 63 | file.close(); 64 | } 65 | 66 | return read; 67 | } 68 | 69 | void FileReader::Clear() 70 | { 71 | m_buffer.clear(); 72 | } 73 | 74 | const std::vector& Utils::FileReader::GetBuffer() const 75 | { 76 | return m_buffer; 77 | } 78 | } -------------------------------------------------------------------------------- /Utils/CrossPlatform.cpp: -------------------------------------------------------------------------------- 1 | #include "CrossPlatform.h" 2 | #include "macros.h" 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace Utils 13 | { 14 | std::mutex localtimeMutex; 15 | 16 | bool CrossPlatform::localtime_safe(const std::time_t* time, struct std::tm& tmOut) 17 | { 18 | #if (IS_WINDOWS) 19 | { 20 | return (0 == localtime_s(&tmOut, time)); 21 | } 22 | #elif (IS_LINUX || IS_APPLE) 23 | { 24 | std::lock_guard lock(localtimeMutex); 25 | if (nullptr != localtime_r(time, &tmOut)) 26 | { 27 | return true; 28 | } 29 | } 30 | #elif 31 | return false; 32 | #endif 33 | } 34 | 35 | bool CrossPlatform::getenv_safe(const char* env_var, std::string& envValueOut) 36 | { 37 | #if (IS_WINDOWS) 38 | { 39 | char* envValue = nullptr; 40 | size_t len = 0; 41 | if (0 == _dupenv_s(&envValue, &len, env_var)) 42 | { 43 | if (envValue != nullptr && len > 0) 44 | { 45 | envValueOut = envValue; 46 | free(envValue); 47 | return true; 48 | } 49 | } 50 | } 51 | #elif (IS_LINUX || IS_APPLE) 52 | { 53 | auto val = std::getenv(env_var); 54 | if (val != nullptr) 55 | { 56 | envValueOut = val; 57 | return true; 58 | } 59 | 60 | } 61 | #endif 62 | 63 | return false; 64 | } 65 | 66 | bool CrossPlatform::tmpnam_safe(std::string& tempNameOut) 67 | { 68 | #if (IS_WINDOWS) 69 | { 70 | char szTempName[L_tmpnam_s]; 71 | if (0 == tmpnam_s(szTempName, L_tmpnam_s)) 72 | { 73 | tempNameOut = szTempName; 74 | return true; 75 | } 76 | } 77 | #elif (IS_LINUX || IS_APPLE) 78 | { 79 | // mkstemp 80 | char szTempName[L_tmpnam]{ 0 }; 81 | if (nullptr != std::tmpnam(szTempName)) 82 | { 83 | tempNameOut = szTempName; 84 | return true; 85 | } 86 | } 87 | #endif 88 | 89 | return false; 90 | } 91 | } -------------------------------------------------------------------------------- /scripts/create-k3d-cluster.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | # Cluster name 3 | [Parameter(Mandatory=$true)] 4 | [string]$ClusterName = "k3dcluster", 5 | # Number of agents to create 6 | [Parameter(Mandatory=$true)] 7 | [int]$NumAgents = 3, 8 | # Ingress host port 9 | [Parameter(Mandatory=$true)] 10 | [int]$IngressHostPort = 8081, 11 | # When set to true, the cluster will be deleted first 12 | [switch]$DeleteClusterFirst = $false, 13 | # When set to true, the cluster will be deleted without asking for confirmation 14 | [switch]$ForceDelete = $false, 15 | # Host Volume Path for PersistentVolume 16 | [Parameter(Mandatory=$true)] 17 | [string]$HostVolumePath = "D:/k3dvolume" 18 | 19 | ) 20 | 21 | # $clusterName="k3dcluster" 22 | $hostIp = "10.0.0.185" 23 | # $numAgents=3 24 | # $ingressHostPort=8081 25 | 26 | if ($DeleteClusterFirst) { 27 | 28 | if (! $ForceDelete) {` 29 | $clusterNameInput = Read-Host "Type cluster name ($ClusterName) and hit ENTER to delete the cluster first..." 30 | } 31 | else { 32 | Write-Host "Force delete specified..." 33 | $clusterNameInput = $ClusterName 34 | } 35 | 36 | if ($clusterNameInput -ne $ClusterName) { 37 | Write-Host "Cluster name did not match. Exiting..." 38 | Exit 1 39 | } 40 | else { 41 | Write-Host "Deleting cluster '$ClusterName'..." 42 | k3d cluster delete $ClusterName 43 | Write-Host "Cluster '$ClusterName' deleted." 44 | } 45 | } 46 | 47 | Write-Host "Creating cluster '$ClusterName'..." 48 | 49 | k3d cluster create $ClusterName ` 50 | --agents $NumAgents ` 51 | --k3s-arg="--tls-san=${hostIp}@server:0" ` 52 | --k3s-arg="--tls-san=precision5820@server:0" ` 53 | --port "${IngressHostPort}:80@loadbalancer" ` 54 | --port "8443:443@loadbalancer" ` 55 | --volume ${HostVolumePath}:/k3dvolume@all 56 | #--volume ${HostVolumePath}:/tmp/k3dvolume@all 57 | 58 | Write-Host "Cluster '$ClusterName' created." 59 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/SymbolName.cpp: -------------------------------------------------------------------------------- 1 | #include "SymbolName.h" 2 | #include "SymbolName.h" 3 | 4 | namespace Odb::Lib::FileModel::Design 5 | { 6 | //SymbolName::SymbolName(const std::string& name, UnitType unitType) 7 | // : m_name(name) 8 | // , m_unitType(unitType) 9 | //{ 10 | //} 11 | 12 | SymbolName::SymbolName() 13 | : m_name("") 14 | , m_unitType(UnitType::None) 15 | { 16 | } 17 | 18 | std::string SymbolName::GetName() const 19 | { 20 | return m_name; 21 | } 22 | 23 | UnitType SymbolName::GetUnitType() const 24 | { 25 | return m_unitType; 26 | } 27 | 28 | bool SymbolName::Parse(const std::filesystem::path& path, const std::string& line, int lineNumber) 29 | { 30 | std::stringstream lineStream(line); 31 | std::string token; 32 | 33 | // $n (index) 34 | if (!std::getline(lineStream, token, ' ')) 35 | { 36 | throw_parse_error(path, line, token, lineNumber); 37 | } 38 | 39 | if (std::getline(lineStream, token, ' ')) 40 | { 41 | m_name = token; 42 | } 43 | else 44 | { 45 | throw_parse_error(path, line, token, lineNumber); 46 | } 47 | 48 | if (std::getline(lineStream, token, ' ')) 49 | { 50 | switch (token[0]) 51 | { 52 | case 'M': 53 | m_unitType = UnitType::Metric; 54 | break; 55 | case 'I': 56 | m_unitType = UnitType::Imperial; 57 | break; 58 | } 59 | } 60 | 61 | return true; 62 | } 63 | 64 | std::unique_ptr SymbolName::to_protobuf() const 65 | { 66 | auto message = std::make_unique(); 67 | message->set_name(m_name); 68 | message->set_unittype(static_cast(m_unitType)); 69 | return message; 70 | } 71 | 72 | void SymbolName::from_protobuf(const Odb::Lib::Protobuf::SymbolName& message) 73 | { 74 | m_name = message.name(); 75 | m_unitType = static_cast(message.unittype()); 76 | } 77 | 78 | //std::shared_ptr SymbolName::Parse(const std::string& line) 79 | //{ 80 | // return nullptr; 81 | //} 82 | } -------------------------------------------------------------------------------- /OdbDesignLib/App/DesignCache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../FileModel/Design/FileArchive.h" 4 | #include "../ProductModel/Design.h" 5 | #include "../odbdesign_export.h" 6 | #include "StringVector.h" 7 | #include 8 | #include 9 | #include 10 | 11 | 12 | namespace Odb::Lib::App 13 | { 14 | class ODBDESIGN_EXPORT DesignCache 15 | { 16 | public: 17 | DesignCache(std::string directory); 18 | ~DesignCache(); 19 | 20 | std::shared_ptr GetDesign(const std::string& designName); 21 | std::shared_ptr GetFileArchive(const std::string& designName); 22 | 23 | void AddFileArchive(const std::string& designName, std::shared_ptr fileArchive, bool save); 24 | 25 | bool SaveFileArchive(const std::string& designName); 26 | 27 | std::vector getLoadedDesignNames(const std::string& filter = "") const; 28 | std::vector getLoadedFileArchiveNames(const std::string& filter = "") const; 29 | std::vector getUnloadedDesignNames(const std::string& filter = "") const; 30 | 31 | int loadAllFileArchives(bool stopOnError); 32 | int loadAllDesigns(bool stopOnError); 33 | int loadFileArchives(const Utils::StringVector& names); 34 | int loadDesigns(const Utils::StringVector& names); 35 | 36 | void setDirectory(const std::string& directory); 37 | const std::string& getDirectory() const; 38 | 39 | void Clear(); 40 | 41 | void ensureDirectoryExists() const; 42 | 43 | private: 44 | std::string m_directory; 45 | 46 | FileModel::Design::FileArchive::StringMap m_fileArchivesByName; 47 | ProductModel::Design::StringMap m_designsByName; 48 | 49 | std::shared_ptr LoadDesign(const std::string& designName); 50 | std::shared_ptr LoadFileArchive(const std::string& designName); 51 | 52 | constexpr inline static const char* DESIGN_EXTENSIONS[] = { "zip", "tgz", "tar.gz", "tar", "gzip" , "gz" }; 53 | 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /Utils/ArchiveExtractor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "utils_export.h" 6 | #include "libarchive_extract.h" 7 | #include 8 | 9 | 10 | namespace Utils 11 | { 12 | class UTILS_EXPORT ArchiveExtractor 13 | { 14 | public: 15 | 16 | enum class e7zExitCode 17 | { 18 | Success = 0, 19 | Warning = 1, 20 | FatalError = 2, 21 | CommandLineError = 7, 22 | NotEnoughMemory = 8, 23 | UserStopped = 255 24 | }; 25 | 26 | ArchiveExtractor(const std::string& path, bool bExtractLzmaInProc = false, bool bExtractLzmaUsing7Zip = true); 27 | //~ArchiveExtractor(); 28 | 29 | std::filesystem::path GetPath() const; 30 | std::string GetExtractionDirectory() const; 31 | 32 | static bool IsArchiveTypeSupported(const std::filesystem::path& file); 33 | static bool IsArchiveTypeSupported(const std::string& file); 34 | 35 | bool Extract(); 36 | bool Extract(const std::string& destinationPath); 37 | 38 | static std::filesystem::path getUncompressedFilePath(const std::filesystem::path& directory, const std::string& filename); 39 | 40 | static bool CompressDir(const std::string& srcDir, const std::string& destDir, 41 | const std::string& archiveName, std::string& fileOut, 42 | CompressionType type = CompressionType::TarGzip); 43 | 44 | constexpr static inline bool ALLOW_ALL_ARCHIVE_EXTENSION_TYPES = false; 45 | constexpr static inline const char* SupportedExtensions[] = { "tgz", "tar.gz", "gz", "zip", "Z", "gzip", "tar" }; 46 | 47 | private: 48 | std::filesystem::path m_path; 49 | std::string m_extractionDirectory; 50 | bool m_bExtractLzmaInProc = false; 51 | bool m_bExtractLzmaUsing7Zip = true; 52 | 53 | bool ExtractLzmaOutOfProc(const std::filesystem::path& destinationPath); 54 | bool ExtractLzmaInProc(const std::filesystem::path& destinationPath); 55 | 56 | static inline const std::vector LZMA_FILE_EXTENSIONS = { ".Z", ".z", ".lzma", ".lz" }; 57 | 58 | constexpr static inline bool HIDE_7Z_COMMAND_OUTPUT = true; 59 | 60 | }; 61 | } 62 | -------------------------------------------------------------------------------- /OdbDesignLib/ProductModel/PinConnection.cpp: -------------------------------------------------------------------------------- 1 | #include "PinConnection.h" 2 | #include 3 | #include "Pin.h" 4 | #include "Component.h" 5 | #include 6 | #include "../ProtoBuf/pinconnection.pb.h" 7 | 8 | 9 | namespace Odb::Lib::ProductModel 10 | { 11 | //PinConnection::~PinConnection() 12 | //{ 13 | //} 14 | 15 | PinConnection::PinConnection(std::shared_ptr pComponent, std::shared_ptr pPin) 16 | : PinConnection(pComponent, pPin, MakeName(*pComponent, *pPin)) 17 | { 18 | } 19 | 20 | PinConnection::PinConnection(std::shared_ptr pComponent, std::shared_ptr pPin, const std::string& name) 21 | : m_name(name) 22 | , m_pComponent(pComponent) 23 | , m_pPin(pPin) 24 | { 25 | } 26 | 27 | std::string PinConnection::MakeName(const Component& component, const Pin& pin) 28 | { 29 | //if (pComponent == nullptr || pPin == nullptr) return "Pin::MakeName() FAILED"; 30 | //return pComponent->GetRefDes() + "-" + pPin->GetName(); 31 | return component.GetRefDes() + "-" + pin.GetName(); 32 | } 33 | 34 | std::shared_ptr PinConnection::GetPin() const 35 | { 36 | return m_pPin; 37 | } 38 | 39 | std::shared_ptr PinConnection::GetComponent() const 40 | { 41 | return m_pComponent; 42 | } 43 | 44 | std::unique_ptr PinConnection::to_protobuf() const 45 | { 46 | auto pPinConnectionMsg = std::make_unique(); 47 | pPinConnectionMsg->set_name(m_name); 48 | pPinConnectionMsg->mutable_component()->CopyFrom(*m_pComponent->to_protobuf()); 49 | pPinConnectionMsg->mutable_pin()->CopyFrom(*m_pPin->to_protobuf()); 50 | return pPinConnectionMsg; 51 | } 52 | 53 | void PinConnection::from_protobuf(const Protobuf::ProductModel::PinConnection& message) 54 | { 55 | m_name = message.name(); 56 | m_pComponent = std::make_shared(); 57 | m_pComponent->from_protobuf(message.component()); 58 | m_pPin = std::make_shared("", -1); 59 | m_pPin->from_protobuf(message.pin()); 60 | } 61 | 62 | } // namespace Odb::Lib::ProductModel 63 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/ContourPolygon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "../../odbdesign_export.h" 7 | #include "../../IProtoBuffable.h" 8 | #include "../../ProtoBuf/common.pb.h" 9 | #include "../../odbdesign_export.h" 10 | 11 | 12 | namespace Odb::Lib::FileModel::Design 13 | { 14 | struct ODBDESIGN_EXPORT ContourPolygon : public IProtoBuffable 15 | { 16 | ~ContourPolygon() 17 | { 18 | m_polygonParts.clear(); 19 | } 20 | 21 | struct ODBDESIGN_EXPORT PolygonPart : public IProtoBuffable 22 | { 23 | enum class Type 24 | { 25 | Segment, 26 | Arc 27 | }; 28 | 29 | Type type; 30 | 31 | // Segment/Arc 32 | double endX, endY; 33 | 34 | // Arc 35 | double xCenter, yCenter; 36 | bool isClockwise; 37 | 38 | // Inherited via IProtoBuffable 39 | std::unique_ptr to_protobuf() const override; 40 | void from_protobuf(const Odb::Lib::Protobuf::ContourPolygon::PolygonPart& message) override; 41 | 42 | typedef std::vector> Vector; 43 | 44 | inline static const char* SEGMENT_RECORD_TOKEN = "OS"; 45 | inline static const char* ARC_RECORD_TOKEN = "OC"; 46 | 47 | }; // struct PolygonPart 48 | 49 | enum class Type 50 | { 51 | Island, 52 | Hole 53 | }; 54 | 55 | Type type; 56 | double xStart, yStart; 57 | 58 | PolygonPart::Vector m_polygonParts; 59 | 60 | // Inherited via IProtoBuffable 61 | std::unique_ptr to_protobuf() const override; 62 | void from_protobuf(const Odb::Lib::Protobuf::ContourPolygon& message) override; 63 | 64 | typedef std::vector> Vector; 65 | 66 | inline static const char* BEGIN_RECORD_TOKEN = "OB"; 67 | inline static const char* END_RECORD_TOKEN = "OE"; 68 | inline static const char* ISLAND_TYPE_TOKEN = "I"; 69 | inline static const char* HOLE_TYPE_TOKEN = "H"; 70 | 71 | }; // struct ContourPolygon 72 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/StepHdrFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../../odbdesign_export.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "../../IProtoBuffable.h" 9 | #include "../../ProtoBuf/stephdrfile.pb.h" 10 | #include "../OdbFile.h" 11 | #include "../IStreamSaveable.h" 12 | 13 | namespace Odb::Lib::FileModel::Design 14 | { 15 | class ODBDESIGN_EXPORT StepHdrFile : public OdbFile, public IProtoBuffable, public IStreamSaveable 16 | { 17 | public: 18 | virtual ~StepHdrFile(); 19 | 20 | struct StepRepeatRecord : public IProtoBuffable 21 | { 22 | std::string name; 23 | double x; 24 | double y; 25 | double dx; 26 | double dy; 27 | int nx; 28 | int ny; 29 | double angle; 30 | bool flip; 31 | bool mirror; 32 | 33 | typedef std::vector> Vector; 34 | 35 | constexpr static const char* ARRAY_HEADER_TOKEN = "STEP-REPEAT"; 36 | 37 | // Inherited via IProtoBuffable 38 | std::unique_ptr to_protobuf() const override; 39 | void from_protobuf(const Odb::Lib::Protobuf::StepHdrFile::StepRepeatRecord& message) override; 40 | }; 41 | 42 | bool Parse(std::filesystem::path path) override; 43 | // Inherited via IStreamSaveable 44 | bool Save(std::ostream& os) override; 45 | 46 | // Inherited via IProtoBuffable 47 | std::unique_ptr to_protobuf() const override; 48 | void from_protobuf(const Odb::Lib::Protobuf::StepHdrFile& message) override; 49 | 50 | private: 51 | std::string m_units; 52 | double xDatum; 53 | double yDatum; 54 | unsigned id; 55 | double xOrigin; 56 | double yOrigin; 57 | double topActive; 58 | double bottomActive; 59 | double rightActive; 60 | double leftActive; 61 | std::string affectingBom; 62 | bool affectingBomChanged; 63 | std::map m_onlineValues; 64 | 65 | StepRepeatRecord::Vector m_stepRepeatRecords; 66 | 67 | }; 68 | } 69 | -------------------------------------------------------------------------------- /.github/.mcp-github.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "sequential-thinking": { 4 | "type": "local", 5 | "command": "npx", 6 | "args": [ 7 | "-y", 8 | "@modelcontextprotocol/server-sequential-thinking@0.0.1" 9 | ], 10 | "tools": ["*"] 11 | }, 12 | "memory": { 13 | "type": "local", 14 | "command": "npx", 15 | "args": [ 16 | "-y", 17 | "@modelcontextprotocol/server-memory@0.0.1" 18 | ], 19 | "tools": ["*"] 20 | }, 21 | "filesystem": { 22 | "type": "local", 23 | "command": "npx", 24 | "args": [ 25 | "-y", 26 | "@modelcontextprotocol/server-filesystem", 27 | "." 28 | ], 29 | "tools": [ 30 | "list_directory", 31 | "read_directory", 32 | "stat", 33 | "glob", 34 | "read_file", 35 | "read_text_file" 36 | ] 37 | }, 38 | "gemini-cli": { 39 | "type": "local", 40 | "command": "npx", 41 | "args": [ 42 | "-y", 43 | "gemini-mcp-tool" 44 | ], 45 | "tools": ["*"] 46 | }, 47 | "notion": { 48 | "type": "local", 49 | "command": "npx", 50 | "args": [ 51 | "-y", 52 | "@notionhq/notion-mcp-server" 53 | ], 54 | "env": { 55 | "OPENAPI_MCP_HEADERS": "COPILOT_MCP_NOTION_OPENAPI_HEADERS" 56 | }, 57 | "tools": ["*"] 58 | }, 59 | "context7": { 60 | "type": "local", 61 | "command": "npx", 62 | "args": [ 63 | "-y", 64 | "@upstash/context7-mcp@latest" 65 | ], 66 | "tools": ["*"] 67 | }, 68 | "microsoft-docs": { 69 | "type": "http", 70 | "url": "https://learn.microsoft.com/api/mcp", 71 | "tools": ["*"] 72 | }, 73 | "deepwiki": { 74 | "type": "sse", 75 | "url": "https://mcp.deepwiki.com/sse", 76 | "tools": ["*"] 77 | }, 78 | "playwright": { 79 | "type": "local", 80 | "command": "npx", 81 | "args": [ 82 | "-y", 83 | "@playwright/mcp@latest" 84 | ], 85 | "tools": ["*"] 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/featuresfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "common.proto"; 7 | import "enums.proto"; 8 | import "symbolname.proto"; 9 | 10 | package Odb.Lib.Protobuf; 11 | 12 | // 13 | // EdaDataFile.h 14 | // 15 | 16 | message FeaturesFile { 17 | 18 | message FeatureRecord 19 | { 20 | enum Type { 21 | Arc = 0; 22 | Pad = 1; 23 | Surface = 2; 24 | Barcode = 3; 25 | Text = 4; 26 | Line = 5; 27 | }; 28 | 29 | optional Type type = 2; 30 | optional double xs = 3; 31 | optional double ys = 4; 32 | optional double xe = 5; 33 | optional double ye = 6; 34 | optional double x = 7; 35 | optional double y = 8; 36 | optional int32 apt_def = 9; 37 | optional int32 apt_def_symbol_num = 10; 38 | optional double apt_def_resize_factor = 11; 39 | optional double xc = 12; 40 | optional double yc = 13; 41 | optional bool cw = 14; 42 | optional string font = 15; 43 | optional double xsize = 16; 44 | optional double ysize = 17; 45 | optional double width_factor = 18; 46 | optional string text = 19; 47 | optional int32 version = 20; 48 | optional int32 sym_num = 21; 49 | optional Polarity polarity = 22; 50 | optional int32 dcode = 23; 51 | optional int32 atr = 24; 52 | optional string value = 25; 53 | optional uint32 id = 26; 54 | optional int32 orient_def = 27; 55 | optional double orient_def_rotation = 28; 56 | 57 | repeated ContourPolygon contourPolygons = 1; 58 | map attributeLookupTable = 29; 59 | } 60 | 61 | optional string units = 1; 62 | optional uint32 id = 2; 63 | optional string path = 5; 64 | optional string directory = 6; 65 | optional int32 numFeatures = 7; 66 | 67 | repeated FeatureRecord featureRecords = 8; 68 | map symbolNamesByName = 9; 69 | repeated SymbolName symbolNames = 10; 70 | 71 | } 72 | -------------------------------------------------------------------------------- /Utils/UrlEncoding.cpp: -------------------------------------------------------------------------------- 1 | #include "UrlEncoding.h" 2 | #include 3 | 4 | namespace Utils 5 | { 6 | static inline unsigned char to_hex(unsigned char x) 7 | { 8 | return x + (x > 9 ? ('A' - 10) : '0'); 9 | } 10 | 11 | static inline unsigned char from_hex(unsigned char ch) 12 | { 13 | if (ch <= '9' && ch >= '0') 14 | ch -= '0'; 15 | else if (ch <= 'f' && ch >= 'a') 16 | ch -= 'a' - 10; 17 | else if (ch <= 'F' && ch >= 'A') 18 | ch -= 'A' - 10; 19 | else 20 | ch = 0; 21 | return ch; 22 | } 23 | 24 | std::string UrlEncoding::encode(const std::string& unencoded) 25 | { 26 | std::ostringstream os; 27 | 28 | for (const auto& c : unencoded) 29 | { 30 | if ((c >= 'a' && c <= 'z') || 31 | (c >= 'A' && c <= 'Z') || 32 | (c >= '0' && c <= '9')) 33 | { 34 | // allowed 35 | os << c; 36 | } 37 | else if (c == ' ') 38 | { 39 | // space -> '+' 40 | os << '+'; 41 | } 42 | else 43 | { 44 | // encode 45 | os << '%' << to_hex(c >> 4) << to_hex(c % 16); 46 | } 47 | } 48 | 49 | return os.str(); 50 | } 51 | 52 | std::string UrlEncoding::decode(const std::string& encoded) 53 | { 54 | std::string result; 55 | 56 | std::string::size_type i; 57 | for (i = 0; i < encoded.size(); ++i) 58 | { 59 | if (encoded[i] == '+') 60 | { 61 | result += ' '; 62 | } 63 | else if (encoded[i] == '%' && encoded.size() > i + 2) 64 | { 65 | const unsigned char ch1 = from_hex(encoded[i + 1]); 66 | const unsigned char ch2 = from_hex(encoded[i + 2]); 67 | const unsigned char ch = (ch1 << 4) | ch2; 68 | result += ch; 69 | i += 2; 70 | } 71 | else 72 | { 73 | result += encoded[i]; 74 | } 75 | } 76 | 77 | return result; 78 | } 79 | } -------------------------------------------------------------------------------- /.github/workflows/validate-setup-scripts.yml: -------------------------------------------------------------------------------- 1 | name: Validate setup scripts (Linux & Windows) 2 | 3 | on: 4 | push: 5 | branches: 6 | - '**' 7 | pull_request: 8 | branches: 9 | - '**' 10 | workflow_dispatch: 11 | 12 | env: 13 | # Mirror repo variable for linter-friendly usage in conditions 14 | ENABLE_WINDOWS_SETUP_VALIDATION: ${{ vars.ENABLE_WINDOWS_SETUP_VALIDATION }} 15 | 16 | jobs: 17 | validate-linux: 18 | name: Validate Linux setup script 19 | runs-on: ubuntu-22.04 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@v5 23 | with: 24 | fetch-depth: 0 25 | 26 | 27 | - name: Fetch Remote Script 28 | shell: pwsh 29 | run: | 30 | # overwrite local script with remote script 31 | Invoke-WebRequest -Uri "https://raw.githubusercontent.com/nam20485/agent-instructions/main/scripts/setup-environment.sh" ` 32 | -OutFile "scripts/setup-environment.sh" ` 33 | -Headers @{"Accept"="application/vnd.github.raw"} 34 | 35 | - name: Run Linux setup script 36 | shell: bash 37 | run: | 38 | # Prefer repository .nvmrc; fail if neither .nvmrc nor env pin present 39 | if [ ! -f .nvmrc ] && [ -z "${NODE_VERSION_PIN}" ]; then 40 | echo "No .nvmrc found and NODE_VERSION_PIN not set; failing to keep determinism." >&2 41 | exit 1 42 | fi 43 | chmod +x scripts/setup-environment.sh 44 | scripts/setup-environment.sh 45 | 46 | validate-windows: 47 | if: "${{ vars.ENABLE_WINDOWS_SETUP_VALIDATION == 'true' }}" 48 | name: Validate Windows setup script 49 | runs-on: windows-2022 50 | steps: 51 | - name: Checkout 52 | uses: actions/checkout@v5 53 | with: 54 | fetch-depth: 0 55 | 56 | - name: Run Windows setup script 57 | shell: pwsh 58 | run: | 59 | if (!(Test-Path ".nvmrc") -and [string]::IsNullOrWhiteSpace($env:NODE_VERSION_PIN)) { 60 | Write-Error "No .nvmrc found and NODE_VERSION_PIN not set; failing to keep determinism." 61 | exit 1 62 | } 63 | pwsh -NoProfile -ExecutionPolicy Bypass -File scripts/setup-environment.ps1 64 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/ContourPolygon.cpp: -------------------------------------------------------------------------------- 1 | #include "ContourPolygon.h" 2 | 3 | namespace Odb::Lib::FileModel::Design 4 | { 5 | std::unique_ptr ContourPolygon::to_protobuf() const 6 | { 7 | std::unique_ptr pContourPolygonMessage(new Odb::Lib::Protobuf::ContourPolygon); 8 | pContourPolygonMessage->set_type((Odb::Lib::Protobuf::ContourPolygon::Type) type); 9 | pContourPolygonMessage->set_xstart(xStart); 10 | pContourPolygonMessage->set_ystart(yStart); 11 | for (const auto& pPolygonPart : m_polygonParts) 12 | { 13 | pContourPolygonMessage->add_polygonparts()->CopyFrom(*pPolygonPart->to_protobuf()); 14 | } 15 | return pContourPolygonMessage; 16 | } 17 | 18 | void ContourPolygon::from_protobuf(const Odb::Lib::Protobuf::ContourPolygon& message) 19 | { 20 | type = (Type) message.type(); 21 | xStart = message.xstart(); 22 | yStart = message.ystart(); 23 | for (const auto& polygonPartMessage : message.polygonparts()) 24 | { 25 | std::shared_ptr pPolygonPart(new PolygonPart); 26 | pPolygonPart->from_protobuf(polygonPartMessage); 27 | m_polygonParts.push_back(pPolygonPart); 28 | } 29 | } 30 | 31 | // Inherited via IProtoBuffable 32 | std::unique_ptr ContourPolygon::PolygonPart::to_protobuf() const 33 | { 34 | std::unique_ptr pPolygonPartMessage(new Odb::Lib::Protobuf::ContourPolygon::PolygonPart); 35 | pPolygonPartMessage->set_endx(endX); 36 | pPolygonPartMessage->set_endy(endY); 37 | pPolygonPartMessage->set_xcenter(xCenter); 38 | pPolygonPartMessage->set_ycenter(yCenter); 39 | pPolygonPartMessage->set_isclockwise(isClockwise); 40 | pPolygonPartMessage->set_type(static_cast(type)); 41 | return pPolygonPartMessage; 42 | } 43 | 44 | void ContourPolygon::PolygonPart::from_protobuf(const Odb::Lib::Protobuf::ContourPolygon::PolygonPart& message) 45 | { 46 | endX = message.endx(); 47 | endY = message.endy(); 48 | xCenter = message.xcenter(); 49 | yCenter = message.ycenter(); 50 | isClockwise = message.isclockwise(); 51 | type = static_cast(message.type()); 52 | } 53 | } -------------------------------------------------------------------------------- /.github/workflows/disabled/test-runtime.yml: -------------------------------------------------------------------------------- 1 | # 2 | # run the executable and make an authenticated call in each of the platforms: 3 | # 4 | # Windows 5 | # Ubuntu 6 | # MacOS 7 | # Docker 8 | 9 | name: Test Runtime 10 | 11 | on: 12 | push: 13 | branches: [ "nam20485" ] 14 | pull_request: 15 | branches: [ "development", "main", "release", "nam20485" ] 16 | 17 | permissions: 18 | contents: read 19 | 20 | env: 21 | ARTIFACTS_DIR: ${{ github.workspace }}/artifacts 22 | ARTIFACTS_DIR_WIN: ${{ github.workspace }}\artifacts 23 | 24 | jobs: 25 | build: 26 | name: Test Runtime Executables 27 | runs-on: ${{ matrix.os }} 28 | permissions: 29 | contents: write 30 | checks: write 31 | 32 | strategy: 33 | # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. 34 | fail-fast: false 35 | 36 | matrix: 37 | include: 38 | # Windows x64 Release 39 | - os: windows-2022 40 | preset: x64-release 41 | # Linux x64 Release 42 | - os: ubuntu-22.04 43 | preset: linux-release 44 | # MacOS x64 Release 45 | - os: macos-12 46 | preset: macos-release 47 | # Linux mingw x64 Release 48 | # - os: ubuntu-22.04 49 | # preset: linux-mingw-w64-release 50 | # # Linux Python Release 51 | # - os: ubuntu-22.04 52 | # preset: python-linux-release 53 | 54 | steps: 55 | 56 | - name: Harden Runner 57 | uses: step-security/harden-runner@63c24ba6bd7ba022e95695ff85de572c04a18142 # v2.7.0 58 | with: 59 | egress-policy: audit 60 | 61 | - name: Checkout Repository 62 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 63 | 64 | # add problem matchers by compiler 65 | - name: Add Problem Matchers 66 | uses: ammaraskar/msvc-problem-matcher@1ebcb382869bfdc2cc645e8a2a43b6d319ea1cc0 # master 67 | if: matrix.os == 'windows-2022' 68 | - name: Add Problem Matchers 69 | uses: ammaraskar/gcc-problem-matcher@0f9c86f9e693db67dacf53986e1674de5f2e5f28 # master 70 | if: matrix.os != 'windows-2022' -------------------------------------------------------------------------------- /OdbDesignServer/OdbDesignServerApp.cpp: -------------------------------------------------------------------------------- 1 | #include "OdbDesignServerApp.h" 2 | #include "Controllers/HelloWorldController.h" 3 | #include "Controllers/FileUploadController.h" 4 | #include "Controllers/FileModelController.h" 5 | #include "Controllers/HealthCheckController.h" 6 | #include "Controllers/DesignsController.h" 7 | #include "macros.h" 8 | #include 9 | 10 | using namespace Odb::Lib::App; 11 | 12 | namespace Odb::App::Server 13 | { 14 | OdbDesignServerApp::OdbDesignServerApp(int argc, char* argv[]) 15 | : OdbServerAppBase(argc, argv) 16 | { 17 | } 18 | 19 | //OdbDesignServerApp::~OdbDesignServerApp() 20 | //{ 21 | //} 22 | 23 | //Utils::ExitCode OdbDesignServerApp::Run() 24 | //{ 25 | // // 26 | // // do any initialization here 27 | // // 28 | 29 | // auto result = OdbServerAppBase::Run(); 30 | 31 | // // 32 | // // do any cleanup here 33 | // // 34 | 35 | // return result; 36 | //} 37 | 38 | void OdbDesignServerApp::add_controllers() 39 | { 40 | m_vecControllers.push_back(std::make_shared(*this)); 41 | m_vecControllers.push_back(std::make_shared(*this)); 42 | m_vecControllers.push_back(std::make_shared(*this)); 43 | m_vecControllers.push_back(std::make_shared(*this)); 44 | m_vecControllers.push_back(std::make_shared(*this)); 45 | } 46 | 47 | bool OdbDesignServerApp::preServerRun() 48 | { 49 | // CORS 50 | auto& cors = crow_app().get_middleware(); 51 | if (Utils::IsProduction()) 52 | { 53 | cors.global() 54 | .headers("*") 55 | .origin("*"); 56 | //cors.global().methods(crow::HTTPMethod::Get, crow::HTTPMethod::Post); 57 | //cors.global().origin("73.157.184.219"); 58 | } 59 | else 60 | { 61 | cors.global() 62 | .headers("*") 63 | .origin("*"); 64 | //cors.global().methods(crow::HTTPMethod::Get); 65 | //cors.global().origin("73.157.184.219"); 66 | } 67 | 68 | // add authentication 69 | bool disableAuth = args().disableAuthentication(); 70 | auto basicRequestAuth = std::make_unique(BasicRequestAuthentication(disableAuth)); 71 | request_auth(std::move(basicRequestAuth)); 72 | 73 | return true; 74 | } 75 | } -------------------------------------------------------------------------------- /Utils/EnumMap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include "str_utils.h" 7 | #include 8 | #include 9 | 10 | namespace Utils 11 | { 12 | template 13 | class EnumMap 14 | { 15 | public: 16 | EnumMap(const std::vector& names, bool caseInsensitive = false); 17 | 18 | const std::string& getValue(const E e) const; 19 | E getValue(const std::string& name) const; 20 | 21 | bool contains(const std::string& name) const; 22 | bool contains(const E e) const; 23 | 24 | //typedef std::exception Exception; 25 | 26 | private: 27 | const std::vector m_names; 28 | const bool m_bCaseInsensitive; 29 | 30 | }; 31 | 32 | template 33 | inline EnumMap::EnumMap(const std::vector& names, bool caseInsensitive) 34 | : m_names(names) 35 | , m_bCaseInsensitive(caseInsensitive) 36 | {} 37 | 38 | template 39 | inline const std::string& EnumMap::getValue(const E e) const 40 | { 41 | auto index = static_cast(e); 42 | if (index < 0 || index >= m_names.size()) 43 | { 44 | std::string msg = "no name found for value: " + std::to_string(index); 45 | throw std::invalid_argument(msg.c_str()); 46 | } 47 | return m_names[index]; 48 | } 49 | 50 | template 51 | inline E EnumMap::getValue(const std::string& name) const 52 | { 53 | std::vector::const_iterator findIt; 54 | if (m_bCaseInsensitive) 55 | { 56 | findIt = Utils::find_str_icmp(m_names.begin(), m_names.end(), name); 57 | } 58 | else 59 | { 60 | findIt = std::find(m_names.begin(), m_names.end(), name); 61 | } 62 | 63 | if (findIt == m_names.end()) 64 | { 65 | std::string msg = "no value found for name: (" + name + ")"; 66 | throw std::invalid_argument(msg.c_str()); 67 | } 68 | return static_cast(std::distance(m_names.begin(), findIt)); 69 | } 70 | 71 | template 72 | inline bool EnumMap::contains(const std::string& name) const 73 | { 74 | return std::find(m_names.begin(), m_names.end(), name) != m_names.end(); 75 | } 76 | 77 | template 78 | inline bool EnumMap::contains(const E e) const 79 | { 80 | auto index = static_cast(e); 81 | return index >= 0 && index < m_names.size(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /Utils/str_utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "utils_export.h" 5 | #include 6 | 7 | 8 | namespace Utils 9 | { 10 | // trim from start (in place) 11 | UTILS_EXPORT std::string& str_ltrim(std::string& s); 12 | // trim from end (in place) 13 | UTILS_EXPORT std::string& str_rtrim(std::string& s); 14 | // trim from both ends (in place) 15 | UTILS_EXPORT std::string& str_trim(std::string& s); 16 | 17 | UTILS_EXPORT std::string& str_ltrim(std::string& s, /*unsigned*/ char toRemove); 18 | // trim from end (in place) 19 | UTILS_EXPORT std::string& str_rtrim(std::string& s, /*unsigned*/ char toRemove); 20 | // trim from both ends (in place) 21 | UTILS_EXPORT std::string& str_trim(std::string& s, /*unsigned*/ char toRemove); 22 | 23 | // trim from start (copying) 24 | UTILS_EXPORT std::string str_ltrim_copy(const std::string& s); 25 | // trim from end (copying) 26 | UTILS_EXPORT std::string str_rtrim_copy(const std::string& s); 27 | // trim from both ends (copying) 28 | UTILS_EXPORT std::string str_trim_copy(const std::string& s); 29 | 30 | UTILS_EXPORT std::string str_ltrim_copy(const std::string&, /*unsigned*/ char toRemove); 31 | // trim from end (copying) 32 | UTILS_EXPORT std::string str_rtrim_copy(const std::string&, /*unsigned*/ char toRemove); 33 | // trim from both ends (copying) 34 | UTILS_EXPORT std::string str_trim_copy(const std::string&, /*unsigned*/ char toRemove); 35 | 36 | UTILS_EXPORT void str_to_lower(std::string& s); 37 | UTILS_EXPORT void str_to_upper(std::string& s); 38 | 39 | UTILS_EXPORT std::string str_to_lower_copy(const std::string& s); 40 | UTILS_EXPORT std::string str_to_upper_copy(const std::string& s); 41 | 42 | //UTILS_EXPORT std::string str_replace(const std::string& s, const std::string& from, const std::string& to); 43 | 44 | UTILS_EXPORT bool str_iequals(const std::string& s1, const std::string& s2); 45 | 46 | UTILS_EXPORT std::vector::iterator find_str_icmp(std::vector::iterator first, 47 | std::vector::iterator last, 48 | const std::string& val); 49 | 50 | UTILS_EXPORT std::vector::const_iterator find_str_icmp(const std::vector::const_iterator first, 51 | const std::vector::const_iterator last, 52 | const std::string& val); 53 | 54 | } -------------------------------------------------------------------------------- /scripts/create-release.js: -------------------------------------------------------------------------------- 1 | async function createRelease({github, context, core}, workspacePath, refName) { 2 | 3 | try { 4 | const createResponse = await github.rest.repos.createRelease({ 5 | generate_release_notes: true, 6 | name: process.env.RELEASE_NAME, 7 | owner: context.repo.owner, 8 | repo: context.repo.repo, 9 | prerelease: false, 10 | tag_name: process.env.RELEASE_TAG, 11 | body: require('fs').readFileSync(workspacePath + '/' + 'release/release-body.md', 'utf8'), 12 | target_commitish: refName 13 | }); 14 | 15 | const files = 16 | [ 17 | { name: 'OdbDesign-Linux-x64.zip', contentType: 'application/zip' }, 18 | { name: 'OdbDesign-Linux-x64.zip.sha256sum', contentType: 'text/plain' }, 19 | { name: 'OdbDesign-Linux-x64.zip.asc', contentType: 'text/plain' }, 20 | { name: 'OdbDesign-Windows-x64.zip', contentType: 'application/zip' }, 21 | { name: 'OdbDesign-Windows-x64.zip.sha256sum', contentType: 'text/plain' }, 22 | { name: 'OdbDesign-Windows-x64.zip.asc', contentType: 'text/plain' }, 23 | { name: 'OdbDesign-MacOS-x64.zip', contentType: 'application/zip' }, 24 | { name: 'OdbDesign-MacOS-x64.zip.sha256sum', contentType: 'text/plain' }, 25 | { name: 'OdbDesign-MacOS-x64.zip.asc', contentType: 'text/plain' } 26 | ]; 27 | 28 | const artifactsPath = workspacePath + '/' + 'artifacts'; 29 | 30 | for (const file of files) { 31 | const filePath = artifactsPath + '/' + file.name; 32 | const uploadResponse = await github.rest.repos.uploadReleaseAsset({ 33 | owner: context.repo.owner, 34 | repo: context.repo.repo, 35 | release_id: createResponse.data.id, 36 | name: file.name, 37 | data: require('fs').readFileSync(filePath), 38 | headers: { 39 | 'content-type': file.contentType, 40 | 'content-length': require('fs').statSync(filePath).size 41 | } 42 | }); 43 | } 44 | } catch (error) { 45 | core.setFailed(error.message); 46 | } 47 | 48 | return context.payload.client_payload.value 49 | } 50 | 51 | module.exports = createRelease; -------------------------------------------------------------------------------- /.github/mcp.json: -------------------------------------------------------------------------------- 1 | { 2 | "servers": { 3 | "sequential-thinking": { 4 | "type": "stdio", 5 | "command": "npx", 6 | "args": [ 7 | "-y", 8 | "@modelcontextprotocol/server-sequential-thinking" 9 | ], 10 | "version": "0.0.1" 11 | }, 12 | "memory": { 13 | "type": "stdio", 14 | "command": "npx", 15 | "args": [ 16 | "-y", 17 | "@modelcontextprotocol/server-memory" 18 | ], 19 | "version": "0.0.1" 20 | }, 21 | "github": { 22 | "type": "http", 23 | "url": "https://api.githubcopilot.com/mcp", 24 | "version": "0.0.1" 25 | }, 26 | "filesystem": { 27 | "command": "npx", 28 | "args": [ 29 | "-y", 30 | "@modelcontextprotocol/server-filesystem", 31 | "${env:USERPROFILE}", 32 | "." 33 | ], 34 | "type": "stdio" 35 | }, 36 | "gemini-cli": { 37 | "command": "npx", 38 | "args": [ 39 | "-y", 40 | "gemini-mcp-tool" 41 | ], 42 | "type": "stdio" 43 | }, 44 | "notion": { 45 | "command": "npx", 46 | "args": [ 47 | "-y", 48 | "@notionhq/notion-mcp-server" 49 | ], 50 | "env": { 51 | "OPENAPI_MCP_HEADERS": { 52 | "Authorization": "Bearer ${input:NOTION_TOKEN}", 53 | "Notion-Version": "2022-06-28" 54 | } 55 | }, 56 | "type": "stdio" 57 | }, 58 | "context7": { 59 | "command": "npx", 60 | "args": [ 61 | "-y", 62 | "@upstash/context7-mcp@latest" 63 | ], 64 | "type": "stdio" 65 | }, 66 | "microsoft-docs": { 67 | "url": "https://learn.microsoft.com/api/mcp", 68 | "type": "http" 69 | }, 70 | "deepwiki": { 71 | "url": "https://mcp.deepwiki.com/sse", 72 | "type": "http" 73 | }, 74 | "playwright": { 75 | "type": "local", 76 | "command": "npx", 77 | "args": [ 78 | "@playwright/mcp@latest" 79 | ] 80 | } 81 | }, 82 | "puppeteer": { 83 | "command": "npx", 84 | "args": [ 85 | "-y", 86 | "@modelcontextprotocol/server-puppeteer" 87 | ], 88 | "env": {} 89 | }, 90 | "web-browser": { 91 | "type": "stdio", 92 | "command": "uv", 93 | "args": [ 94 | "tool", 95 | "run", 96 | "web-browser-mcp-server" 97 | ] 98 | }, 99 | "inputs": [ 100 | { 101 | "id": "NOTION_TOKEN", 102 | "type": "promptString", 103 | "description": "Notion API Token (https://www.notion.so/profile/integrations)", 104 | "password": true 105 | } 106 | ] 107 | } -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/StandardFontsFile.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../OdbFile.h" 4 | #include "../../odbdesign_export.h" 5 | #include "../../enums.h" 6 | #include 7 | #include "../../IProtoBuffable.h" 8 | #include "../../ProtoBuf/standardfontsfile.pb.h" 9 | #include "../IStreamSaveable.h" 10 | 11 | namespace Odb::Lib::FileModel::Design 12 | { 13 | class ODBDESIGN_EXPORT StandardFontsFile : public OdbFile, public IProtoBuffable, public IStreamSaveable 14 | { 15 | public: 16 | StandardFontsFile() = default; 17 | ~StandardFontsFile(); 18 | 19 | bool Parse(std::filesystem::path path) override; 20 | // Inherited via IStreamSaveable 21 | bool Save(std::ostream& os) override; 22 | 23 | // Inherited via IProtoBuffable 24 | std::unique_ptr to_protobuf() const override; 25 | void from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile& message) override; 26 | 27 | struct CharacterBlock : public IProtoBuffable 28 | { 29 | ~CharacterBlock(); 30 | 31 | struct LineRecord : public IProtoBuffable 32 | { 33 | double xStart; 34 | double yStart; 35 | double xEnd; 36 | double yEnd; 37 | Polarity polarity; 38 | LineShape shape; 39 | double width; 40 | 41 | std::unique_ptr to_protobuf() const override; 42 | void from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock::LineRecord& message) override; 43 | 44 | typedef std::vector> Vector; 45 | 46 | inline static constexpr const char* RECORD_TOKEN = "LINE"; 47 | }; 48 | 49 | inline static constexpr const char* BEGIN_TOKEN = "CHAR"; 50 | inline static constexpr const char* END_TOKEN = "ECHAR"; 51 | 52 | char character; 53 | LineRecord::Vector m_lineRecords; 54 | 55 | std::unique_ptr to_protobuf() const override; 56 | void from_protobuf(const Odb::Lib::Protobuf::StandardFontsFile::CharacterBlock& message) override; 57 | 58 | typedef std::vector> Vector; 59 | 60 | }; 61 | 62 | private: 63 | double m_xSize; 64 | double m_ySize; 65 | double m_offset; 66 | 67 | CharacterBlock::Vector m_characterBlocks; 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /OdbDesignLib/protoc/componentsfile.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | //// https://protobuf.dev/reference/cpp/cpp-generated/#message 4 | //option optimize_for = CODE_SIZE; 5 | 6 | import "common.proto"; 7 | import "enums.proto"; 8 | 9 | package Odb.Lib.Protobuf; 10 | 11 | // 12 | // EdaDataFile.h 13 | // 14 | 15 | message ComponentsFile { 16 | 17 | message ComponentRecord { 18 | 19 | message ToeprintRecord { 20 | 21 | optional uint32 pinNumber = 1; 22 | optional double locationX = 2; 23 | optional double locationY = 3; 24 | optional double rotation = 4; 25 | optional bool mirror = 5; 26 | optional uint32 netNumber = 6; 27 | optional uint32 subnetNumber = 7; 28 | optional string name = 8; 29 | 30 | } 31 | 32 | optional uint32 pkgRef = 1; 33 | optional double locationX = 2; 34 | optional double locationY = 3; 35 | optional double rotation = 4; 36 | optional bool mirror = 5; 37 | optional string compName = 6; 38 | optional string partName = 7; 39 | optional string attributes = 8; 40 | optional uint32 id = 9; 41 | optional uint32 index = 10; 42 | 43 | repeated PropertyRecord propertyRecords = 11; 44 | repeated ToeprintRecord toeprintRecords = 12; 45 | map attributeLookupTable = 13; 46 | 47 | } 48 | 49 | message BomDescriptionRecord 50 | { 51 | optional string cpn = 1; 52 | optional string pkg = 2; 53 | optional string ipn = 3; 54 | repeated string descriptions = 4; 55 | optional string vpl_vnd = 5; 56 | optional string vpl_mpn = 6; 57 | optional string vnd = 7; 58 | optional string mpn = 8; 59 | } 60 | 61 | optional string units = 1; 62 | optional uint32 id = 2; 63 | optional BoardSide side = 3; 64 | optional string layerName = 4; 65 | optional string path = 5; 66 | optional string directory = 6; 67 | 68 | repeated string attributeNames = 7; 69 | repeated string attributeTextValues = 8; 70 | 71 | repeated ComponentRecord componentRecords = 9; 72 | map componentRecordsByName = 10; 73 | 74 | repeated PropertyRecord propertyRecords = 11; 75 | map propertyRecordsByName = 12; 76 | 77 | map bomDescriptionRecordsByCpn = 13; 78 | } -------------------------------------------------------------------------------- /OdbDesignLib/App/OdbDesignArgs.cpp: -------------------------------------------------------------------------------- 1 | #include "OdbDesignArgs.h" 2 | #include 3 | 4 | namespace Odb::Lib::App 5 | { 6 | OdbDesignArgs::OdbDesignArgs(int argc, char* argv[]) 7 | : CommandLineArgs(argc, argv) 8 | { 9 | } 10 | 11 | int OdbDesignArgs::port() const 12 | { 13 | return intArg("port", DEFAULT_PORT); 14 | } 15 | 16 | bool OdbDesignArgs::useHttps() const 17 | { 18 | return boolArg("use-https", DEFAULT_USE_HTTPS); 19 | } 20 | 21 | std::string OdbDesignArgs::sslDir() const 22 | { 23 | return stringArg("ssl-dir", DEFAULT_SSL_DIR); 24 | } 25 | 26 | std::string OdbDesignArgs::designsDir() const 27 | { 28 | return stringArg("designs-dir", DEFAULT_DESIGNS_DIR); 29 | } 30 | 31 | std::string OdbDesignArgs::templatesDir() const 32 | { 33 | return stringArg("templates-dir", DEFAULT_TEMPLATES_DIR); 34 | } 35 | 36 | bool OdbDesignArgs::help() const 37 | { 38 | return boolArg("help", DEFAULT_HELP); 39 | } 40 | 41 | std::string OdbDesignArgs::loadDesign() const 42 | { 43 | return stringArg("load-design", DEFAULT_LOAD_DESIGN); 44 | } 45 | 46 | bool OdbDesignArgs::loadAll() const 47 | { 48 | return boolArg("load-all", DEFAULT_LOAD_ALL); 49 | } 50 | 51 | bool OdbDesignArgs::disableAuthentication() const 52 | { 53 | return boolArg("disable-authentication", DEFAULT_DISABLE_AUTH); 54 | } 55 | 56 | std::string OdbDesignArgs::getUsageString() const 57 | { 58 | std::stringstream ss; 59 | ss << "Usage: " << executableName() << " [options]\n"; 60 | ss << "Options:\n"; 61 | ss << " --port Port to listen on (default: " << DEFAULT_PORT << ")\n"; 62 | ss << " --use-https Use HTTPS (default: " << (DEFAULT_USE_HTTPS ? "true" : "false") << ")\n"; 63 | ss << " --ssl-dir Directory containing SSL certificate and key files (default: " << DEFAULT_SSL_DIR << ")\n"; 64 | ss << " --designs-dir Directory containing design files (default: " << DEFAULT_DESIGNS_DIR << ")\n"; 65 | ss << " --templates-dir Directory containing template files (default: " << DEFAULT_TEMPLATES_DIR << ")\n"; 66 | ss << " --load-design Design to load on startup (default: " << DEFAULT_LOAD_DESIGN << ")\n"; 67 | ss << " --load-all Load all designs on startup (default: " << (DEFAULT_LOAD_ALL ? "true" : "false") << ")\n"; 68 | ss << " --disable-authentication Disable authentication (default: " << (DEFAULT_DISABLE_AUTH ? "true" : "false") << ")\n"; 69 | ss << " --help Print this help message\n"; 70 | return ss.str(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /OdbDesignLib/FileModel/Design/StepDirectory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "../../odbdesign_export.h" 9 | #include "LayerDirectory.h" 10 | #include "EdaDataFile.h" 11 | #include "NetlistFile.h" 12 | #include "../../IProtoBuffable.h" 13 | #include "../../ProtoBuf/stepdirectory.pb.h" 14 | #include "ComponentsFile.h" 15 | #include "AttrListFile.h" 16 | #include "StepHdrFile.h" 17 | #include "../ISaveable.h" 18 | #include "FeaturesFile.h" 19 | 20 | 21 | namespace Odb::Lib::FileModel::Design 22 | { 23 | class ODBDESIGN_EXPORT StepDirectory : public IProtoBuffable, public ISaveable 24 | { 25 | public: 26 | StepDirectory(std::filesystem::path path); 27 | ~StepDirectory(); 28 | 29 | std::string GetName(); 30 | std::filesystem::path GetPath(); 31 | 32 | const EdaDataFile& GetEdaDataFile() const; 33 | const LayerDirectory::StringMap& GetLayersByName() const; 34 | const NetlistFile::StringMap& GetNetlistsByName() const; 35 | const AttrListFile& GetAttrListFile() const; 36 | const FeaturesFile& GetProfileFile() const; 37 | const StepHdrFile& GetStepHdrFile() const; 38 | 39 | const ComponentsFile* GetTopComponentsFile() const; 40 | const ComponentsFile* GetBottomComponentsFile() const; 41 | 42 | bool Parse(); 43 | // Inherited via ISaveable 44 | bool Save(const std::filesystem::path& directory) override; 45 | 46 | typedef std::map> StringMap; 47 | 48 | // Inherited via IProtoBuffable 49 | std::unique_ptr to_protobuf() const override; 50 | void from_protobuf(const Odb::Lib::Protobuf::StepDirectory& message) override; 51 | 52 | private: 53 | std::string m_name; 54 | std::filesystem::path m_path; 55 | 56 | LayerDirectory::StringMap m_layersByName; 57 | NetlistFile::StringMap m_netlistsByName; 58 | EdaDataFile m_edaData; 59 | AttrListFile m_attrListFile; 60 | FeaturesFile m_profileFile; 61 | StepHdrFile m_stepHdrFile; 62 | 63 | bool ParseLayerFiles(std::filesystem::path layersPath); 64 | bool ParseNetlistFiles(std::filesystem::path netlistsPath); 65 | bool ParseEdaDataFiles(std::filesystem::path edaPath); 66 | bool ParseAttrListFile(std::filesystem::path attrListFileDirectory); 67 | bool ParseProfileFile(std::filesystem::path profileFileDirectory); 68 | bool ParseStepHdrFile(std::filesystem::path stepHdrFileDirectory); 69 | 70 | constexpr inline static const char* PROFILE_FILENAME = "profile"; 71 | 72 | }; 73 | } 74 | 75 | -------------------------------------------------------------------------------- /docs/CODEQL_SETUP_COMPLETE.md: -------------------------------------------------------------------------------- 1 | # CodeQL Setup Complete! 🎉 2 | 3 | Your CodeQL security analysis configuration has been successfully set up for the OdbDesign project. 4 | 5 | ## What's Been Configured 6 | 7 | ### 🔧 Core Configuration Files 8 | - **`.github/workflows/codeql.yml`** - Enhanced GitHub Actions workflow with optimizations 9 | - **`.github/codeql-config.yml`** - Comprehensive analysis configuration 10 | - **`.github/codeql/README.md`** - Complete documentation 11 | 12 | ### 🔍 Custom Security Queries 13 | - **`odbdesign-security.ql`** - Detects unsafe string operations (strcpy, sprintf, etc.) 14 | - **`http-response-splitting.ql`** - Checks for HTTP response splitting in web server code 15 | - **`odbdesign-suite.qls`** - Organized query suite combining custom and standard checks 16 | 17 | ### 🛠️ Development Tools 18 | - **`scripts/run-codeql-local.ps1`** - PowerShell script for local testing 19 | - **`.vscode/codeql-settings.json`** - VS Code integration settings 20 | 21 | ## Key Features 22 | 23 | ✅ **Comprehensive Security Coverage**: CWE-078, CWE-121, CWE-416, CWE-476 and more 24 | ✅ **Performance Optimized**: TRAP caching, parallel analysis, smart exclusions 25 | ✅ **CI/CD Integration**: Automatic PR scanning, weekly scheduled runs 26 | ✅ **Custom Patterns**: Project-specific security checks for C++ and web server code 27 | ✅ **False Positive Filtering**: Excludes generated code, dependencies, and build artifacts 28 | 29 | ## Next Steps 30 | 31 | 1. **Test Locally** (Optional): 32 | ```powershell 33 | # Install CodeQL CLI first: https://github.com/github/codeql-cli-binaries 34 | .\scripts\run-codeql-local.ps1 35 | ``` 36 | 37 | 2. **Commit Changes**: 38 | ```bash 39 | git add .github/ .vscode/ scripts/ 40 | git commit -m "feat: comprehensive CodeQL security analysis setup" 41 | git push 42 | ``` 43 | 44 | 3. **Monitor Results**: 45 | - Check GitHub Security tab after first run 46 | - Review any findings in PR comments 47 | - Adjust filters in `codeql-config.yml` if needed 48 | 49 | ## Workflow Triggers 50 | 51 | - **Push** to main branches (main, development, staging, nam20485) 52 | - **Pull Requests** to main branches 53 | - **Weekly Schedule** (Mondays at 6 AM UTC) 54 | - **Manual Trigger** via GitHub Actions UI 55 | 56 | ## Getting Help 57 | 58 | - 📖 See `.github/codeql/README.md` for detailed documentation 59 | - 🐛 Check workflow logs in GitHub Actions for troubleshooting 60 | - 💡 Use local script for faster development cycle testing 61 | 62 | Your code is now protected by enterprise-grade security analysis! 🛡️ 63 | --------------------------------------------------------------------------------